📄 httpd.java
字号:
/** * Get a shuffler for this server's client. * Whenever possible, we use a shuffler program to speed up communication * with the client. This methods return whatever the server deems * appropriate for this client shuffler. * @return A Shuffler instance, or <strong>null</strong>. * @see org.w3c.jigsaw.http.Shuffler */ public synchronized Shuffler getShuffler (Client client) { return shuffler ; } protected String getBanner() { return "Jigsaw["+version+"]"; } public void run () { // Emit some traces before starting up: System.out.println(getBanner()+": serving at "+getURL()); System.out.flush() ; errlog("started at: "+new Date()+"."); // Enter the evil loop: while ( ( ! finishing) && ( socket != null ) ) { Socket ns = null ; try { ns = socket.accept() ; ns.setTcpNoDelay(true); } catch (IOException e) { if (debug) e.printStackTrace() ; errlog ("failed to accept incoming connection on "+socket) ; // just in case, as it may have been created. try { ns.close(); } catch (Exception ex) {}; ns = null; } if ( (socket != null) && (ns != null) && (factory != null) ) factory.handleConnection (ns) ; } // Our socket has been closed, perform associated cleanup. cleanup(restarting) ; } /** * Perform the given request on behalf of this server. * @param request The request to perform. * @return A non-null Reply instance. * @exception ProtocolException If some error occurs during processing the * request. * @exception ResourceException If a resource got a fatal error. */ public ReplyInterface perform(RequestInterface req) throws ProtocolException, ResourceException { Request request = (Request) req; // This may be a server-wide request, this is an ugly hack in HTTP spec if ( request.getURL() == Request.THE_SERVER ) { if ( request.getMethod().equals("OPTIONS") ) { HttpTokenList pub = null; synchronized(this) { if ( publicHeader == null ) pub = HttpFactory.makeStringList(publicMethods); publicHeader = pub; } Reply reply = request.makeReply(HTTP.OK); if ( pub != null ) { reply.setHeaderValue(Reply.H_PUBLIC, pub); } reply.setContentLength(0); return reply; } } if (request.getMethod().equals("TRACE")) { // check if the resource can be proxied boolean doit = true; LookupState ls = new LookupState(request); LookupResult lr = new LookupResult(root.getResourceReference()); try { if ( root.lookup(ls, lr) ) { ResourceReference target = lr.getTarget(); if (target != null) { try { // this is plain ugly and won't work for proxy // not based on this resource // do we need another way to to this? FramedResource fr = (FramedResource) target.lock(); Class cff = Class.forName( "org.w3c.jigsaw.proxy.ForwardFrame"); doit = (fr.getFrameReference(cff) == null); } catch (Exception ex) { // fail miserably to the fallback } finally { target.unlock(); } } } } catch (Exception ex) {}; if (doit) { Reply reply = request.makeReply(HTTP.OK); reply.setNoCache(); // don't cache this reply.setMaxAge(-1); // Dump the request as the body // Removed unused headers: // FIXME should be something else for chuncked stream ByteArrayOutputStream ba = new ByteArrayOutputStream(); try { reply.setContentType(new MimeType("message/http")); request.dump(ba); reply.setContentLength(ba.size()); } catch (Exception ex) { ex.printStackTrace(); } reply.setStream(new ByteArrayInputStream(ba.toByteArray())); return reply; } } // Create a lookup state, and a lookup result: ProtocolException error = null; LookupState ls = null; LookupResult lr = null; // Run the lookup algorithm of root resource: // catch exception to get error (FIXME) try { lr = new LookupResult(root.getResourceReference()); ls = new LookupState(request); if ( root.lookup(ls, lr) ) { if (lr.hasReply()) return lr.getReply(); } } catch (ProtocolException ex) { error = ex; } catch (Exception ex) { /* * We have a problem here, the error can be a configuration * or resource/extension problem, and it should be a * 5xx error, or it is a client side error and it should be * a 4xx error, ex, try with "Authorization:" and it fails. * For now we will reply with a 400, but with a FIXME */ Reply err = request.makeReply(HTTP.BAD_REQUEST); err.setContent("<html><head><title>Bad Request</title></head>\n" + "<body><p>The server was not able to " + "understand this request</p></body></html>"); error = new ProtocolException(err); } // Let the target resource perform the method ResourceReference target = lr.getTarget(); Reply reply = null; ResourceFilter filters[] = lr.getFilters(); int infilter = 0; if (error == null) { //call the ingoing filters: try { // temporary target resource !!! WARNING request.setTargetResource(target); if ( filters != null ) { for ( ; infilter < filters.length ; infilter++ ) { if ( filters[infilter] == null ) continue; reply = (Reply)filters[infilter]. ingoingFilter(request, filters, infilter); if ( reply != null ) { return reply; } } } } catch (ProtocolException ex) { error = ex; } //perform the request: if ((error == null) && (target != null)) { request.setFilters(filters, infilter); request.setTargetResource(target); try { FramedResource res = (FramedResource)target.lock(); reply = (Reply)res.perform(request); if (reply == null) { reply = request.makeReply(HTTP.NOT_FOUND); if (uri_error) { reply.setContent("<html><head><title>Not Found" + "</title></head>\n"+ "<body><h1>Invalid" + " URL</h1><p>The URL <b>"+ request.getURL()+ "</b> that you requested is not" + " available "+ " for this protocol.</body>\n" +"</html>"); } else { reply.setContent("<html><head><title>Not Found" + "</title></head>\n"+ "<body><h1>Invalid" + " URL</h1><p>The URL" + "</b> that you requested is not" + " available "+ " for this protocol.</body>\n" +"</html>"); } reply.setContentType(org.w3c.www.mime.MimeType. TEXT_HTML); } } catch (InvalidResourceException ex) { //FIXME reply = request.makeReply(HTTP.NOT_FOUND); if (uri_error) { reply.setContent("<html><head><title>Not"+ " Found</title>"+ "</head><body><b>The URL <b>"+ request.getURL()+ "</b> that you requested is not " + "available, "+ " probably deleted.</body></html>"); } else { reply.setContent("<html><head><title>Not"+ " Found</title>"+ "</head><body><b>The URL"+ " that you requested is not " + "available, "+ " probably deleted.</body></html>"); } reply.setContentType(org.w3c.www.mime.MimeType.TEXT_HTML); } finally { target.unlock(); } } else { reply = request.makeReply(HTTP.NOT_FOUND); if (uri_error) { reply.setContent("<html><head>\n"+ "<title>Not Found</title></head>"+ "<body><h1>Invalid URL</h1><p>The URL"+ " <b>"+ request.getURL()+ "</b> that you requested is not"+ " available "+ " on that server.</body></html>"); } else { reply.setContent("<html><head>\n"+ "<title>Not Found</title></head>"+ "<body><h1>Invalid URL</h1><p>The URL"+ " that you requested is not"+ " available "+ " on that server.</body></html>"); } reply.setContentType(org.w3c.www.mime.MimeType.TEXT_HTML); } } // call the outgoing filters: if ((reply == null) || (reply.getStatus() != HTTP.DONE)) { if ( error == null ) { for (int i = infilter ; --i >= 0 ; ) { if ( filters[i] == null ) continue; Reply fr = (Reply)filters[i].outgoingFilter(request, reply, filters, i); if ( fr != null ) return fr; } } else { // Make sure we always invoke appropriate filters: if (filters != null) { for (int i = filters.length ; --i >= 0 ; ) { if ( filters[i] == null ) { continue; } Reply fr = (Reply)filters[i].exceptionFilter(request, error, filters, i); if ( fr != null ){ return fr; } } } reply = (Reply)error.getReply() ; if (reply == null) { reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR); if (uri_error) { reply.setContent("<html><head>\n"+ "<title>Server Error</title>"+ "</head><body><h1>Invalid URL</h1>"+ "<p>The URL <b>"+ request.getURL()+ "</b>: isn't available "+ " on that server.</body></html>"); } else { reply.setContent("<html><head>\n"+ "<title>Server Error</title>"+ "</head><body><h1>Invalid URL</h1>"+ "<p>The URL"+ " isn't available "+ " on that server.</body></html>"); } reply.setContentType(org.w3c.www.mime.MimeType.TEXT_HTML); } } } return reply; } protected boolean checkUpgrade(String id, ObservableProperties props) { // Check for an upgrade: int configvers = props.getInteger(httpd.VERSCOUNT_P, 1); if (configvers < httpd.verscount) { System.err.println("*** Jigsaw needs upgrade from internal "+ "version "+configvers+" to "+ httpd.verscount); if (httpd.verscount == 4) { org.w3c.tools.resources.serialization.Serializer serializer = new org.w3c.tools.resources.serialization.xml.XMLSerializer(); props.put(httpd.SERIALIZER_CLASS_P, "org.w3c.tools.resources.serialization.xml.XMLSerializer"); File propsfile = props.getFile(PROPS_P, null); Upgrader upgrader = new Upgrader(id, getConfigDirectory(), propsfile, serializer); props.put(httpd.VERSCOUNT_P, String.valueOf(httpd.verscount)); props.put(httpd.SERVER_SOFTWARE_P, "Jigsaw/"+version); try { upgrader.upgrade(httpd.verscount); return true; } catch (Exception ex) { System.err.println(ex.getMessage()); return false; } } return false; } return true; } /** * Initialize a new HTTP server. * The server wil first be initialized from the available properties, * it will than startup, and finally run in its own thread. * @param identifier The string identifying this server's occurence. * @param props A set of properties to initialize from. * @exception ServerHandlerInitException if unable to be initialized. */ public void initialize (ServerHandlerManager shm, String identifier, ObservableProperties props) throws ServerHandlerInitException { // Check for an optional upgrade of config files: // checkUpgrade(shm, identifier, props); this.shm = shm; // Initialize from properties: this.identifier = identifier ; this.props = props; // with an explicit cast for buggy compilers this.props.registerObserver((PropertyMonitoring)this) ; initializeProperties() ; if (! checkUpgrade(identifier, props)) throw new ServerHandlerInitException("Upgrade failed."); // Create the socket, and run the server: initializeServerSocket(); } /** * start the server * it will than startup, and finally run in its own thread. */ public void start () throws ServerHandlerInitException { if (!isAClone) { // Create the default resource context (shared by all resources): this.context = new ResourceContext(this); //FIXME // Create the resource store manager initializeResourceSpace(identifier, root_class, props.getString(EDIT_ROOT_P, root_name), props.getString(SERIALIZER_CLASS_P, null), max_loaded_store); this.context.setSpace(getResourceSpace()); // Create the resource indexer object initializeIndexer(); // Resurect this server root entity: initializeRootResource(); // Resurect the realms catalog initializeRealmsCatalog() ; // Initialize property sets initializePropertySets(); // Create this server event manager initializeEventManager(); // Initialize the logger object: initializeLogger(); // Initialize the shuffler object: if ( shuffler_path != null ) { try { this.shuffler = new Shuffler (shuffler_path) ; } catch (Error e) { warning ("unable to launch shuffler to "+ shuffler_path+ ": " + e.getMessage()) ; this.shuffler = null ; } catch (RuntimeException e) { warning (e, "unable to launch shuffler to "+ shuffler_path+ ": " + e.getMessage()) ; this.shuffler = null ; } } if ( this.shuffler != null ) trace ("using shuffler at: " + shuffler_path) ; // startup classes loadStartupClasses(); // Yeah, now start: this.thread.start(); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -