Return-Path: Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: (qmail 38819 invoked from network); 20 May 2006 02:14:15 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 20 May 2006 02:14:15 -0000 Received: (qmail 57443 invoked by uid 500); 20 May 2006 02:13:27 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 56631 invoked by uid 500); 20 May 2006 02:13:24 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 56586 invoked by uid 500); 20 May 2006 02:13:23 -0000 Delivered-To: apmail-jakarta-tomcat-dev@jakarta.apache.org Received: (qmail 56576 invoked by uid 99); 20 May 2006 02:13:23 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 19 May 2006 19:13:23 -0700 X-ASF-Spam-Status: No, hits=0.6 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [140.211.166.113] (HELO eris.apache.org) (140.211.166.113) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 19 May 2006 19:13:18 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id E54021A9842; Fri, 19 May 2006 19:12:57 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r407939 [1/8] - in /tomcat/sandbox/java/org/apache/coyote/servlet: ./ util/ Date: Sat, 20 May 2006 02:12:52 -0000 To: tomcat-dev@jakarta.apache.org From: costin@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20060520021257.E54021A9842@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: costin Date: Fri May 19 19:12:51 2006 New Revision: 407939 URL: http://svn.apache.org/viewvc?rev=407939&view=rev Log: vn cleanup Since this is sandbox :-), some very experimental classes ( cut&pasted from catalina, but with a lot of interfaces/hierarcy removed ), for a very minimal container. Basic req/response works - but most of the advanced features ( realm, etc ) is not yet implemented. Please ignore :-)--This line, and those below, will be ignored-- A servlet A servlet/ApplicationFilterFactory.java A servlet/ServletInputStreamImpl.java A servlet/ServletWriterImpl.java A servlet/ServletOutputStreamImpl.java A servlet/HttpSessionImpl.java A servlet/FilterChainImpl.java A servlet/ServletContextImpl.java A servlet/Host.java A servlet/SessionManager.java A servlet/ServletRequestImpl.java A servlet/LocalStrings.properties A servlet/ServletRequestWrapperImpl.java A servlet/RequestDispatcherImpl.java A servlet/FilterMap.java A servlet/Globals.java A servlet/ApplicationAuthorization.java A servlet/ServletResponseImpl.java A servlet/todo A servlet/ServletResponseWrapperImpl.java A servlet/ServletReaderImpl.java A servlet/CoyoteServletFacade.java A servlet/ServletConfigImpl.java A servlet/FilterConfigImpl.java A servlet/util A servlet/util/LocalStrings.properties A servlet/util/Enumerator.java A servlet/util/StringParser.java A servlet/util/RequestUtil.java A servlet/util/CharsetMapper.java A servlet/util/CharsetMapperDefault.properties A servlet/util/ParameterMap.java Added: tomcat/sandbox/java/org/apache/coyote/servlet/ tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationAuthorization.java tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationFilterFactory.java tomcat/sandbox/java/org/apache/coyote/servlet/CoyoteServletFacade.java tomcat/sandbox/java/org/apache/coyote/servlet/FilterChainImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/FilterConfigImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/FilterMap.java tomcat/sandbox/java/org/apache/coyote/servlet/Globals.java tomcat/sandbox/java/org/apache/coyote/servlet/Host.java tomcat/sandbox/java/org/apache/coyote/servlet/HttpSessionImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/LocalStrings.properties tomcat/sandbox/java/org/apache/coyote/servlet/RequestDispatcherImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletConfigImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletContextImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletInputStreamImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletOutputStreamImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletReaderImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletRequestImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletRequestWrapperImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletResponseImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletResponseWrapperImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/ServletWriterImpl.java tomcat/sandbox/java/org/apache/coyote/servlet/SessionManager.java tomcat/sandbox/java/org/apache/coyote/servlet/todo tomcat/sandbox/java/org/apache/coyote/servlet/util/ tomcat/sandbox/java/org/apache/coyote/servlet/util/CharsetMapper.java tomcat/sandbox/java/org/apache/coyote/servlet/util/CharsetMapperDefault.properties tomcat/sandbox/java/org/apache/coyote/servlet/util/Enumerator.java tomcat/sandbox/java/org/apache/coyote/servlet/util/LocalStrings.properties tomcat/sandbox/java/org/apache/coyote/servlet/util/ParameterMap.java tomcat/sandbox/java/org/apache/coyote/servlet/util/RequestUtil.java tomcat/sandbox/java/org/apache/coyote/servlet/util/StringParser.java Added: tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationAuthorization.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationAuthorization.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationAuthorization.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationAuthorization.java Fri May 19 19:12:51 2006 @@ -0,0 +1,23 @@ +/* + */ +package org.apache.coyote.servlet; + +import java.security.Principal; + +/** Subset of Realm. + * + * Authentication and web.xml-defined authorization are done in a filter ( valve ), + * this is needed for the programmatic callbacks. + * + * + * + * @author Costin Manolache + */ +public class ApplicationAuthorization { + + public boolean hasRole(Principal userPrincipal, String realRole) { + return false; + } + + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationFilterFactory.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationFilterFactory.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationFilterFactory.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/ApplicationFilterFactory.java Fri May 19 19:12:51 2006 @@ -0,0 +1,347 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.coyote.servlet; + + +import javax.servlet.Servlet; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; + +//import org.apache.catalina.Globals; + +/** + * Factory for the creation and caching of Filters and creationg + * of Filter Chains. + * + * costin: This is another mapping - done in RequestDispatcher. + * Also: StandardHostValve - sets attribute for error pages, + * StandardWrapperValve - mapping per invocation + * + * @author Greg Murray + * @author Remy Maucherat + * @version $Revision: 1.0 + */ + +public final class ApplicationFilterFactory { + + + // -------------------------------------------------------------- Constants + + + public static final int ERROR = 1; + public static final Integer ERROR_INTEGER = new Integer(ERROR); + public static final int FORWARD = 2; + public static final Integer FORWARD_INTEGER = new Integer(FORWARD); + public static final int INCLUDE = 4; + public static final Integer INCLUDE_INTEGER = new Integer(INCLUDE); + public static final int REQUEST = 8; + public static final Integer REQUEST_INTEGER = new Integer(REQUEST); + + /** + * Request dispatcher state. + */ + public static final String DISPATCHER_TYPE_ATTR = + "org.apache.catalina.core.DISPATCHER_TYPE"; + + /** + * Request dispatcher path. + */ + public static final String DISPATCHER_REQUEST_PATH_ATTR = + "org.apache.catalina.core.DISPATCHER_REQUEST_PATH"; + + private static final SecurityManager securityManager = + System.getSecurityManager(); + + private static ApplicationFilterFactory factory = null;; + + + // ----------------------------------------------------------- Constructors + + + /* + * Prevent instanciation outside of the getInstanceMethod(). + */ + private ApplicationFilterFactory() { + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Return the fqctory instance. + */ + public static ApplicationFilterFactory getInstance() { + if (factory == null) { + factory = new ApplicationFilterFactory(); + } + return factory; + } + + + /** + * Construct and return a FilterChain implementation that will wrap the + * execution of the specified servlet instance. If we should not execute + * a filter chain at all, return null. + * + * @param request The servlet request we are processing + * @param servlet The servlet instance to be wrapped + */ + public FilterChainImpl createFilterChain + (ServletRequest request, ServletConfigImpl wrapper, Servlet servlet) { + + // get the dispatcher type + int dispatcher = -1; + if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) { + Integer dispatcherInt = + (Integer) request.getAttribute(DISPATCHER_TYPE_ATTR); + dispatcher = dispatcherInt.intValue(); + } + String requestPath = null; + Object attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR); + + if (attribute != null){ + requestPath = attribute.toString(); + } + + HttpServletRequest hreq = null; + if (request instanceof HttpServletRequest) + hreq = (HttpServletRequest)request; + // If there is no servlet to execute, return null + if (servlet == null) + return (null); + + // Create and initialize a filter chain object + FilterChainImpl filterChain = null; + if ((securityManager == null) && (request instanceof ServletRequestImpl)) { + ServletRequestImpl req = (ServletRequestImpl) request; + filterChain = (FilterChainImpl) req.getFilterChain(); + if (filterChain == null) { + filterChain = new FilterChainImpl(); + req.setFilterChain(filterChain); + } + } else { + // Security: Do not recycle + filterChain = new FilterChainImpl(); + } + + filterChain.setServlet(servlet); + +// filterChain.setSupport +// (((ServletWrapper)wrapper).getInstanceSupport()); + + // Acquire the filter mappings for this Context + ServletContextImpl context = (ServletContextImpl) wrapper.getParent(); + FilterMap filterMaps[] = context.findFilterMaps(); + + // If there are no filter mappings, we are done + if ((filterMaps == null) || (filterMaps.length == 0)) + return (filterChain); + + // Acquire the information we will need to match filter mappings + String servletName = wrapper.getName(); + + int n = 0; + + // Add the relevant path-mapped filters to this filter chain + for (int i = 0; i < filterMaps.length; i++) { + if (!matchDispatcher(filterMaps[i] ,dispatcher)) { + continue; + } + if (!matchFiltersURL(filterMaps[i], requestPath)) + continue; + FilterConfigImpl filterConfig = (FilterConfigImpl) + context.findFilterConfig(filterMaps[i].getFilterName()); + if (filterConfig == null) { + ; // FIXME - log configuration problem + continue; + } + filterChain.addFilter(filterConfig); + n++; + } + + // Add filters that match on servlet name second + for (int i = 0; i < filterMaps.length; i++) { + if (!matchDispatcher(filterMaps[i] ,dispatcher)) { + continue; + } + if (!matchFiltersServlet(filterMaps[i], servletName)) + continue; + FilterConfigImpl filterConfig = (FilterConfigImpl) + context.findFilterConfig(filterMaps[i].getFilterName()); + if (filterConfig == null) { + ; // FIXME - log configuration problem + continue; + } + filterChain.addFilter(filterConfig); + n++; + } + + // Return the completed filter chain + return (filterChain); + + } + + + // -------------------------------------------------------- Private Methods + + + /** + * Return true if the context-relative request path + * matches the requirements of the specified filter mapping; + * otherwise, return null. + * + * @param filterMap Filter mapping being checked + * @param requestPath Context-relative request path of this request + */ + private boolean matchFiltersURL(FilterMap filterMap, String requestPath) { + + if (requestPath == null) + return (false); + + // Match on context relative request path + String testPath = filterMap.getURLPattern(); + if (testPath == null) + return (false); + + // Case 1 - Exact Match + if (testPath.equals(requestPath)) + return (true); + + // Case 2 - Path Match ("/.../*") + if (testPath.equals("/*")) + return (true); + if (testPath.endsWith("/*")) { + if (testPath.regionMatches(0, requestPath, 0, + testPath.length() - 2)) { + if (requestPath.length() == (testPath.length() - 2)) { + return (true); + } else if ('/' == requestPath.charAt(testPath.length() - 2)) { + return (true); + } + } + return (false); + } + + // Case 3 - Extension Match + if (testPath.startsWith("*.")) { + int slash = requestPath.lastIndexOf('/'); + int period = requestPath.lastIndexOf('.'); + if ((slash >= 0) && (period > slash) + && (period != requestPath.length() - 1) + && ((requestPath.length() - period) + == (testPath.length() - 1))) { + return (testPath.regionMatches(2, requestPath, period + 1, + testPath.length() - 2)); + } + } + + // Case 4 - "Default" Match + return (false); // NOTE - Not relevant for selecting filters + + } + + + /** + * Return true if the specified servlet name matches + * the requirements of the specified filter mapping; otherwise + * return false. + * + * @param filterMap Filter mapping being checked + * @param servletName Servlet name being checked + */ + private boolean matchFiltersServlet(FilterMap filterMap, + String servletName) { + + if (servletName == null) { + return (false); + } else { + if (servletName.equals(filterMap.getServletName())) { + return (true); + } else { + return false; + } + } + + } + + + /** + * Convienience method which returns true if the dispatcher type + * matches the dispatcher types specified in the FilterMap + */ + private boolean matchDispatcher(FilterMap filterMap, int dispatcher) { + switch (dispatcher) { + case FORWARD : { + if (filterMap.getDispatcherMapping() == FilterMap.FORWARD || + filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) { + return true; + } + break; + } + case INCLUDE : { + if (filterMap.getDispatcherMapping() == FilterMap.INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) { + return true; + } + break; + } + case REQUEST : { + if (filterMap.getDispatcherMapping() == FilterMap.REQUEST || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE) { + return true; + } + break; + } + case ERROR : { + if (filterMap.getDispatcherMapping() == FilterMap.ERROR || + filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR || + filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE || + filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE) { + return true; + } + break; + } + } + return false; + } + + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/CoyoteServletFacade.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/CoyoteServletFacade.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/CoyoteServletFacade.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/CoyoteServletFacade.java Fri May 19 19:12:51 2006 @@ -0,0 +1,429 @@ +/* + */ +package org.apache.coyote.servlet; + +import java.io.IOException; +import java.util.HashMap; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.apache.coyote.ActionCode; +import org.apache.coyote.Adapter; +import org.apache.coyote.Request; +import org.apache.coyote.Response; +import org.apache.coyote.adapters.FileAdapter; +import org.apache.coyote.http11.Http11Protocol; +import org.apache.coyote.standalone.MessageWriter; +import org.apache.tomcat.util.buf.ByteChunk; +import org.apache.tomcat.util.buf.MessageBytes; +import org.apache.tomcat.util.http.mapper.Mapper; +import org.apache.tomcat.util.http.mapper.MappingData; +import org.apache.tomcat.util.res.StringManager; + +/** + * Frontend for a minimal servlet impl for coyote. + * + * This is based on catalina classes, with non-essential features removed. + * It is possible to add back some of the flexibility using callbacks/hooks, but + * without requiring additional code - this package should be a sufficient + * implementation for a working servlet container. + * + * @author Costin Manolache + */ +public class CoyoteServletFacade { + static CoyoteServletFacade facade = new CoyoteServletFacade(); + + protected HashMap hosts = new HashMap(); + protected Http11Protocol proto; + Mapper mapper = new Mapper(); + Mapper authMapper = new Mapper(); + + String hostname = ""; // current hostname, used for settings + + protected CoyoteServletProcessor mainAdapter; + FileAdapter fa = new FileAdapter(); + + + private CoyoteServletFacade() { + proto = new Http11Protocol(); + + mainAdapter = new CoyoteServletProcessor(mapper); + + //Counters cnt=new Counters(); + //cnt.setNext( mainAdapter ); + proto.setAdapter(mainAdapter); + //proto.setAdapter(cnt); + + //mapper.addWrapper("*", fa); + mapper.setDefaultHostName("localhost"); + + } + + public static CoyoteServletFacade getServletImpl() { + // TODO: restrict access to only first call. + return facade; + } + + public void initHttp(int port) { + proto.setPort(port); + } + + public void start() { + if( proto.getPort() == 0 ) { //&& + //proto.getEndpoint().getServerSocket() == null) { + proto.setPort(8800); + } + + try { + proto.init(); + + proto.getEndpoint().setDaemon(false); + + proto.start(); + + } catch (Throwable e) { + e.printStackTrace(); + } + } + + // TODO: make sure the mapper is the only one holding references to any + // of the objects - better reloading + + /** + * + * @param hostname - "" if default host, or string to be matched with Host header + * @param path - context path, "/" for root, "/examples", etc + * @return a servlet context + */ + public ServletContext createServletContext(String hostname, String path) { + Host host = (Host)hosts.get(hostname); + if( host == null ) { + host = new Host(); + host.setName(hostname); + hosts.put(hostname, host); + mapper.addHost(hostname, new String[] {}, host); + } + ServletContextImpl ctx = new ServletContextImpl(path); + ctx.setParent(host); + ctx.setPath(path); + + // TODO: read web.xml or equivalent + + // TODO: defaults + // + mapper.addContext(hostname, path, ctx, new String[] {"index.html"}, + null); + mapper.addWrapper(hostname, path, "/", fa); + host.addChild(ctx); + return ctx; + } + + // -------------- Web.xml reader will call this --------- + // For specialized cases - you can call this directly + // Experiment: WebXmlConfig to call this or generate properties, then + // at run time read the properties. + + public void setContextParams(ServletContext ctx, HashMap params) { + ((ServletContextImpl)ctx).setContextParameters(params); + } + + public ServletConfig createServletWrapper(ServletContext ctx, + String name, Servlet servlet) throws ServletException { + ServletConfigImpl w = new ServletConfigImpl(); + // TODO: postpone to first use + // TODO: grab config + servlet.init(w); + w.setServlet(servlet); + w.setParent((ServletContextImpl)ctx); + return w; + } + + public void addMapping(String path, ServletConfig wrapper) { + ServletContextImpl ctx = (ServletContextImpl)wrapper.getServletContext(); + Host host = (ctx).getParent(); + mapper.addWrapper(host.getName(), ctx.getPath(), path, + new CoyoteServletAdapter(wrapper)); + } + + // TODO: auth + + public static class CoyoteServletProcessor implements Adapter { + private Mapper mapper=new Mapper(); + + public CoyoteServletProcessor(Mapper mapper2) { + mapper = mapper2; + } + + public void service(Request req, final Response res) + throws Exception { + try { + + MessageBytes decodedURI = req.decodedURI(); + decodedURI.duplicate(req.requestURI()); + + if (decodedURI.getType() == MessageBytes.T_BYTES) { + // %xx decoding of the URL + try { + req.getURLDecoder().convert(decodedURI, false); + } catch (IOException ioe) { + res.setStatus(400); + res.setMessage("Invalid URI"); + throw ioe; + } + // Normalization + if (!normalize(req.decodedURI())) { + res.setStatus(400); + res.setMessage("Invalid URI"); + return; + } + // Character decoding + //convertURI(decodedURI, request); + } else { + // The URL is chars or String, and has been sent using an in-memory + // protocol handler, we have to assume the URL has been properly + // decoded already + decodedURI.toChars(); + } + + + + // TODO: per thread data - does it help ? + + MappingData mapRes = new MappingData(); + mapper.map(req.remoteHost(), req.decodedURI(), + mapRes); + + Adapter h=(Adapter)mapRes.wrapper; + if (h != null) { + h.service( req, res ); + } + + } catch( Throwable t ) { + t.printStackTrace(System.out); + } + + // Final processing + MessageWriter.getWriter(req, res, 0).flush(); + res.finish(); + + req.recycle(); + res.recycle(); + + } + + /** + * Normalize URI. + *

