Return-Path: Mailing-List: contact tomcat-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list tomcat-dev@jakarta.apache.org Received: (qmail 29389 invoked from network); 6 Jan 2000 21:31:18 -0000 Received: from mercury.sun.com (192.9.25.1) by 63.211.145.10 with SMTP; 6 Jan 2000 21:31:18 -0000 Received: from shorter.eng.sun.com ([129.144.123.35]) by mercury.Sun.COM (8.9.3+Sun/8.9.3) with ESMTP id NAA04518 for ; Thu, 6 Jan 2000 13:30:02 -0800 (PST) From: Costin.Manolache@eng.sun.com Received: from eng.sun.com (costin [129.144.251.103]) by shorter.eng.sun.com (8.9.3+Sun/8.9.3/ENSMAIL,v1.7) with ESMTP id NAA07204 for ; Thu, 6 Jan 2000 13:30:01 -0800 (PST) Sender: Costin.Manolache@eng.sun.com Message-ID: <3875095D.C0680E93@eng.sun.com> Date: Thu, 06 Jan 2000 21:30:05 +0000 X-Mailer: Mozilla 4.51 [en] (X11; U; Linux 2.2.12-20 i686) X-Accept-Language: en MIME-Version: 1.0 To: Tomcat Subject: Proposal: request processing cleanup Content-Type: multipart/alternative; boundary="------------60FAFDB7BC0EF2D8F73B00C4" --------------60FAFDB7BC0EF2D8F73B00C4 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Existing model The current request processing is implemented in: * ContextManager - it's the entry point used by Adapters ( service() method is called after Request/Response is generated). * Context - implements the ServletContext API, except mappings. * Container - keeps all the mappings defined in context, and all the ServletWrappers. * RequestMapper - implements the alghoritm used to find the servlet inside a Container. * LookupResult - The servlet associated with a URI, plus path info and servlet path * RequestDispatcherImpl - will create a new LookupResult and use it to create a sub-request * InvokerServlet - if no servlet is found in Context/Container, it will generate a new one using defaults. * DefaultServlet - for non-servlet resources. * Request - URI, headers, attributes - and some informations generated by the rest of the code ( overlaps with LookupResult ) * Interceptors - Context and ServletWrapper will call Lifecycle and Service interceptors. When a request is generated by Adapter, ContextManager will parse the URI, find the Context and delegate the processing to it. The Context will delegate it to Container, which will create a new RequestMapper that will do a second parsing and return a LookupResult, and then delegate to the resulted ServletWrapper. Context and ServletWrapper will also call a list of Interceptors. ( this is based on my understanding of the code :-) New model. This model is based on Interceptors and use the same semantics/alghoritm as Apache (and NSAPI, ISAPI !!) - each request ( or sub-request) will follow the same path, with several types of Interceptors processing the request in a specific way. In addition to the Lifecycle and Service Interceptors ( and the SecurityInterceptors as defined by J2EE or Craig's security package), we will have interceptors that will parse the URI and set the Context, ServletWrapper and all other informations required by the spec. * Request - same role ( changes: move LookupResult functionality inside Request, RequestDispatcher will create a subrequest instead of using LookupResult ) * ContextManager - same role, but instead of hardcoded parsing of the request to find a Context it will call a a set of translation Interceptors == RequestHandlers ( configurable - the current code will be the default !). * Interceptor ( or RequestHandler ?? ) - will process the request. The current parsing code from RequestMapper, ContextManager, InvokerServlet, Container, etc will be moved in one or many handlers. The initial implementation will use the existing code to parse the URI and find the Context, ServletWrapper, pathInfo, servletPath, etc and set them in the Request object. ( please also read the Apache docs&code, with Request==request_struct, ServletWrapper==handler, Context==per_dir_config, Interceptor=handler method in a module, etc. ) Notes * it cleans up existing code. The current code is the result of a long evolution ( including the introduction of RequestDispatcher and the current semantics of Context), we need something simpler and easier to follow. * allow better integration with web servers. This model is similar ( or identical?) with Apache request processing and few other servers. * Will help improve the standalone server - it can use a different set of Interceptors, and it is easier to experiment with faster parsers * You can customize tomcat for specific tasks. For example, if a server has only one context and no virtual hosts it can use a simple interceptor and cut 1/2 of the size ( embeded? ). This will also fix several virtual-host problems in the existing code. * it will keep the critical path in one place, and IMHO it will be easier to read and understand. * Craig: It is a specific way to process the request - with 2 Container layers: ContextManager and ServletWrapper. It is a particular implementation of Container - it doesn't prevent the hierarchy of containers as in your proposal (2.2.1). Implementation I made few experiments and the changes doesn't affect too much outside core. Most of the code is written, and assuming no absolute -1 is raised most of code can be reorganized in 1-2 weeks. The first step is to merge LookupResult and Request, and change RequestDispatcherImpl and the other classes acordingly. Second, RequestMapper must be transformed into an Interceptor ( i.e. made stateless ). The code from ContextManager can be moved in a Interceptor ( that will parse the URI and set the Context - if none is already there !). Some code from Context will go into SessionInterceptor - that will further decouple the session-related code. Container.lookupServlet will be part another interceptor ( or merged with ContextInterceptor, and use same parsing code ). --------------60FAFDB7BC0EF2D8F73B00C4--