Annotation of java/classes/org/w3c/www/protocol/http/HttpManager.java, revision 1.1

1.1     ! abaird      1: // HttpManager.java
        !             2: // $Id$
        !             3: // (c) COPYRIGHT MIT and INRIA, 1996.
        !             4: // Please first read the full copyright statement in file COPYRIGHT.html
        !             5: 
        !             6: package w3c.www.protocol.http ;
        !             7: 
        !             8: import java.util.*;
        !             9: import java.net.*;
        !            10: import java.io.*; // FIXME - DEBUG
        !            11: 
        !            12: import w3c.www.mime.*;
        !            13: 
        !            14: class ReplyFactory implements MimeParserFactory {
        !            15:     
        !            16:     public MimeHeaderHolder createHeaderHolder(MimeParser parser) {
        !            17:        return new Reply(parser);
        !            18:     }
        !            19: 
        !            20: }
        !            21: 
        !            22: 
        !            23: /**
        !            24:  * The client side HTTP request manager.
        !            25:  * This class is the user interface (along with the other public classes of
        !            26:  * this package) for the W3C client side library implementing HTTP. 
        !            27:  * A typicall request is launched though the following sequence:
        !            28:  * <pre>
        !            29:  * HttpManager     manager = HttpManager.getManager() ;
        !            30:  * Request request = manager.makeRequest() ;
        !            31:  * request.setMethod(HTTP.GET) ;
        !            32:  * request.setURL(new URL("http://www.w3.org/pub/WWW/"));
        !            33:  * Reply    reply = manager.runRequest(request) ;
        !            34:  * // Get the reply input stream that contains the actual data:
        !            35:  * InputStream in = reply.getInputStream() ;
        !            36:  * ...
        !            37:  * </pre>
        !            38:  */
        !            39: 
        !            40: public class HttpManager {
        !            41:     private static HttpManager manager = null;
        !            42:     
        !            43:     /**
        !            44:      * The server this manager knows about, indexed by FQDN of target servers.
        !            45:      */
        !            46:     protected Hashtable servers = null;
        !            47:     /**
        !            48:      * The template request (the request we will clone to create new requests)
        !            49:      */
        !            50:     Request template = null ;
        !            51:     /**
        !            52:      * The filter engine attached to this manager.
        !            53:      */
        !            54:     FilterEngine filteng = null;
        !            55:      
        !            56: 
        !            57:     /**
        !            58:      * Get an instance of the HTTP manager.
        !            59:      * This method returns an actual instance of the HTTP manager. It may
        !            60:      * return different managers, if it decides to distribute the load on
        !            61:      * different managers (avoid the HttpManager being a bottleneck).
        !            62:      * @return An application wide instance of the HTTP manager.
        !            63:      */
        !            64: 
        !            65:     public static synchronized HttpManager getManager() {
        !            66:        if ( manager == null ) {
        !            67:            manager = new HttpManager() ;
        !            68:            // Have little fun !
        !            69:            DebugFilter filter = new DebugFilter();
        !            70:            manager.setFilter(filter);
        !            71:        }
        !            72:        return manager;
        !            73:     }
        !            74: 
        !            75: 
        !            76:     /**
        !            77:      * Get the appropriate server object for handling request to given target.
        !            78:      * @param key The server's identifier encoded as a <code>host:port</code>
        !            79:      * String.
        !            80:      * @return An object complying to the HttpServer interface.
        !            81:      * @exception HttpException If the given host name couldn't be resolved.
        !            82:      */
        !            83: 
        !            84:     protected synchronized HttpServer lookupServer(String host, int port) 
        !            85:        throws HttpException
        !            86:     {
        !            87:        String id = ((port == 80) ? host : (host +":"+port));
        !            88:        // Check for an existing server:
        !            89:        HttpServer server = (HttpServer) servers.get(id);
        !            90:        if ( server != null )
        !            91:            return server;
        !            92:        // Create and register a new server:
        !            93:        server = new HttpBasicServer();
        !            94:        server.initialize(this, host, port);
        !            95:        servers.put(id, server);
        !            96:        return server;
        !            97:     }
        !            98:      
        !            99:     /**
        !           100:      * One of our server handler wants to open a connection.
        !           101:      * @param block A boolean indicating whether we should block the calling
        !           102:      * thread until a token is available (otherwise, the method will just
        !           103:      * peek at the connection count, and return the appropriate result).
        !           104:      * @return A boolean, <strong>true</strong> if the connection can be
        !           105:      * opened straight, <strong>false</strong> otherwise.
        !           106:      */
        !           107: 
        !           108:     protected boolean negotiateConnection(int ccount) {
        !           109:        return (ccount < 2);
        !           110:     }
        !           111: 
        !           112:     /**
        !           113:      * Run the given request, in synchronous mode.
        !           114:      * This method will launch the given request, and block the calling thread
        !           115:      * until the response headers are available.
        !           116:      * @param request The request to run.
        !           117:      * @return An instance of Reply, containing all the reply 
        !           118:      * informations.
        !           119:      * @exception HTTPException If something failed during request processing.
        !           120:      */
        !           121:     
        !           122:     public Reply runRequest(Request request)
        !           123:        throws HttpException
        !           124:     {
        !           125:        URL target = request.getURL();
        !           126:        // Locate the appropriate target server:
        !           127:        int port = target.getPort();
        !           128:        HttpServer server = lookupServer(target.getHost()
        !           129:                                         , (port == -1) ? 80 : port);
        !           130:        // Now run through the ingoing filters:
        !           131:        RequestFilter filters[] = filteng.run(request);
        !           132:        if ( filters != null ) {
        !           133:            for (int i = 0 ; i < filters.length ; i++) {
        !           134:                filters[i].ingoingFilter(request);
        !           135:            }
        !           136:        }
        !           137:        // Get the server to give back a reply:
        !           138:        Reply reply = server.runRequest(request);
        !           139:        // Apply the filters on the way back:
        !           140:        if ( filters != null ) {
        !           141:            for (int i = 0 ; i < filters.length ; i++)
        !           142:                filters[i].outgoingFilter(request, reply);
        !           143:        }
        !           144:        return reply;
        !           145:     }
        !           146: 
        !           147:     /**
        !           148:      * Get this manager's reply factory.
        !           149:      * The Reply factory is used when prsing incomming reply from servers, it
        !           150:      * decides what object will be created to hold the actual reply from the 
        !           151:      * server.
        !           152:      * @return An object compatible with the MimeParserFactory interface.
        !           153:      */
        !           154: 
        !           155:     MimeParserFactory factory = null ;
        !           156: 
        !           157:     public synchronized MimeParserFactory getReplyFactory() {
        !           158:        if ( factory == null )
        !           159:            factory = new ReplyFactory();
        !           160:        return factory;
        !           161:     }
        !           162: 
        !           163:     /**
        !           164:      * Add a new request filter.
        !           165:      * Request filters are called <em>before</em> a request is launched, and
        !           166:      * <em>after</em> the reply headers are available. They allow applications
        !           167:      * to setup specific request headers (such as PICS, or PEP stuff) on the
        !           168:      * way in, and check the reply on the way out.
        !           169:      * <p>Request filters are application wide: if their scope matches
        !           170:      * the current request, then they will always be aplied.
        !           171:      * <p>Filter scopes are defined inclusively and exclusively
        !           172:      * @param filter The request filter to add.
        !           173:      */
        !           174: 
        !           175:     public void setFilter(URL incs[], URL exs[], RequestFilter filter) {
        !           176:        if ( incs != null ) {
        !           177:            for (int i = 0 ; i < incs.length ; i++)
        !           178:                filteng.setFilter(incs[i], true, filter);
        !           179:        }
        !           180:        if ( exs != null ) {
        !           181:            for (int i = 0 ; i < exs.length ; i++)
        !           182:                filteng.setFilter(exs[i], false, filter);
        !           183:        }
        !           184:        return;
        !           185:     }
        !           186: 
        !           187:     public void setFilter(RequestFilter filter) {
        !           188:        filteng.setFilter(filter);
        !           189:     }
        !           190: 
        !           191:     /**
        !           192:      * Add a request processor.
        !           193:      * Request processors are application wide hooks, able to answer request
        !           194:      * by querying a local cache. An application can set as many request
        !           195:      * processor as it wants, each of them will be called in trun (in the order
        !           196:      * they were registered), if any of them returns a reply, the request
        !           197:      * processing will be halted, and the generated reply returned.
        !           198:      * <p>Request processors can also be used to query distant cache, through
        !           199:      * some home-brew protocols.
        !           200:      * @param processor The request processor to be added.
        !           201:      */
        !           202: 
        !           203:     public void addProcessor(RequestProcessor processor) {
        !           204:     }
        !           205: 
        !           206:     /**
        !           207:      * Remove a request processor.
        !           208:      * Remove the given request processor.
        !           209:      * @return A boolean, <strong>true</strong> if the processor was found
        !           210:      * and removed, <strong>false</strong> otherwise.
        !           211:      */
        !           212: 
        !           213:     public boolean removeProcessor(RequestProcessor processor) {
        !           214:        return false;
        !           215:     }
        !           216: 
        !           217:     /**
        !           218:      * Create a new default outgoing request.
        !           219:      * This method should <em>always</em> be used to create outgoing requests.
        !           220:      * It will initialize the request with appropriate default values for 
        !           221:      * the various headers, and make sure that the request is enhanced by
        !           222:      * the registered request filters.
        !           223:      * @return An instance of Request, suitable to be launched.
        !           224:      */
        !           225: 
        !           226:     public Request createRequest() {
        !           227:        return (Request) template.getClone() ;
        !           228:     }
        !           229: 
        !           230:     /**
        !           231:      * Global settings - Set the max number of allowed connections.
        !           232:      * Set the maximum number of simultaneous connections that can remain
        !           233:      * opened. The manager will take care of queuing requests if this number
        !           234:      * is reached.
        !           235:      * <p>This value defaults to the value of the 
        !           236:      * <code>w3c.www.http.maxConnections</code> property.
        !           237:      * @param max_conn The allowed maximum simultaneous open connections.
        !           238:      */
        !           239: 
        !           240:     public void setMaxConnections(int max_conn) {
        !           241:     }
        !           242: 
        !           243:     /**
        !           244:      * Global settings - Set an optional proxy to use.
        !           245:      * Set the proxy to which all requests should be targeted. If the
        !           246:      * <code>w3c.www.http.proxy</code> property is defined, it will be
        !           247:      * used as the default value.
        !           248:      * @param proxy The URL for the proxy to use.
        !           249:      */
        !           250: 
        !           251:     public void setProxy(URL proxy) {
        !           252:     }
        !           253: 
        !           254:     /**
        !           255:      * Global settings - Set the request timeout.
        !           256:      * Once a request has been emited, the HttpManager will sit for this 
        !           257:      * given number of milliseconds before the request is declared to have
        !           258:      * timed-out.
        !           259:      * <p>This timeout value defaults to the value of the
        !           260:      * <code>w3c.www.http.requestTimeout</code> property value.
        !           261:      * @param ms The timeout value in milliseconds.
        !           262:      */
        !           263: 
        !           264:     public void setRequestTimeout(int ms) {
        !           265:     }
        !           266: 
        !           267:     /**
        !           268:      * Global settings - Define a global request header.
        !           269:      * Set a default value for some request header. Once defined, the
        !           270:      * header will automatically be defined on <em>all</em> outgoing requests
        !           271:      * created through the <code>createRequest</code> request.
        !           272:      * @param name The name of the header, case insensitive.
        !           273:      * @param value It's default value.
        !           274:      */
        !           275:     
        !           276:     public void setGlobalHeader(String name, String value) {
        !           277:        template.setValue(name, value);
        !           278:     }
        !           279: 
        !           280:     public String getGlobalHeader(String name) {
        !           281:        return template.getValue(name);
        !           282:     }
        !           283: 
        !           284:     /**
        !           285:      * Create a new HttpManager.
        !           286:      * This can only be called from this package. The caller must rather
        !           287:      * use the <code>getManager</code> method.
        !           288:      * @param props The properties from which the manager should initialize 
        !           289:      * itself, or <strong>null</strong> if none are available.
        !           290:      */
        !           291: 
        !           292:     HttpManager(Properties props) {
        !           293:        this.template = new Request(this);
        !           294:        this.servers  = new Hashtable();
        !           295:        this.filteng  = new FilterEngine();
        !           296:     }
        !           297: 
        !           298:     HttpManager() {
        !           299:        this(System.getProperties());
        !           300:     }
        !           301: 
        !           302:     /**
        !           303:      * DEBUGGING !
        !           304:      */
        !           305: 
        !           306:     public static void main(String args[]) {
        !           307:        try {
        !           308:            // Get the manager, and define some global headers:
        !           309:            HttpManager manager = HttpManager.getManager();
        !           310:            manager.setGlobalHeader("User-Agent", "Jigsaw/1.0a");
        !           311:            manager.setGlobalHeader("Accept", "*/*;q=1.0");
        !           312:            manager.setGlobalHeader("Accept-Encoding", "gzip");
        !           313:            Request request = manager.createRequest();
        !           314:            request.setURL(new URL(args[0]));
        !           315:            request.setMethod("GET");
        !           316:            Reply       reply   = manager.runRequest(request);
        !           317:            // Display some infos:
        !           318:            System.out.println("last-modified: "+reply.getLastModified());
        !           319:            System.out.println("length       : "+reply.getContentLength());
        !           320:            // Display the returned body:
        !           321:            InputStream in = reply.getInputStream();
        !           322:            byte buf[] = new byte[4096];
        !           323:            int  cnt   = 0;
        !           324:            while ((cnt = in.read(buf)) > 0) 
        !           325:                System.out.print(new String(buf, 0, 0, cnt));
        !           326:            System.out.println("-");
        !           327:            in.close();
        !           328:        } catch (Exception ex) {
        !           329:            ex.printStackTrace();
        !           330:            
        !           331:        }
        !           332:        System.exit(1);
        !           333:     }
        !           334: }

Webmaster