+ * This method normalizes "\", "//", "/./" and "/../". This method will + * return false when trying to go above the root, or if the URI contains + * a null byte. + * + * @param uriMB URI to be normalized + */ + public static boolean normalize(MessageBytes uriMB) { + + ByteChunk uriBC = uriMB.getByteChunk(); + byte[] b = uriBC.getBytes(); + int start = uriBC.getStart(); + int end = uriBC.getEnd(); + + // URL * is acceptable + if ((end - start == 1) && b[start] == (byte) '*') + return true; + + int pos = 0; + int index = 0; + + // Replace '\' with '/' + // Check for null byte + for (pos = start; pos < end; pos++) { + if (b[pos] == (byte) '\\') + b[pos] = (byte) '/'; + if (b[pos] == (byte) 0) + return false; + } + + // The URL must start with '/' + if (b[start] != (byte) '/') { + return false; + } + + // Replace "//" with "/" + for (pos = start; pos < (end - 1); pos++) { + if (b[pos] == (byte) '/') { + while ((pos + 1 < end) && (b[pos + 1] == (byte) '/')) { + copyBytes(b, pos, pos + 1, end - pos - 1); + end--; + } + } + } + + // If the URI ends with "/." or "/..", then we append an extra "/" + // Note: It is possible to extend the URI by 1 without any side effect + // as the next character is a non-significant WS. + if (((end - start) >= 2) && (b[end - 1] == (byte) '.')) { + if ((b[end - 2] == (byte) '/') + || ((b[end - 2] == (byte) '.') + && (b[end - 3] == (byte) '/'))) { + b[end] = (byte) '/'; + end++; + } + } + + uriBC.setEnd(end); + + index = 0; + + // Resolve occurrences of "/./" in the normalized path + while (true) { + index = uriBC.indexOf("/./", 0, 3, index); + if (index < 0) + break; + copyBytes(b, start + index, start + index + 2, + end - start - index - 2); + end = end - 2; + uriBC.setEnd(end); + } + + index = 0; + + // Resolve occurrences of "/../" in the normalized path + while (true) { + index = uriBC.indexOf("/../", 0, 4, index); + if (index < 0) + break; + // Prevent from going outside our context + if (index == 0) + return false; + int index2 = -1; + for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --) { + if (b[pos] == (byte) '/') { + index2 = pos; + } + } + copyBytes(b, start + index2, start + index + 3, + end - start - index - 3); + end = end + index2 - index - 3; + uriBC.setEnd(end); + index = index2; + } + + //uriBC.setBytes(b, start, end); + uriBC.setEnd(end); + return true; + + } + + + /** + * Copy an array of bytes to a different position. Used during + * normalization. + */ + protected static void copyBytes(byte[] b, int dest, int src, int len) { + for (int pos = 0; pos < len; pos++) { + b[pos + dest] = b[pos + src]; + } + } + + public boolean event(Request req, Response res, boolean error) throws Exception { + // TODO Auto-generated method stub + return false; + } + + } + + public static class CoyoteServletAdapter implements Adapter { + static StringManager sm = StringManager.getManager("org.apache.coyote.servlet"); + + private static org.apache.commons.logging.Log log= + org.apache.commons.logging.LogFactory.getLog( CoyoteServletAdapter.class ); + + + public static final int ADAPTER_NOTES = 1; + + ServletConfigImpl servletConfig; + + public CoyoteServletAdapter( ServletConfig cfg ) { + this.servletConfig = (ServletConfigImpl)cfg; + } + + + /** Coyote / mapper adapter. Result of the mapper. + * + * This replaces the valve chain, the path is: + * 1. coyote calls mapper -> result Adapter + * 2. service is called. Additional filters are set on the wrapper. + */ + public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) + throws IOException { + + ServletRequestImpl request = (ServletRequestImpl) req.getNote(ADAPTER_NOTES); + ServletResponseImpl response = (ServletResponseImpl) res.getNote(ADAPTER_NOTES); + + if (request == null) { + + // Create objects + request = new ServletRequestImpl(); + request.setCoyoteRequest(req); + response = new ServletResponseImpl(); + response.setRequest(request); + response.setCoyoteResponse(res); + + // Link objects + request.setResponse(response); + + // Set as notes + req.setNote(ADAPTER_NOTES, request); + res.setNote(ADAPTER_NOTES, response); + + // Set query string encoding +// req.getParameters().setQueryStringEncoding +// (connector.getURIEncoding()); + + } + + try { + + // Parse and set Catalina and configuration specific + // request parameters +// if ( postParseRequest(req, request, res, response) ) { +// // Calling the container +// connector.getContainer().getPipeline().getFirst().invoke(request, response); +// } + // Catalina default valves : + // Find host/context + // apply auth filters + // + + + Servlet servlet = servletConfig.allocate(); + + servlet.service(request, response); + + response.finishResponse(); + req.action( ActionCode.ACTION_POST_REQUEST , null); + + } catch (IOException e) { + ; + } catch (Throwable t) { + log.error(sm.getString("coyoteAdapter.service"), t); + } finally { + // Recycle the wrapper request and response + request.recycle(); + response.recycle(); + } + + } + + + public boolean event(Request req, Response res, boolean error) throws Exception { + // TODO Auto-generated method stub + return false; + } + + } + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/FilterChainImpl.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/FilterChainImpl.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/FilterChainImpl.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/FilterChainImpl.java Fri May 19 19:12:51 2006 @@ -0,0 +1,340 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.coyote.servlet; + + +import java.io.IOException; +import java.security.PrivilegedActionException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tomcat.util.res.StringManager; + +// Not thread safe !! + +/** + * Implementation of javax.servlet.FilterChain used to manage + * the execution of a set of filters for a particular request. When the + * set of defined filters has all been executed, the next call to + * doFilter() will execute the servlet's service() + * method itself. + * + * @author Craig R. McClanahan + * @version $Revision: 303523 $ $Date: 2004-11-22 08:35:18 -0800 (Mon, 22 Nov 2004) $ + */ + +final class FilterChainImpl implements FilterChain { + + + // -------------------------------------------------------------- Constants + + + public static final int INCREMENT = 10; + + + // ----------------------------------------------------------- Constructors + + + /** + * Construct a new chain instance with no defined filters. + */ + public FilterChainImpl() { + + super(); + + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * Filters. + */ + private FilterConfigImpl[] filters = + new FilterConfigImpl[0]; + + + /** + * The int which is used to maintain the current position + * in the filter chain. + */ + private int pos = 0; + + + /** + * The int which gives the current number of filters in the chain. + */ + private int n = 0; + + + /** + * The servlet instance to be executed by this chain. + */ + private Servlet servlet = null; + + + /** + * The string manager for our package. + */ + private static final StringManager sm = + StringManager.getManager("org.apache.coyote.servlet"); + + + /** + * The InstanceSupport instance associated with our Wrapper (used to + * send "before filter" and "after filter" events. + */ +// private InstanceSupport support = null; + + + /** + * Static class array used when the SecurityManager is turned on and + * doFilterserviceservice() method of the servlet itself. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet exception occurs + */ + public void doFilter(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + + if( System.getSecurityManager() != null ) { + final ServletRequest req = request; + final ServletResponse res = response; + try { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Object run() + throws ServletException, IOException { + internalDoFilter(req,res); + return null; + } + } + ); + } catch( PrivilegedActionException pe) { + Exception e = pe.getException(); + if (e instanceof ServletException) + throw (ServletException) e; + else if (e instanceof IOException) + throw (IOException) e; + else if (e instanceof RuntimeException) + throw (RuntimeException) e; + else + throw new ServletException(e.getMessage(), e); + } + } else { + internalDoFilter(request,response); + } + } + + private void internalDoFilter(ServletRequest request, + ServletResponse response) + throws IOException, ServletException { + + // Call the next filter if there is one + if (pos < n) { + FilterConfigImpl filterConfig = filters[pos++]; + Filter filter = null; + try { + filter = filterConfig.getFilter(); +// support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT, +// filter, request, response); + +// if( System.getSecurityManager() != null ) { +// final ServletRequest req = request; +// final ServletResponse res = response; +// Principal principal = +// ((HttpServletRequest) req).getUserPrincipal(); +// +// Object[] args = new Object[]{req, res, this}; +// SecurityUtil.doAsPrivilege +// ("doFilter", filter, classType, args); +// +// args = null; +// } else { + filter.doFilter(request, response, this); +// } + +// support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, +// filter, request, response); + } catch (IOException e) { +// if (filter != null) +// support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, +// filter, request, response, e); + throw e; + } catch (ServletException e) { +// if (filter != null) +// support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, +// filter, request, response, e); + throw e; + } catch (RuntimeException e) { +// if (filter != null) +// support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, +// filter, request, response, e); + throw e; + } catch (Throwable e) { +// if (filter != null) +// support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT, +// filter, request, response, e); + throw new ServletException + (sm.getString("filterChain.filter"), e); + } + return; + } + + // We fell off the end of the chain -- call the servlet instance + try { +// support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT, +// servlet, request, response); + if ((request instanceof HttpServletRequest) && + (response instanceof HttpServletResponse)) { +// +// if( System.getSecurityManager() != null ) { +// final ServletRequest req = request; +// final ServletResponse res = response; +// Principal principal = +// ((HttpServletRequest) req).getUserPrincipal(); +// Object[] args = new Object[]{req, res}; +// SecurityUtil.doAsPrivilege("service", +// servlet, +// classTypeUsedInService, +// args, +// principal); +// args = null; +// } else { + servlet.service((HttpServletRequest) request, + (HttpServletResponse) response); +// } + } else { + servlet.service(request, response); + } +// support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, +// servlet, request, response); + } catch (IOException e) { +// support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, +// servlet, request, response, e); + throw e; + } catch (ServletException e) { +// support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, +// servlet, request, response, e); + throw e; + } catch (RuntimeException e) { +// support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, +// servlet, request, response, e); + throw e; + } catch (Throwable e) { +// support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, +// servlet, request, response, e); + throw new ServletException + (sm.getString("filterChain.servlet"), e); + } + + } + + + // -------------------------------------------------------- Package Methods + + + + /** + * Add a filter to the set of filters that will be executed in this chain. + * + * @param filterConfig The FilterConfig for the servlet to be executed + */ + void addFilter(FilterConfigImpl filterConfig) { + + if (n == filters.length) { + FilterConfigImpl[] newFilters = + new FilterConfigImpl[n + INCREMENT]; + System.arraycopy(filters, 0, newFilters, 0, n); + filters = newFilters; + } + filters[n++] = filterConfig; + + } + + + /** + * Release references to the filters and wrapper executed by this chain. + */ + void release() { + + n = 0; + pos = 0; + servlet = null; +// support = null; + + } + + + /** + * Set the servlet that will be executed at the end of this chain. + * + * @param servlet The Wrapper for the servlet to be executed + */ + void setServlet(Servlet servlet) { + + this.servlet = servlet; + + } + + + /** + * Set the InstanceSupport object used for event notifications + * for this filter chain. + * + * @param support The InstanceSupport object for our Wrapper + */ +// void setSupport(InstanceSupport support) { +// +// this.support = support; +// +// } + + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/FilterConfigImpl.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/FilterConfigImpl.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/FilterConfigImpl.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/FilterConfigImpl.java Fri May 19 19:12:51 2006 @@ -0,0 +1,214 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.coyote.servlet; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.apache.coyote.servlet.util.Enumerator; +import org.apache.tomcat.util.log.SystemLogHandler; + + +/** + * A Filter is configured in web.xml by: + * - name - used in mappings + * - className - used to instantiate the filter + * - init params + * - other things not used in the servlet container ( icon, descr, etc ) + * + * + */ +final class FilterConfigImpl implements FilterConfig, Serializable { + + public FilterConfigImpl(ServletContextImpl context) { + super(); + this.context = context; + } + + /** + * The Context with which we are associated. + */ + private ServletContextImpl context = null; + + /** + * The application Filter we are configured for. + */ + private transient Filter filter = null; + + private String filterName = null; + + void setFilterName(String filterName) { + this.filterName = filterName; + } + + private Map parameters = new HashMap(); + + public Map getParameterMap() { + return (this.parameters); + } + + private String filterClass = null; + + public String getFilterClass() { + return (this.filterClass); + } + + public void setFilterClass(String filterClass) { + this.filterClass = filterClass; + } + + + + // --------------------------------------------------- FilterConfig Methods + + public String getFilterName() { + return (this.filterName); + } + + public String getInitParameter(String name) { + Map map = getParameterMap(); + if (map == null) + return (null); + else + return ((String) map.get(name)); + } + + + /** + * Return an Enumeration of the names of the initialization + * parameters for this Filter. + */ + public Enumeration getInitParameterNames() { + + Map map = getParameterMap(); + if (map == null) + return (new Enumerator(new ArrayList())); + else + return (new Enumerator(map.keySet())); + + } + + + /** + * Return the ServletContext of our associated web application. + */ + public ServletContext getServletContext() { + + return (this.context.getServletContext()); + + } + + + /** + * Return a String representation of this object. + */ + public String toString() { + + StringBuffer sb = new StringBuffer("ApplicationFilterConfig["); + sb.append("name="); + sb.append(getFilterName()); + sb.append(", filterClass="); + sb.append(getFilterClass()); + sb.append("]"); + return (sb.toString()); + + } + + + // -------------------------------------------------------- Package Methods + + + /** + * Return the application Filter we are configured for. + * + * @exception ClassCastException if the specified class does not implement + * the javax.servlet.Filter interface + * @exception ClassNotFoundException if the filter class cannot be found + * @exception IllegalAccessException if the filter class cannot be + * publicly instantiated + * @exception InstantiationException if an exception occurs while + * instantiating the filter object + * @exception ServletException if thrown by the filter's init() method + */ + Filter getFilter() throws ClassCastException, ClassNotFoundException, + IllegalAccessException, InstantiationException, ServletException { + + // Return the existing filter instance, if any + if (this.filter != null) + return (this.filter); + + // Identify the class loader we will be using + String filterClass = getFilterClass(); + ClassLoader classLoader = null; + if (filterClass.startsWith("org.apache.catalina.")) + classLoader = this.getClass().getClassLoader(); + else + classLoader = context.getClassLoader(); + + ClassLoader oldCtxClassLoader = + Thread.currentThread().getContextClassLoader(); + + // Instantiate a new instance of this filter and return it + Class clazz = classLoader.loadClass(filterClass); + this.filter = (Filter) clazz.newInstance(); + if (context instanceof ServletContextImpl && + ((ServletContextImpl)context).getSwallowOutput()) { + try { + SystemLogHandler.startCapture(); + filter.init(this); + } finally { + String log = SystemLogHandler.stopCapture(); + if (log != null && log.length() > 0) { + getServletContext().log(log); + } + } + } else { + filter.init(this); + } + return (this.filter); + + } + + + /** + * Release the Filter instance associated with this FilterConfig, + * if there is one. + */ + void release() { + + if (this.filter != null){ + filter.destroy(); + } + this.filter = null; + + } + + + // -------------------------------------------------------- Private Methods + + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/FilterMap.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/FilterMap.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/FilterMap.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/FilterMap.java Fri May 19 19:12:51 2006 @@ -0,0 +1,215 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.coyote.servlet; + + +import java.io.Serializable; + +import org.apache.coyote.servlet.util.RequestUtil; + + +/** + * Representation of a filter mapping for a web application, as represented + * in a <filter-mapping> element in the deployment + * descriptor. Each filter mapping must contain a filter name plus either + * a URL pattern or a servlet name. + * + * @author Craig R. McClanahan + * @version $Revision: 302879 $ $Date: 2004-05-13 13:40:49 -0700 (Thu, 13 May 2004) $ + */ + +public class FilterMap implements Serializable { + + + // ------------------------------------------------------------- Properties + + + /** + * The name of this filter to be executed when this mapping matches + * a particular request. + */ + + public static final int ERROR = 1; + public static final int FORWARD = 2; + public static final int FORWARD_ERROR =3; + public static final int INCLUDE = 4; + public static final int INCLUDE_ERROR = 5; + public static final int INCLUDE_ERROR_FORWARD =6; + public static final int INCLUDE_FORWARD = 7; + public static final int REQUEST = 8; + public static final int REQUEST_ERROR = 9; + public static final int REQUEST_ERROR_FORWARD = 10; + public static final int REQUEST_ERROR_FORWARD_INCLUDE = 11; + public static final int REQUEST_ERROR_INCLUDE = 12; + public static final int REQUEST_FORWARD = 13; + public static final int REQUEST_INCLUDE = 14; + public static final int REQUEST_FORWARD_INCLUDE= 15; + + // represents nothing having been set. This will be seen + // as equal to a REQUEST + private static final int NOT_SET = -1; + + private int dispatcherMapping=NOT_SET; + + private String filterName = null; + + public String getFilterName() { + return (this.filterName); + } + + public void setFilterName(String filterName) { + this.filterName = filterName; + } + + + /** + * The servlet name this mapping matches. + */ + private String servletName = null; + + public String getServletName() { + return (this.servletName); + } + + public void setServletName(String servletName) { + this.servletName = servletName; + } + + + /** + * The URL pattern this mapping matches. + */ + private String urlPattern = null; + + public String getURLPattern() { + return (this.urlPattern); + } + + public void setURLPattern(String urlPattern) { + this.urlPattern = RequestUtil.URLDecode(urlPattern); + } + + /** + * + * This method will be used to set the current state of the FilterMap + * representing the state of when filters should be applied: + * + * ERROR + * FORWARD + * FORWARD_ERROR + * INCLUDE + * INCLUDE_ERROR + * INCLUDE_ERROR_FORWARD + * REQUEST + * REQUEST_ERROR + * REQUEST_ERROR_INCLUDE + * REQUEST_ERROR_FORWARD_INCLUDE + * REQUEST_INCLUDE + * REQUEST_FORWARD, + * REQUEST_FORWARD_INCLUDE + * + */ + public void setDispatcher(String dispatcherString) { + String dispatcher = dispatcherString.toUpperCase(); + + if (dispatcher.equals("FORWARD")) { + + // apply FORWARD to the global dispatcherMapping. + switch (dispatcherMapping) { + case NOT_SET : dispatcherMapping = FORWARD; break; + case ERROR : dispatcherMapping = FORWARD_ERROR; break; + case INCLUDE : dispatcherMapping = INCLUDE_FORWARD; break; + case INCLUDE_ERROR : dispatcherMapping = INCLUDE_ERROR_FORWARD; break; + case REQUEST : dispatcherMapping = REQUEST_FORWARD; break; + case REQUEST_ERROR : dispatcherMapping = REQUEST_ERROR_FORWARD; break; + case REQUEST_ERROR_INCLUDE : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break; + case REQUEST_INCLUDE : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break; + } + } else if (dispatcher.equals("INCLUDE")) { + // apply INCLUDE to the global dispatcherMapping. + switch (dispatcherMapping) { + case NOT_SET : dispatcherMapping = INCLUDE; break; + case ERROR : dispatcherMapping = INCLUDE_ERROR; break; + case FORWARD : dispatcherMapping = INCLUDE_FORWARD; break; + case FORWARD_ERROR : dispatcherMapping = INCLUDE_ERROR_FORWARD; break; + case REQUEST : dispatcherMapping = REQUEST_INCLUDE; break; + case REQUEST_ERROR : dispatcherMapping = REQUEST_ERROR_INCLUDE; break; + case REQUEST_ERROR_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break; + case REQUEST_FORWARD : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break; + } + } else if (dispatcher.equals("REQUEST")) { + // apply REQUEST to the global dispatcherMapping. + switch (dispatcherMapping) { + case NOT_SET : dispatcherMapping = REQUEST; break; + case ERROR : dispatcherMapping = REQUEST_ERROR; break; + case FORWARD : dispatcherMapping = REQUEST_FORWARD; break; + case FORWARD_ERROR : dispatcherMapping = REQUEST_ERROR_FORWARD; break; + case INCLUDE : dispatcherMapping = REQUEST_INCLUDE; break; + case INCLUDE_ERROR : dispatcherMapping = REQUEST_ERROR_INCLUDE; break; + case INCLUDE_FORWARD : dispatcherMapping = REQUEST_FORWARD_INCLUDE; break; + case INCLUDE_ERROR_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break; + } + } else if (dispatcher.equals("ERROR")) { + // apply ERROR to the global dispatcherMapping. + switch (dispatcherMapping) { + case NOT_SET : dispatcherMapping = ERROR; break; + case FORWARD : dispatcherMapping = FORWARD_ERROR; break; + case INCLUDE : dispatcherMapping = INCLUDE_ERROR; break; + case INCLUDE_FORWARD : dispatcherMapping = INCLUDE_ERROR_FORWARD; break; + case REQUEST : dispatcherMapping = REQUEST_ERROR; break; + case REQUEST_INCLUDE : dispatcherMapping = REQUEST_ERROR_INCLUDE; break; + case REQUEST_FORWARD : dispatcherMapping = REQUEST_ERROR_FORWARD; break; + case REQUEST_FORWARD_INCLUDE : dispatcherMapping = REQUEST_ERROR_FORWARD_INCLUDE; break; + } + } + } + + public int getDispatcherMapping() { + // per the SRV.6.2.5 absence of any dispatcher elements is + // equivelant to a REQUEST value + if (dispatcherMapping == NOT_SET) return REQUEST; + else return dispatcherMapping; + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Render a String representation of this object. + */ + public String toString() { + + StringBuffer sb = new StringBuffer("FilterMap["); + sb.append("filterName="); + sb.append(this.filterName); + if (servletName != null) { + sb.append(", servletName="); + sb.append(servletName); + } + if (urlPattern != null) { + sb.append(", urlPattern="); + sb.append(urlPattern); + } + sb.append("]"); + return (sb.toString()); + + } + + +} Added: tomcat/sandbox/java/org/apache/coyote/servlet/Globals.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/Globals.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/Globals.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/Globals.java Fri May 19 19:12:51 2006 @@ -0,0 +1,324 @@ +/* + * Copyright 1999,2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.coyote.servlet; + + +/** + * Global constants that are applicable to multiple packages within Catalina. + * + * @author Craig R. McClanahan + * @version $Revision: 303495 $ $Date: 2004-11-18 22:07:56 -0800 (Thu, 18 Nov 2004) $ + */ + +public final class Globals { + + /** + * The servlet context attribute under which we store the alternate + * deployment descriptor for this web application + */ + public static final String ALT_DD_ATTR = + "org.apache.catalina.deploy.alt_dd"; + + /** + * The request attribute under which we store the array of X509Certificate + * objects representing the certificate chain presented by our client, + * if any. + */ + public static final String CERTIFICATES_ATTR = + "javax.servlet.request.X509Certificate"; + + /** + * The request attribute under which we store the name of the cipher suite + * being used on an SSL connection (as an object of type + * java.lang.String). + */ + public static final String CIPHER_SUITE_ATTR = + "javax.servlet.request.cipher_suite"; + + + /** + * The servlet context attribute under which we store the class loader + * used for loading servlets (as an object of type java.lang.ClassLoader). + */ + public static final String CLASS_LOADER_ATTR = + "org.apache.catalina.classloader"; + + /** + * Request dispatcher state. + */ + public static final String DISPATCHER_TYPE_ATTR = + "org.apache.catalina.core.DISPATCHER_TYPE"; + + /** + * Request dispatcher path. + */ + public static final String DISPATCHER_REQUEST_PATH_ATTR = + "org.apache.catalina.core.DISPATCHER_REQUEST_PATH"; + + /** + * The JNDI directory context which is associated with the context. This + * context can be used to manipulate static files. + */ + public static final String RESOURCES_ATTR = + "org.apache.catalina.resources"; + + + /** + * The servlet context attribute under which we store the class path + * for our application class loader (as an object of type String), + * delimited with the appropriate path delimiter for this platform. + */ + public static final String CLASS_PATH_ATTR = + "org.apache.catalina.jsp_classpath"; + + + /** + * The request attribute under which we forward a Java exception + * (as an object of type Throwable) to an error page. + */ + public static final String EXCEPTION_ATTR = + "javax.servlet.error.exception"; + + + /** + * The request attribute under which we forward the request URI + * (as an object of type String) of the page on which an error occurred. + */ + public static final String EXCEPTION_PAGE_ATTR = + "javax.servlet.error.request_uri"; + + + /** + * The request attribute under which we forward a Java exception type + * (as an object of type Class) to an error page. + */ + public static final String EXCEPTION_TYPE_ATTR = + "javax.servlet.error.exception_type"; + + + /** + * The request attribute under which we forward an HTTP status message + * (as an object of type STring) to an error page. + */ + public static final String ERROR_MESSAGE_ATTR = + "javax.servlet.error.message"; + + + /** + * The request attribute under which the Invoker servlet will store + * the invoking servlet path, if it was used to execute a servlet + * indirectly instead of through a servlet mapping. + */ + public static final String INVOKED_ATTR = + "org.apache.catalina.INVOKED"; + + + /** + * The request attribute under which we expose the value of the + * <jsp-file> value associated with this servlet, + * if any. + */ + public static final String JSP_FILE_ATTR = + "org.apache.catalina.jsp_file"; + + + /** + * The request attribute under which we store the key size being used for + * this SSL connection (as an object of type java.lang.Integer). + */ + public static final String KEY_SIZE_ATTR = + "javax.servlet.request.key_size"; + + /** + * The request attribute under which we store the session id being used + * for this SSL connection (as an object of type java.lang.String). + */ + public static final String SSL_SESSION_ID_ATTR = + "javax.servlet.request.ssl_session"; + + + /** + * The servlet context attribute under which the managed bean Registry + * will be stored for privileged contexts (if enabled). + */ + public static final String MBEAN_REGISTRY_ATTR = + "org.apache.catalina.Registry"; + + + /** + * The servlet context attribute under which the MBeanServer will be stored + * for privileged contexts (if enabled). + */ + public static final String MBEAN_SERVER_ATTR = + "org.apache.catalina.MBeanServer"; + + + /** + * The request attribute under which we store the servlet name on a + * named dispatcher request. + */ + public static final String NAMED_DISPATCHER_ATTR = + "org.apache.catalina.NAMED"; + + + /** + * The request attribute under which the request URI of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_REQUEST_URI_ATTR = + "javax.servlet.include.request_uri"; + + + /** + * The request attribute under which the context path of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_CONTEXT_PATH_ATTR = + "javax.servlet.include.context_path"; + + + /** + * The request attribute under which the path info of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_PATH_INFO_ATTR = + "javax.servlet.include.path_info"; + + + /** + * The request attribute under which the servlet path of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_SERVLET_PATH_ATTR = + "javax.servlet.include.servlet_path"; + + + /** + * The request attribute under which the query string of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_QUERY_STRING_ATTR = + "javax.servlet.include.query_string"; + + + /** + * The request attribute under which the original request URI is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_REQUEST_URI_ATTR = + "javax.servlet.forward.request_uri"; + + + /** + * The request attribute under which the original context path is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_CONTEXT_PATH_ATTR = + "javax.servlet.forward.context_path"; + + + /** + * The request attribute under which the original path info is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_PATH_INFO_ATTR = + "javax.servlet.forward.path_info"; + + + /** + * The request attribute under which the original servlet path is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_SERVLET_PATH_ATTR = + "javax.servlet.forward.servlet_path"; + + + /** + * The request attribute under which the original query string is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_QUERY_STRING_ATTR = + "javax.servlet.forward.query_string"; + + + /** + * The request attribute under which we forward a servlet name to + * an error page. + */ + public static final String SERVLET_NAME_ATTR = + "javax.servlet.error.servlet_name"; + + + /** + * The name of the cookie used to pass the session identifier back + * and forth with the client. + */ + public static final String SESSION_COOKIE_NAME = "JSESSIONID"; + + + /** + * The name of the path parameter used to pass the session identifier + * back and forth with the client. + */ + public static final String SESSION_PARAMETER_NAME = "jsessionid"; + + + /** + * The servlet context attribute under which we store a flag used + * to mark this request as having been processed by the SSIServlet. + * We do this because of the pathInfo mangling happening when using + * the CGIServlet in conjunction with the SSI servlet. (value stored + * as an object of type String) + */ + public static final String SSI_FLAG_ATTR = + "org.apache.catalina.ssi.SSIServlet"; + + + /** + * The request attribute under which we forward an HTTP status code + * (as an object of type Integer) to an error page. + */ + public static final String STATUS_CODE_ATTR = + "javax.servlet.error.status_code"; + + + /** + * The subject under which the AccessControlContext is running. + */ + public static final String SUBJECT_ATTR = + "javax.security.auth.subject"; + + + /** + * The servlet context attribute under which we record the set of + * welcome files (as an object of type String[]) for this application. + */ + public static final String WELCOME_FILES_ATTR = + "org.apache.catalina.WELCOME_FILES"; + + + /** + * The servlet context attribute under which we store a temporary + * working directory (as an object of type File) for use by servlets + * within this web application. + */ + public static final String WORK_DIR_ATTR = + "javax.servlet.context.tempdir"; + + +} --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org