From: costin Date: Tue, 25 May 2010 06:09:40 +0000 (+0000) Subject: Removing the mini-'servlet' code from lite. The goal is to implement connector and... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=9662f229a4f550b0b25c26a869de10b7ee664ee8;p=tomcat7.0 Removing the mini-'servlet' code from lite. The goal is to implement connector and http client, this creates confusion. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@947931 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterChainImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterChainImpl.java deleted file mode 100644 index ab99ee4cc..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterChainImpl.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -/** - * Wraps the list of filters for the current request. One instance - * associated with each RequestImpl, reused. - * - * Populated by the mapper ( WebappFilterMapper for example ), which - * determines the filters for the current request. - * - * Not thread safe. - */ -public final class FilterChainImpl implements FilterChain { - - private List filters = new ArrayList(); - - /** - * The int which is used to maintain the current position - * in the filter chain. - */ - private int pos = 0; - - /** - * The servlet instance to be executed by this chain. - */ - private Servlet servlet = null; - - - private ServletConfigImpl wrapper; - - - public FilterChainImpl() { - super(); - } - - - /** - * Invoke the next filter in this chain, passing the specified request - * and response. If there are no more filters in this chain, invoke - * the service() 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 { - - - // Call the next filter if there is one - if (pos < filters.size()) { - FilterConfigImpl filterConfig = filters.get(pos++); - Filter filter = null; - try { - filter = filterConfig.getFilter(); - filter.doFilter(request, response, this); - } catch (IOException e) { - throw e; - } catch (ServletException e) { - throw e; - } catch (RuntimeException e) { - throw e; - } catch (Throwable e) { - e.printStackTrace(); - throw new ServletException("Throwable", e); - } - return; - } - - // We fell off the end of the chain -- call the servlet instance - try { - if (servlet != null) - servlet.service(request, response); - } catch (IOException e) { - throw e; - } catch (ServletException e) { - throw e; - } catch (RuntimeException e) { - throw e; - } catch (Throwable e) { - throw new ServletException("Throwable", 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 - */ - public void addFilter(FilterConfigImpl filterConfig) { - filters.add(filterConfig); - } - - - /** - * Release references to the filters and wrapper executed by this chain. - */ - public void release() { - filters.clear(); - pos = 0; - servlet = null; - } - - - /** - * Set the servlet that will be executed at the end of this chain. - * Set by the mapper filter - */ - public void setServlet(ServletConfigImpl wrapper, Servlet servlet) { - this.wrapper = wrapper; - this.servlet = servlet; - } - - // ------ Getters for information ------------ - - public int getSize() { - return filters.size(); - } - - public FilterConfigImpl getFilter(int i) { - return filters.get(i); - } - - public Servlet getServlet() { - return servlet; - } - - public ServletConfigImpl getServletConfig() { - return wrapper; - } - - public int getPos() { - return pos; - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterConfigImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterConfigImpl.java deleted file mode 100644 index a94fd5586..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/FilterConfigImpl.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Map; -import java.util.Set; - -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import org.apache.tomcat.servlets.util.Enumerator; - - -/** - * 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 ) - * - * Alternatively, in API mode you can pass the actual filter. - * - * @see ServletConfigImpl - */ -public class FilterConfigImpl implements FilterConfig { - - public FilterConfigImpl(ServletContextImpl context) { - this.ctx = context; - } - - boolean asyncSupported; - - ServletContextImpl ctx = null; - - /** - * The application Filter we are configured for. - */ - private transient Filter filter = null; - - String descryption; - - private String filterName; - - private String filterClassName; - - Map initParams; - - private Class filterClass; - - private boolean initDone = false; - - public void setData(String filterName, String filterClass, - Map params) { - this.filterName = filterName; - this.filterClassName = filterClass; - this.initParams = params; - } - - public void setFilter(Filter f) { - filter = f; - } - - public String getFilterName() { - return filterName; - } - - public void setFilterClass(Class filterClass2) { - this.filterClass = filterClass2; - } - - - public String getInitParameter(String name) { - if (initParams == null) return null; - return initParams.get(name); - } - - /** - * Return an Enumeration of the names of the initialization - * parameters for this Filter. - */ - public Enumeration getInitParameterNames() { - if (initParams == null) - return (new Enumerator(new ArrayList())); - else - return (new Enumerator(initParams.keySet())); - } - - - /** - * Return the ServletContext of our associated web application. - */ - public ServletContext getServletContext() { - return ctx; - } - - /** - * Return the application Filter we are configured for. - */ - public Filter createFilter() throws ClassCastException, ClassNotFoundException, - IllegalAccessException, InstantiationException, ServletException { - - // Return the existing filter instance, if any - if (filter != null) - return filter; - - ClassLoader classLoader = ctx.getClassLoader(); - - ClassLoader oldCtxClassLoader = - Thread.currentThread().getContextClassLoader(); - if (classLoader != oldCtxClassLoader) { - Thread.currentThread().setContextClassLoader(classLoader); - } - try { - if (filterClass == null) { - filterClass = (Class) classLoader.loadClass(filterClassName); - } - this.filter = (Filter) filterClass.newInstance(); - } finally { - if (classLoader != oldCtxClassLoader) { - Thread.currentThread().setContextClassLoader(oldCtxClassLoader); - } - } - - // TODO: resource injection - - return filter; - } - - public Filter getFilter() throws ClassCastException, ClassNotFoundException, IllegalAccessException, InstantiationException, ServletException { - Filter filter = createFilter(); - if (!initDone ) { - filter.init(this); - initDone = true; - } - return (this.filter); - } - - - /** - * Release the Filter instance associated with this FilterConfig, - * if there is one. - */ - public void release() { - if (this.filter != null){ - filter.destroy(); - } - this.filter = null; - } - - public boolean setInitParameter(String name, String value) - throws IllegalArgumentException, IllegalStateException { - return ServletContextImpl.setInitParameter(ctx, initParams, - name, value); - } - - public Set setInitParameters(Map initParameters) - throws IllegalArgumentException, IllegalStateException { - return ServletContextImpl.setInitParameters(ctx, initParams, - initParameters); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/JspLoader.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/JspLoader.java deleted file mode 100644 index 63a301de3..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/JspLoader.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import java.io.IOException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import org.apache.tomcat.lite.http.HttpChannel; -import org.apache.tomcat.lite.http.HttpRequest; -import org.apache.tomcat.servlets.jsp.BaseJspLoader; - -public class JspLoader extends BaseJspLoader { - - public ClassLoader getClassLoader(ServletContext ctx) { - return ((ServletContextImpl) ctx).getClassLoader(); - } - - public String getClassPath(ServletContext ctx) { - return ((ServletContextImpl) ctx).getClassPath(); - } - - protected void compileAndInitPage(ServletContext ctx, - String jspUri, - ServletConfig cfg, - String classPath) - throws ServletException, IOException { - - ServletContextImpl ctxI = (ServletContextImpl)ctx; - HttpChannel server = ctxI.getEngine().getLocalConnector().getServer(); - - HttpRequest req = server.getRequest(); - - req.addParameter("uriroot", ctx.getRealPath("/")); - req.addParameter("jspFiles", jspUri.substring(1)); - req.addParameter("classPath", classPath); - req.addParameter("pkg", getPackage(ctx, jspUri)); - - // TODO: init params to specify - // TODO: remote request - RequestDispatcher disp = ctx.getNamedDispatcher("jspc"); - - ServletRequestImpl sreq = - TomcatLite.getFacade(req); - sreq.setContext((ServletContextImpl) ctx); - disp.forward(sreq, sreq.getResponse()); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/Locale2Charset.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/Locale2Charset.java deleted file mode 100644 index eee852676..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/Locale2Charset.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.InputStream; -import java.util.Locale; -import java.util.Properties; - - - -/** - * One instance per Context. Holds the - * - * Utility class that attempts to map from a Locale to the corresponding - * character set to be used for interpreting input text (or generating - * output text) when the Content-Type header does not include one. You - * can customize the behavior of this class by modifying the mapping data - * it loads, or by subclassing it (to change the algorithm) and then using - * your own version for a particular web application. - * - * @author Craig R. McClanahan - */ -public class Locale2Charset { - - - // shared for all instances - they can add more in a copy - private static Properties defaultMap = new Properties(); - - static { - defaultMap.put("en", "ISO-8859-1"); - } - - Locale2Charset() { - map = defaultMap; - } - - - // ---------------------------------------------------- Instance Variables - - /** - * The mapping properties that have been initialized from the specified or - * default properties resource. - */ - private Properties map; - - - // ------------------------------------------------------- Public Methods - - - /** - * Calculate the name of a character set to be assumed, given the specified - * Locale and the absence of a character set specified as part of the - * content type header. - * - * @param locale The locale for which to calculate a character set - */ - public String getCharset(Locale locale) { - // Match full language_country_variant first, then language_country, - // then language only - String charset = map.getProperty(locale.toString()); - if (charset == null) { - charset = map.getProperty(locale.getLanguage() + "_" - + locale.getCountry()); - if (charset == null) { - charset = map.getProperty(locale.getLanguage()); - } - } - return (charset); - } - - - /** - * The deployment descriptor can have a - * locale-encoding-mapping-list element which describes the - * webapp's desired mapping from locale to charset. This method - * gets called when processing the web.xml file for a context - * - * @param locale The locale for a character set - * @param charset The charset to be associated with the locale - */ - public void addCharsetMapping(String locale, String charset) { - if (map == defaultMap) { - // new copy, don't modify original - map = new Properties(defaultMap); - } - map.put(locale, charset); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/RequestDispatcherImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/RequestDispatcherImpl.java deleted file mode 100644 index 91d37b766..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/RequestDispatcherImpl.java +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.ServletResponse; -import javax.servlet.ServletResponseWrapper; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tomcat.lite.http.MappingData; -import org.apache.tomcat.lite.io.CBuffer; - - -/** - * - */ -public final class RequestDispatcherImpl implements RequestDispatcher { - /** - * 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 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 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 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"; - - - // ----------------------------------------------------- Instance Variables - - private static Logger log = Logger.getLogger(RequestDispatcherImpl.class.getName()); - - private ServletContextImpl ctx = null; - - /** - * The servlet name for a named dispatcher. - */ - private String name = null; - - // Path for a path dispatcher - private String path; - - /** - * MappingData object - per thread for buffering. - */ - private transient ThreadLocal localMappingData = - new ThreadLocal(); - - /* - OrigRequest(ServletRequestImpl) -> include/forward * -> this include - - On the path: user-defined RequestWrapper or our ServletRequestWrapper - - include() is called with a RequestWrapper(->...->origRequest) or origRequest - - Based on params, etc -> we wrap the req / response in ServletRequestWrapper, - call filters+servlet. Inside, the req can be wrapped again in - userReqWrapper, and other include called. - - - */ - - /** - * The outermost request that will be passed on to the invoked servlet. - */ - private ServletRequest outerRequest = null; - - /** - * The outermost response that will be passed on to the invoked servlet. - */ - private ServletResponse outerResponse = null; - - /** - * The request wrapper we have created and installed (if any). - */ - private ServletRequest wrapRequest = null; - - /** - * The response wrapper we have created and installed (if any). - */ - private ServletResponse wrapResponse = null; - - // Parameters used when constructing the dispatcvher - /** - * The extra path information for this RequestDispatcher. - */ - private String pathInfo = null; - /** - * The query string parameters for this RequestDispatcher. - */ - private String queryString = null; - /** - * The request URI for this RequestDispatcher. - */ - private String requestURI = null; - /** - * The servlet path for this RequestDispatcher. - */ - private String servletPath = null; - - // - private String origServletPath = null; - - /** - * The Wrapper associated with the resource that will be forwarded to - * or included. - */ - private ServletConfigImpl wrapper = null; - - private Servlet servlet; - - /** Named dispatcher - */ - public RequestDispatcherImpl(ServletConfigImpl wrapper, String name) { - this.wrapper = wrapper; - this.name = name; - this.ctx = (ServletContextImpl) wrapper.getServletContext(); - - } - - public RequestDispatcherImpl(ServletContextImpl ctx, String path) { - this.path = path; - this.ctx = ctx; - } - - - - /** - * Forward this request and response to another resource for processing. - * Any runtime exception, IOException, or ServletException thrown by the - * called servlet will be propogated to the caller. - * - * @param request The servlet request to be forwarded - * @param response The servlet response to be forwarded - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet exception occurs - */ - public void forward(ServletRequest request, ServletResponse response) - throws ServletException, IOException - { - // Reset any output that has been buffered, but keep headers/cookies - if (response.isCommitted()) { - throw new IllegalStateException("forward(): response.isComitted()"); - } - - try { - response.resetBuffer(); - } catch (IllegalStateException e) { - throw e; - } - - // Set up to handle the specified request and response - setup(request, response, false); - - // Identify the HTTP-specific request and response objects (if any) - HttpServletRequest hrequest = (HttpServletRequest) request; - - ServletRequestWrapperImpl wrequest = - (ServletRequestWrapperImpl) wrapRequest(); - - - if (name != null) { - wrequest.setRequestURI(hrequest.getRequestURI()); - wrequest.setContextPath(hrequest.getContextPath()); - wrequest.setServletPath(hrequest.getServletPath()); - wrequest.setPathInfo(hrequest.getPathInfo()); - wrequest.setQueryString(hrequest.getQueryString()); - - - } else { // path based - mapPath(); - if (wrapper == null) { - throw new ServletException("Forward not found " + - path); - } - String contextPath = ctx.getContextPath(); - if (hrequest.getAttribute(FORWARD_REQUEST_URI_ATTR) == null) { - wrequest.setAttribute(FORWARD_REQUEST_URI_ATTR, - hrequest.getRequestURI()); - wrequest.setAttribute(FORWARD_CONTEXT_PATH_ATTR, - hrequest.getContextPath()); - wrequest.setAttribute(FORWARD_SERVLET_PATH_ATTR, - hrequest.getServletPath()); - wrequest.setAttribute(FORWARD_PATH_INFO_ATTR, - hrequest.getPathInfo()); - wrequest.setAttribute(FORWARD_QUERY_STRING_ATTR, - hrequest.getQueryString()); - } - - wrequest.setContextPath(contextPath); - wrequest.setRequestURI(requestURI); - wrequest.setServletPath(servletPath); - wrequest.setPathInfo(pathInfo); - if (queryString != null) { - wrequest.setQueryString(queryString); - wrequest.setQueryParams(queryString); - } - } - processRequest(outerRequest, outerResponse); - - wrequest.recycle(); - unwrapRequest(); - - // This is not a real close in order to support error processing -// if ( log.isDebugEnabled() ) -// log.debug(" Disabling the response for futher output"); - - if (response instanceof ServletResponseImpl) { - ((ServletResponseImpl) response).flushBuffer(); - ((ServletResponseImpl) response).setSuspended(true); - } else { - // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped - // and may no longer be instance of RequestFacade - if (log.isLoggable(Level.FINE)){ - log.fine( " The Response is vehiculed using a wrapper: " - + response.getClass().getName() ); - } - - // Close anyway - try { - PrintWriter writer = response.getWriter(); - writer.close(); - } catch (IllegalStateException e) { - try { - ServletOutputStream stream = response.getOutputStream(); - stream.close(); - } catch (IllegalStateException f) { - ; - } catch (IOException f) { - ; - } - } catch (IOException e) { - ; - } - } - } - - - - /** - * Include the response from another resource in the current response. - * Any runtime exception, IOException, or ServletException thrown by the - * called servlet will be propogated to the caller. - * - * @param request The servlet request that is including this one - * @param response The servlet response to be appended to - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet exception occurs - */ - public void include(ServletRequest request, ServletResponse response) - throws ServletException, IOException - { - - // Set up to handle the specified request and response - setup(request, response, true); - - // Create a wrapped response to use for this request - // this actually gets inserted somewhere in the chain - it's not - // the last one, but first non-user response - wrapResponse(); - ServletRequestWrapperImpl wrequest = - (ServletRequestWrapperImpl) wrapRequest(); - - - // Handle an HTTP named dispatcher include - if (name != null) { - wrequest.setAttribute(NAMED_DISPATCHER_ATTR, name); - if (servletPath != null) wrequest.setServletPath(servletPath); - wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR, - new Integer(WebappFilterMapper.INCLUDE)); - wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, - origServletPath); - } else { - mapPath(); - String contextPath = ctx.getContextPath(); - if (requestURI != null) - wrequest.setAttribute(INCLUDE_REQUEST_URI_ATTR, - requestURI); - if (contextPath != null) - wrequest.setAttribute(INCLUDE_CONTEXT_PATH_ATTR, - contextPath); - if (servletPath != null) - wrequest.setAttribute(INCLUDE_SERVLET_PATH_ATTR, - servletPath); - if (pathInfo != null) - wrequest.setAttribute(INCLUDE_PATH_INFO_ATTR, - pathInfo); - if (queryString != null) { - wrequest.setAttribute(INCLUDE_QUERY_STRING_ATTR, - queryString); - wrequest.setQueryParams(queryString); - } - - wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR, - new Integer(WebappFilterMapper.INCLUDE)); - wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, - origServletPath); - } - - invoke(outerRequest, outerResponse); - - wrequest.recycle(); - unwrapRequest(); - unwrapResponse(); - } - - - // -------------------------------------------------------- Private Methods - - public void mapPath() { - if (path == null || servletPath != null) return; - - // Retrieve the thread local URI, used for mapping - // TODO: recycle RequestDispatcher stack and associated objects - // instead of this object - - // Retrieve the thread local mapping data - MappingData mappingData = (MappingData) localMappingData.get(); - if (mappingData == null) { - mappingData = new MappingData(); - localMappingData.set(mappingData); - } - - // Get query string - int pos = path.indexOf('?'); - if (pos >= 0) { - queryString = path.substring(pos + 1); - } else { - pos = path.length(); - } - - // Map the URI - CBuffer uriMB = CBuffer.newInstance(); - //mappingData.localURIBytes; - uriMB.recycle(); - //CharChunk uriCC = uriMB.getCharChunk(); - try { - /* - * Ignore any trailing path params (separated by ';') for mapping - * purposes. - * This is sometimes broken - path params can be on any path - * component, not just last. - */ - int semicolon = path.indexOf(';'); - if (pos >= 0 && semicolon > pos) { - semicolon = -1; - } - if (ctx.getContextPath().length() > 1 ) { - uriMB.append(ctx.getContextPath()); - } - uriMB.append(path, 0, - semicolon > 0 ? semicolon : pos); - - // TODO: make charBuffer part of request or something - ctx.getEngine().getDispatcher().map(ctx.getContextMap(), uriMB, mappingData); - - // at least default wrapper must be returned - -// /* -// * Append any trailing path params (separated by ';') that were -// * ignored for mapping purposes, so that they're reflected in the -// * RequestDispatcher's requestURI -// */ -// if (semicolon > 0) { -// // I don't think this will be used in future -// charBuffer.append(path, -// semicolon, pos - semicolon); -// } - } catch (Exception e) { - log.log(Level.SEVERE, "getRequestDispatcher()", e); - } - - wrapper = (ServletConfigImpl) mappingData.getServiceObject(); - servletPath = mappingData.wrapperPath.toString(); - pathInfo = mappingData.pathInfo.toString(); - - mappingData.recycle(); - - } - - - /** - * Prepare the request based on the filter configuration. - * @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 error occurs - */ - private void processRequest(ServletRequest request, - ServletResponse response) - throws IOException, ServletException { - Integer disInt = - (Integer) request.getAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR); - if (disInt != null) { - if (disInt.intValue() != WebappFilterMapper.ERROR) { - outerRequest.setAttribute - (WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, - origServletPath); - outerRequest.setAttribute - (WebappFilterMapper.DISPATCHER_TYPE_ATTR, - new Integer(WebappFilterMapper.FORWARD)); - } - invoke(outerRequest, response); - } - - } - - - - - /** - * Ask the resource represented by this RequestDispatcher to process - * the associated request, and create (or append to) the associated - * response. - *

- * IMPLEMENTATION NOTE: This implementation assumes - * that no filters are applied to a forwarded or included resource, - * because they were already done for the original request. - * - * @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 error occurs - */ - private void invoke(ServletRequest request, ServletResponse response) - throws IOException, ServletException { - - // Checking to see if the context classloader is the current context - // classloader. If it's not, we're saving it, and setting the context - // classloader to the Context classloader - ClassLoader oldCCL = Thread.currentThread().getContextClassLoader(); - ClassLoader contextClassLoader = ctx.getClassLoader(); - - if (oldCCL != contextClassLoader) { - Thread.currentThread().setContextClassLoader(contextClassLoader); - } else { - oldCCL = null; - } - - // Initialize local variables we may need - HttpServletResponse hresponse = (HttpServletResponse) response; - IOException ioException = null; - ServletException servletException = null; - RuntimeException runtimeException = null; - - servletException = allocateServlet(hresponse, servletException); - - // Get the FilterChain Here - WebappFilterMapper factory = - ((ServletContextImpl)wrapper.getServletContext()).getFilterMapper(); - - FilterChainImpl filterChain = factory.createFilterChain(request, - wrapper, - servlet); - - // Call the service() method for the allocated servlet instance - try { - String jspFile = wrapper.getJspFile(); - if (jspFile != null) - request.setAttribute(JSP_FILE_ATTR, jspFile); - else - request.removeAttribute(JSP_FILE_ATTR); - // for includes/forwards - if ((servlet != null) && (filterChain != null)) { - filterChain.doFilter(request, response); - } - } catch (IOException e) { - ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + - wrapper.getServletName(), e); - ioException = e; - } catch (UnavailableException e) { - ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + - wrapper.getServletName(), e); - servletException = e; - wrapper.unavailable(e); - } catch (ServletException e) { - servletException = e; - } catch (RuntimeException e) { - ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + - wrapper.getServletName(), e); - runtimeException = e; - } - request.removeAttribute(JSP_FILE_ATTR); - - // Release the filter chain (if any) for this request - if (filterChain != null) - filterChain.release(); - - servletException = servletDealocate(servletException); - - // Reset the old context class loader - if (oldCCL != null) - Thread.currentThread().setContextClassLoader(oldCCL); - - // Unwrap request/response if needed - unwrapRequest(); - unwrapResponse(); - - // Rethrow an exception if one was thrown by the invoked servlet - if (ioException != null) - throw ioException; - if (servletException != null) - throw servletException; - if (runtimeException != null) - throw runtimeException; - - } - - private ServletException servletDealocate(ServletException servletException) - { - if (servlet != null) { - wrapper.deallocate(servlet); - } - return servletException; - } - - private ServletException allocateServlet(HttpServletResponse hresponse, - ServletException servletException) - throws IOException - { - boolean unavailable = false; - - // Check for the servlet being marked unavailable - if (wrapper.isUnavailable()) { - ctx.getLogger().log(Level.WARNING, "isUnavailable() " + wrapper.getServletName()); - long available = wrapper.getAvailable(); - if ((available > 0L) && (available < Long.MAX_VALUE)) - hresponse.setDateHeader("Retry-After", available); - hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, - "Unavailable"); // No need to include internal info: wrapper.getServletName(); - unavailable = true; - } - - // Allocate a servlet instance to process this request - try { - if (!unavailable) { - servlet = wrapper.allocate(); - } - } catch (ServletException e) { - ctx.getLogger().log(Level.WARNING, "RequestDispatcher: allocate " + - wrapper.toString()); - servletException = e; - servlet = null; - } catch (Throwable e) { - ctx.getLogger().log(Level.WARNING, "allocate() error " + wrapper.getServletName(), e); - servletException = new ServletException - ("Allocate error " + wrapper.getServletName(), e); - servlet = null; - } - return servletException; - } - - - /** - * Set up to handle the specified request and response - * - * @param request The servlet request specified by the caller - * @param response The servlet response specified by the caller - * @param including Are we performing an include() as opposed to - * a forward()? - */ - private void setup(ServletRequest request, ServletResponse response, - boolean including) { - - this.outerRequest = request; - this.outerResponse = response; - } - - - /** - * Unwrap the request if we have wrapped it. Not sure how it could end - * up in the middle. - */ - private void unwrapRequest() { - if (wrapRequest == null) - return; - - ServletRequest previous = null; - ServletRequest current = outerRequest; - while (current != null) { - // If we run into the container request we are done - if (current instanceof ServletRequestImpl) - break; - - // Remove the current request if it is our wrapper - if (current == wrapRequest) { - ServletRequest next = - ((ServletRequestWrapper) current).getRequest(); - if (previous == null) - outerRequest = next; - else - ((ServletRequestWrapper) previous).setRequest(next); - break; - } - - // Advance to the next request in the chain - previous = current; - current = ((ServletRequestWrapper) current).getRequest(); - } - } - - - /** - * Unwrap the response if we have wrapped it. - */ - private void unwrapResponse() { - if (wrapResponse == null) - return; - - ServletResponse previous = null; - ServletResponse current = outerResponse; - while (current != null) { - // If we run into the container response we are done - if (current instanceof ServletResponseImpl) - break; - - // Remove the current response if it is our wrapper - if (current == wrapResponse) { - ServletResponse next = - ((ServletResponseWrapper) current).getResponse(); - if (previous == null) - outerResponse = next; - else - ((ServletResponseWrapper) previous).setResponse(next); - break; - } - // Advance to the next response in the chain - previous = current; - current = ((ServletResponseWrapper) current).getResponse(); - } - } - - - /** - * Create and return a request wrapper that has been inserted in the - * appropriate spot in the request chain. - */ - private ServletRequest wrapRequest() { - // Locate the request we should insert in front of - ServletRequest previous = null; - ServletRequest current = outerRequest; - while (current != null) { - if (!(current instanceof ServletRequestWrapper)) - break; - if (current instanceof ServletRequestWrapperImpl) - break; - if (current instanceof ServletRequestImpl) - break; - // user-specified - previous = current; - current = ((ServletRequestWrapper) current).getRequest(); - } - // now previous will be a user-specified wrapper, - // and current one of our own wrappers ( deeper in stack ) - // ... current USER_previous USER USER - // previous is null if the top request is ours. - - // Instantiate a new wrapper at this point and insert it in the chain - ServletRequest wrapper = null; - - // Compute a crossContext flag - boolean crossContext = isCrossContext(); - wrapper = - new ServletRequestWrapperImpl((HttpServletRequest) current, - ctx, crossContext); - - if (previous == null) { - // outer becomes the wrapper, includes orig wrapper inside - outerRequest = wrapper; - } else { - // outer remains user-specified sersvlet, delegating to - // our wrapper, which delegates to real request or our wrapper. - ((ServletRequestWrapper) previous).setRequest(wrapper); - } - wrapRequest = wrapper; - return (wrapper); - } - - private boolean isCrossContext() { - boolean crossContext = false; - if ((outerRequest instanceof ServletRequestWrapperImpl) || - (outerRequest instanceof ServletRequestImpl) || - (outerRequest instanceof HttpServletRequest)) { - HttpServletRequest houterRequest = - (HttpServletRequest) outerRequest; - Object contextPath = - houterRequest.getAttribute(INCLUDE_CONTEXT_PATH_ATTR); - if (contextPath == null) { - // Forward - contextPath = houterRequest.getContextPath(); - } - crossContext = !(ctx.getContextPath().equals(contextPath)); - } - return crossContext; - } - - - /** - * Create and return a response wrapper that has been inserted in the - * appropriate spot in the response chain. - * - * Side effect: updates outerResponse, wrapResponse. - * The chain is updated with a wrapper below lowest user wrapper - */ - private ServletResponse wrapResponse() { - // Locate the response we should insert in front of - ServletResponse previous = null; - ServletResponse current = outerResponse; - while (current != null) { - if (!(current instanceof ServletResponseWrapper)) - break; - if (current instanceof ServletResponseImpl) - break; - previous = current; - current = ((ServletResponseWrapper) current).getResponse(); - } - - // Instantiate a new wrapper at this point and insert it in the chain - ServletResponse wrapper = - new ServletResponseIncludeWrapper(current); - - if (previous == null) { - // outer is ours, we can wrap on top - outerResponse = wrapper; - } else { - // outer is user-specified, leave it alone. - // we insert ourself below the lowest user-specified response - ((ServletResponseWrapper) previous).setResponse(wrapper); - } - wrapResponse = wrapper; - return (wrapper); - - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi.java deleted file mode 100644 index 2290bb6c5..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import org.apache.tomcat.lite.http.HttpRequest; - -public class ServletApi { - - public ServletContextImpl newContext() { - return null; - } - - public ServletRequestImpl newRequest(HttpRequest req) { - return null; - } - - - public static ServletApi get() { - Class cls = null; - try { - Class.forName("javax.servlet.http.Part"); - cls = Class.forName("org.apache.tomcat.lite.servlet.ServletApi30"); - } catch (Throwable t) { - try { - cls = Class.forName("org.apache.tomcat.lite.servlet.ServletApi25"); - } catch (ClassNotFoundException e) { - throw new RuntimeException("Can't load servlet api", e); - } - } - try { - return (ServletApi) cls.newInstance(); - } catch (Throwable e) { - throw new RuntimeException("Can't load servlet api", e); - } - } - -} \ No newline at end of file diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi25.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi25.java deleted file mode 100644 index 1e2fe5334..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi25.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import org.apache.tomcat.lite.http.HttpRequest; - -public class ServletApi25 extends ServletApi { - public ServletContextImpl newContext() { - return new ServletContextImpl() { - - }; - } - - public ServletRequestImpl newRequest(HttpRequest req) { - return new ServletRequestImpl(req) { - - }; - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java deleted file mode 100644 index d641cb66b..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletApi30.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.naming.NamingException; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.descriptor.JspConfigDescriptor; -import javax.servlet.http.Part; - -import org.apache.tomcat.InstanceManager; -import org.apache.tomcat.integration.ObjectManager; -import org.apache.tomcat.lite.http.HttpRequest; - -public class ServletApi30 extends ServletApi { - public ServletContextImpl newContext() { - return new Servlet30ContextImpl(); - } - - public ServletRequestImpl newRequest(HttpRequest req) { - return new ServletRequestImpl(req) { - - public Part getPart(String name) { - return null; - } - - public Collection getParts() throws IOException, - ServletException { - return null; - } - - public AsyncContext getAsyncContext() { - return null; - } - - public DispatcherType getDispatcherType() { - return null; - } - - public AsyncContext startAsync() { - return null; - } - - public AsyncContext startAsync(ServletRequest servletRequest, - ServletResponse servletResponse) { - return null; - } - - }; - } - - public final class Servlet30ContextImpl extends ServletContextImpl { - protected void initEngineDefaults() throws ServletException { - super.initEngineDefaults(); - setAttribute(InstanceManager.class.getName(), - new LiteInstanceManager(getObjectManager())); - } - - public Dynamic addFilter(String filterName, String className) { - FilterConfigImpl fc = new FilterConfigImpl(this); - fc.setData(filterName, null, new HashMap()); - fc.setData(filterName, className, new HashMap()); - filters.put(filterName, fc); - return new DynamicFilterRegistration(fc); - } - - public Dynamic addFilter(String filterName, Filter filter) { - FilterConfigImpl fc = new FilterConfigImpl(this); - fc.setData(filterName, null, new HashMap()); - fc.setFilter(filter); - filters.put(filterName, fc); - return new DynamicFilterRegistration(fc); - } - - public Dynamic addFilter(String filterName, - Class filterClass) { - FilterConfigImpl fc = new FilterConfigImpl(this); - fc.setData(filterName, null, new HashMap()); - fc.setFilterClass(filterClass); - filters.put(filterName, fc); - return new DynamicFilterRegistration(fc); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet( - String servletName, String className) { - return null; - } - - public javax.servlet.ServletRegistration.Dynamic addServlet( - String servletName, Servlet servlet) { - return null; - } - - public javax.servlet.ServletRegistration.Dynamic addServlet( - String servletName, Class servletClass) { - return null; - } - - public Set getDefaultSessionTrackingModes() { - return null; - } - - public Set getEffectiveSessionTrackingModes() { - return null; - } - - public FilterRegistration getFilterRegistration(String filterName) { - return null; - } - - public Map getFilterRegistrations() { - return null; - } - - public JspConfigDescriptor getJspConfigDescriptor() { - return null; - } - - public ServletRegistration getServletRegistration(String servletName) { - return null; - } - - public Map getServletRegistrations() { - return null; - } - - public SessionCookieConfig getSessionCookieConfig() { - return null; - } - - public int getMajorVersion() { - return 3; - } - - public int getMinorVersion() { - return 0; - } - - public void setSessionTrackingModes( - Set sessionTrackingModes) - throws IllegalStateException, IllegalArgumentException { - } - } - - private final class LiteInstanceManager implements InstanceManager { - private ObjectManager om; - - public LiteInstanceManager(ObjectManager objectManager) { - this.om = objectManager; - } - - @Override - public void destroyInstance(Object o) - throws IllegalAccessException, - InvocationTargetException { - } - - @Override - public Object newInstance(String className) - throws IllegalAccessException, - InvocationTargetException, NamingException, - InstantiationException, - ClassNotFoundException { - return om.get(className); - } - - @Override - public Object newInstance(String fqcn, - ClassLoader classLoader) - throws IllegalAccessException, - InvocationTargetException, NamingException, - InstantiationException, - ClassNotFoundException { - return om.get(fqcn); - } - - @Override - public void newInstance(Object o) - throws IllegalAccessException, - InvocationTargetException, NamingException { - om.bind(o.getClass().getName(), o); - } - } - - public static class DynamicFilterRegistration implements Dynamic { - FilterConfigImpl fcfg; - - public DynamicFilterRegistration( - org.apache.tomcat.lite.servlet.FilterConfigImpl fc) { - } - - @Override - public void addMappingForServletNames(EnumSet dispatcherTypes, - boolean isMatchAfter, - String... servletNames) { - if (fcfg.ctx.startDone) { - // Use the context method instead of the servlet API to - // add mappings after context init. - throw new IllegalStateException(); - } - ArrayList dispatchers = new ArrayList(); - for (DispatcherType dt: dispatcherTypes) { - dispatchers.add(dt.name()); - } - for (String servletName: servletNames) { - fcfg.ctx.getFilterMapper().addMapping(fcfg.getFilterName(), - null, servletName, (String[]) dispatchers.toArray(), isMatchAfter); - } - } - - @Override - public void addMappingForUrlPatterns(EnumSet dispatcherTypes, - boolean isMatchAfter, - String... urlPatterns) { - if (fcfg.ctx.startDone) { - // Use the context method instead of the servlet API to - // add mappings after context init. - throw new IllegalStateException(); - } - ArrayList dispatchers = new ArrayList(); - for (DispatcherType dt: dispatcherTypes) { - dispatchers.add(dt.name()); - } - for (String url: urlPatterns) { - fcfg.ctx.getFilterMapper().addMapping(fcfg.getFilterName(), - url, null, (String[]) dispatchers.toArray(), isMatchAfter); - } - } - - @Override - public boolean setInitParameter(String name, String value) - throws IllegalArgumentException, IllegalStateException { - return fcfg.ctx.setInitParameter(fcfg.ctx, fcfg.initParams, - name, value); - } - - @Override - public Set setInitParameters(Map initParameters) - throws IllegalArgumentException, IllegalStateException { - return ServletContextImpl.setInitParameters(fcfg.ctx, fcfg.initParams, - initParameters); - } - - @Override - public void setAsyncSupported(boolean isAsyncSupported) - throws IllegalStateException { - fcfg.asyncSupported = isAsyncSupported; - } - - @Override - public Collection getServletNameMappings() { - return null; - } - - @Override - public Collection getUrlPatternMappings() { - return null; - } - - @Override - public String getClassName() { - return null; - } - - @Override - public String getInitParameter(String name) { - return null; - } - - @Override - public Map getInitParameters() { - return null; - } - - @Override - public String getName() { - return null; - } - } - - class ServletDynamicRegistration implements Dynamic { - ServletConfigImpl sc; - - @Override - public void setAsyncSupported(boolean isAsyncSupported) - throws IllegalStateException { - sc.asyncSupported = isAsyncSupported; - } - - @Override - public boolean setInitParameter(String name, String value) - throws IllegalArgumentException, IllegalStateException { - return sc.setInitParameter(name, value); - } - - @Override - public Set setInitParameters(Map initParameters) - throws IllegalArgumentException, IllegalStateException { - return setInitParameters(initParameters); - } - - @Override - public void addMappingForServletNames( - EnumSet dispatcherTypes, boolean isMatchAfter, - String... servletNames) { - } - - @Override - public void addMappingForUrlPatterns( - EnumSet dispatcherTypes, boolean isMatchAfter, - String... urlPatterns) { - } - - @Override - public Collection getServletNameMappings() { - return null; - } - - @Override - public Collection getUrlPatternMappings() { - return null; - } - - @Override - public String getClassName() { - return null; - } - - @Override - public String getInitParameter(String name) { - return null; - } - - @Override - public Map getInitParameters() { - return null; - } - - @Override - public String getName() { - return null; - } - - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletConfigImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletConfigImpl.java deleted file mode 100644 index 235d1e1d2..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletConfigImpl.java +++ /dev/null @@ -1,880 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.Method; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.SingleThreadModel; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tomcat.integration.jmx.JMXProxyServlet; -import org.apache.tomcat.lite.http.HttpChannel; -import org.apache.tomcat.lite.http.HttpRequest; -import org.apache.tomcat.lite.http.HttpResponse; -import org.apache.tomcat.lite.http.MappingData; -import org.apache.tomcat.lite.io.WrappedException; -import org.apache.tomcat.servlets.jsp.BaseJspLoader; -import org.apache.tomcat.servlets.util.Enumerator; - -/** - * Based on Wrapper. - * - * Standard implementation of the Wrapper interface that represents - * an individual servlet definition. No child Containers are allowed, and - * the parent Container must be a Context. - * - * @author Craig R. McClanahan - * @author Remy Maucherat - */ -@SuppressWarnings("deprecation") -public class ServletConfigImpl implements ServletConfig, HttpChannel.HttpService { - - protected boolean asyncSupported; - - private static Logger log= - Logger.getLogger(ServletConfigImpl.class.getName()); - - private static final String[] DEFAULT_SERVLET_METHODS = new String[] { - "GET", "HEAD", "POST" }; - - // TODO: refactor all 'stm' to separate class (not implemented) - // public static final String SINGLE_THREADED_PROXY = - // "org.apache.tomcat.servlets.jsp.SingleThreadedProxyServlet"; - - protected String description; - protected Map initParams = new HashMap(); - protected String servletName; - protected String servletClassName; - protected String jspFile; - protected int loadOnStartup = -1; - protected String runAs; - - protected Map securityRoleRef = new HashMap(); // roleName -> [roleLink] - - /** - * The date and time at which this servlet will become available (in - * milliseconds since the epoch), or zero if the servlet is available. - * If this value equals Long.MAX_VALUE, the unavailability of this - * servlet is considered permanent. - */ - private transient long available = 0L; - - private ServletContextImpl ctx; - - /** - * The (single) initialized instance of this servlet. - */ - private transient Servlet instance = null; - - /** - * Are we unloading our servlet instance at the moment? - */ - private transient boolean unloading = false; - - private Class servletClass = null; - - // Support for SingleThreaded - /** - * The count of allocations that are currently active (even if they - * are for the same instance, as will be true on a non-STM servlet). - */ - private transient int countAllocated = 0; - - private transient boolean singleThreadModel = false; - /** - * Stack containing the STM instances. - */ - private transient Stack instancePool = null; - - - // Statistics - private transient long loadTime=0; - private transient int classLoadTime=0; - - public AtomicLong processingTime = new AtomicLong(); - public AtomicInteger maxTime = new AtomicInteger(); - public AtomicInteger requestCount = new AtomicInteger(); - public AtomicInteger errorCount = new AtomicInteger(); - - // ------------------------------------------------------------- Properties - public ServletConfigImpl(ServletContextImpl ctx, String name, - String classname) { - this.servletName = name; - this.servletClassName = classname; - this.ctx = ctx; - ctx.lite.notifyAdd(this); - } - - public ServletConfigImpl(Servlet realServlet) throws IOException { - instance = realServlet; - try { - realServlet.init(this); - } catch (ServletException e) { - throw new WrappedException(e); - } - } - - /** - * Return the available date/time for this servlet, in milliseconds since - * the epoch. If this date/time is Long.MAX_VALUE, it is considered to mean - * that unavailability is permanent and any request for this servlet will return - * an SC_NOT_FOUND error. If this date/time is in the future, any request for - * this servlet will return an SC_SERVICE_UNAVAILABLE error. If it is zero, - * the servlet is currently available. - */ - public long getAvailable() { - return (this.available); - } - - /** - * Set the available date/time for this servlet, in milliseconds since the - * epoch. If this date/time is Long.MAX_VALUE, it is considered to mean - * that unavailability is permanent and any request for this servlet will return - * an SC_NOT_FOUND error. If this date/time is in the future, any request for - * this servlet will return an SC_SERVICE_UNAVAILABLE error. - * - * @param available The new available date/time - */ - public void setAvailable(long available) { - - long oldAvailable = this.available; - if (available > System.currentTimeMillis()) - this.available = available; - else - this.available = 0L; - - } - - - /** - * Return the number of active allocations of this servlet, even if they - * are all for the same instance (as will be true for servlets that do - * not implement SingleThreadModel. - */ - public int getCountAllocated() { - return (this.countAllocated); - } - - /** - * Return the jsp-file setting for this servlet. - */ - public String getJspFile() { - return jspFile; - } - - public void setJspFile(String s) { - this.jspFile = s; - } - - /** - * Return the load-on-startup order value (negative value means - * load on first call). - */ - public int getLoadOnStartup() { - return loadOnStartup; - } - - /** - * Return the fully qualified servlet class name for this servlet. - */ - public String getServletClass() { - return servletClassName; - } - - /** - * Is this servlet currently unavailable? - */ - public boolean isUnavailable() { - if (available == 0L) - return (false); - else if (available <= System.currentTimeMillis()) { - available = 0L; - return (false); - } else - return (true); - - } - - - /** - * Gets the names of the methods supported by the underlying servlet. - * - * This is the same set of methods included in the Allow response header - * in response to an OPTIONS request method processed by the underlying - * servlet. - * - * @return Array of names of the methods supported by the underlying - * servlet - * @throws IOException - */ - public String[] getServletMethods() throws ServletException, IOException { - - Class servletClazz = loadServlet().getClass(); - if (!javax.servlet.http.HttpServlet.class.isAssignableFrom( - servletClazz)) { - return DEFAULT_SERVLET_METHODS; - } - - HashSet allow = new HashSet(); - allow.add("TRACE"); - allow.add("OPTIONS"); - - Method[] methods = getAllDeclaredMethods(servletClazz); - for (int i=0; methods != null && inull - * to mark this servlet as permanently unavailable - */ - public void unavailable(UnavailableException unavailable) { - getServletContext().log("UnavailableException:" + getServletName()); - if (unavailable == null) - setAvailable(Long.MAX_VALUE); - else if (unavailable.isPermanent()) - setAvailable(Long.MAX_VALUE); - else { - int unavailableSeconds = unavailable.getUnavailableSeconds(); - if (unavailableSeconds <= 0) - unavailableSeconds = 60; // Arbitrary default - setAvailable(System.currentTimeMillis() + - (unavailableSeconds * 1000L)); - } - - } - - - /** - * Unload all initialized instances of this servlet, after calling the - * destroy() method for each instance. This can be used, - * for example, prior to shutting down the entire servlet engine, or - * prior to reloading all of the classes from the Loader associated with - * our Loader's repository. - * - * @exception ServletException if an exception is thrown by the - * destroy() method - */ - public synchronized void unload() throws ServletException { - setAvailable(Long.MAX_VALUE); - - // Nothing to do if we have never loaded the instance - if (!singleThreadModel && (instance == null)) - return; - unloading = true; - - // Loaf a while if the current instance is allocated - // (possibly more than once if non-STM) - if (countAllocated > 0) { - int nRetries = 0; - long delay = ctx.getUnloadDelay() / 20; - while ((nRetries < 21) && (countAllocated > 0)) { - if ((nRetries % 10) == 0) { - log.info("Servlet.unload() timeout " + - countAllocated); - } - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - ; - } - nRetries++; - } - } - - ClassLoader oldCtxClassLoader = - Thread.currentThread().getContextClassLoader(); - if (instance != null) { - ClassLoader classLoader = instance.getClass().getClassLoader(); - - PrintStream out = System.out; - // Call the servlet destroy() method - try { - Thread.currentThread().setContextClassLoader(classLoader); - instance.destroy(); - } catch (Throwable t) { - instance = null; - //instancePool = null; - unloading = false; - throw new ServletException("Servlet.destroy() " + - getServletName(), t); - } finally { - // restore the context ClassLoader - Thread.currentThread().setContextClassLoader(oldCtxClassLoader); - } - - // Deregister the destroyed instance - instance = null; - } - if (singleThreadModel && (instancePool != null)) { - try { - ClassLoader classLoader = ctx.getClassLoader(); - Thread.currentThread().setContextClassLoader(classLoader); - while (!instancePool.isEmpty()) { - ((Servlet) instancePool.pop()).destroy(); - } - } catch (Throwable t) { - instancePool = null; - unloading = false; - throw new ServletException("Servlet.destroy() " + getServletName(), t); - } finally { - // restore the context ClassLoader - Thread.currentThread().setContextClassLoader - (oldCtxClassLoader); - } - instancePool = null; - } - - singleThreadModel = false; - - unloading = false; - } - - - /** - * Return the initialization parameter value for the specified name, - * if any; otherwise return null. - * - * @param name Name of the initialization parameter to retrieve - */ - public String getInitParameter(String name) { - return initParams.get(name); - } - - - /** - * Return the set of initialization parameter names defined for this - * servlet. If none are defined, an empty Enumeration is returned. - */ - public Enumeration getInitParameterNames() { - synchronized (initParams) { - return (new Enumerator(initParams.keySet())); - } - } - - - /** - * Return the servlet context with which this servlet is associated. - */ - public ServletContext getServletContext() { - return ctx; - } - - - /** - * Return the name of this servlet. - */ - public String getServletName() { - return servletName; - } - - private Method[] getAllDeclaredMethods(Class c) { - - if (c.equals(javax.servlet.http.HttpServlet.class)) { - return null; - } - - Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass()); - - Method[] thisMethods = c.getDeclaredMethods(); - if (thisMethods == null) { - return parentMethods; - } - - if ((parentMethods != null) && (parentMethods.length > 0)) { - Method[] allMethods = - new Method[parentMethods.length + thisMethods.length]; - System.arraycopy(parentMethods, 0, allMethods, 0, - parentMethods.length); - System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, - thisMethods.length); - - thisMethods = allMethods; - } - - return thisMethods; - } - - /** Specify the instance. Avoids the class lookup, disables unloading. - * Use for embedded case, or to control the allocation. - * - * @param servlet - */ - public void setServlet(Servlet servlet) { - instance = servlet; - ctx.getObjectManager().bind("Servlet:" + - ctx.getContextPath() + ":" + getServletName(), - this); - } - - public String getSecurityRoleRef(String role) { - return (String)securityRoleRef.get(role); - } - - public void setSecurityRoleRef(Map securityRoles) { - this.securityRoleRef = securityRoles; - } - - public void setConfig(Map initParams) { - this.initParams = initParams; - } - - public void setLoadOnStartup(int loadOnStartup) { - this.loadOnStartup = loadOnStartup; - } - - public Set addMapping(String... urlPatterns) { - if (ctx.startDone) { - // Use the context method instead of the servlet API to - // add mappings after context init. - throw new IllegalStateException(); - } - Set failed = new HashSet(); - for (String url: urlPatterns) { - if (url == null) { - throw new IllegalArgumentException(); - } - if (ctx.contextConfig.servletMapping.get(url) != null) { - failed.add(url); - } else { - ctx.contextConfig.servletMapping.put(url, getServletName()); - ctx.addMapping(url, this); - } - } - return failed; - } - - public boolean setInitParameter(String name, String value) - throws IllegalArgumentException, IllegalStateException { - return ServletContextImpl.setInitParameter(ctx, initParams, - name, value); - } - - public Set setInitParameters(Map initParameters) - throws IllegalArgumentException, IllegalStateException { - return ServletContextImpl.setInitParameters(ctx, initParams, - initParameters); - } - - public void setServletClass(Class servletClass2) { - servletClass = servletClass2; - } - - @Override - public void service(HttpRequest httpReq, HttpResponse httpRes) - throws IOException { - - HttpChannel client = httpReq.getHttpChannel(); - ServletRequestImpl req = TomcatLite.getFacade(client.getRequest()); - ServletResponseImpl res = req.getResponse(); - - // TODO - try { - instance.service(req, res); - } catch (ServletException e) { - throw new WrappedException(e); - } - } - - /** 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. - * @param mapRes - */ - void serviceServlet(ServletContextImpl ctx, - ServletRequestImpl req, - ServletResponseImpl res, - ServletConfigImpl servletConfig, - MappingData mapRes) - throws IOException { - - requestCount.incrementAndGet(); - Servlet servlet = null; - long t0 = System.currentTimeMillis(); - - try { - if (servletConfig.isUnavailable()) { - handleUnavailable(res, servletConfig); - return; - } - try { - servlet = servletConfig.allocate(); - } catch(ServletException ex) { - handleUnavailable(res, servletConfig); - return; - } - WebappFilterMapper filterMap = ctx.getFilterMapper(); - FilterChainImpl chain = - filterMap.createFilterChain(req, servletConfig, servlet); - - try { - if (chain == null) { - if (servlet != null) { - servlet.service(req, res); - } else { - System.err.println("No servlet " + req.getRequestURI()); - res.sendError(404); - } - } else { - chain.doFilter(req, res); - } - } catch(UnavailableException ex) { - servletConfig.unavailable(ex); - handleUnavailable(res, servletConfig); - return; - } - - // servlet completed without exception. Check status - int status = res.getStatus(); - if (status != 200 && !res.isCommitted()) { - String statusPage = ctx.findStatusPage(status); - - if (statusPage != null) { - ctx.handleStatusPage(req, res, status, statusPage); - } else { - // Send a default message body. - // TODO: maybe other mechanism to customize default. - res.defaultStatusPage(status, res.getMessage()); - } - } - - } catch (Throwable t) { - errorCount.incrementAndGet(); - ctx.handleError(req, res, t); - } finally { - int time = (int) (System.currentTimeMillis() - t0); - if (time > maxTime.get()) { - maxTime.set(time); - } - processingTime.addAndGet(time); - if (servlet != null) { // single-thread servlet - servletConfig.deallocate(servlet); - } - } - } - - private void handleUnavailable(ServletResponseImpl response, - ServletConfigImpl servletConfig) - throws IOException { - long available = servletConfig.getAvailable(); - if ((available > 0L) && (available < Long.MAX_VALUE)) - response.setDateHeader("Retry-After", available); - // TODO: handle via error pages ! - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, - "Service unavailable"); - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java deleted file mode 100644 index b68c5e247..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletContextImpl.java +++ /dev/null @@ -1,1563 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.Filter; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextAttributeEvent; -import javax.servlet.ServletContextAttributeListener; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletException; - -import org.apache.tomcat.integration.ObjectManager; -import org.apache.tomcat.lite.http.BaseMapper; -import org.apache.tomcat.lite.io.FileConnectorJavaIo; -import org.apache.tomcat.lite.util.MimeMap; -import org.apache.tomcat.lite.util.UrlUtils; -import org.apache.tomcat.servlets.config.ConfigLoader; -import org.apache.tomcat.servlets.config.ServletContextConfig; -import org.apache.tomcat.servlets.config.ServletContextConfig.FilterData; -import org.apache.tomcat.servlets.config.ServletContextConfig.FilterMappingData; -import org.apache.tomcat.servlets.config.ServletContextConfig.ServletData; -import org.apache.tomcat.servlets.session.UserSessionManager; -import org.apache.tomcat.servlets.util.Enumerator; -import org.apache.tomcat.servlets.util.RequestUtil; - - -/** - * Context - initialized from web.xml or using APIs. - * - * Initialization order: - * - * - add all listeners - * - add all filters - * - add all servlets - * - * - session parameters - * - - * - * @author Craig R. McClanahan - * @author Remy Maucherat - * @version $Id$ - */ - -public abstract class ServletContextImpl implements ServletContext { - - /** - * Empty collection to serve as the basis for empty enumerations. - */ - private static final ArrayList empty = new ArrayList(); - - private Logger log; - - /** - * Base path - the directory root of the webapp - */ - protected String basePath = null; - - protected String contextPath; - - // All config from web.xml and other sources - protected ServletContextConfig contextConfig = null; - - // Includes the default values, will be merged with contextConfig - MimeMap contentTypes = new MimeMap(); - - /** - * The context attributes for this context. - */ - protected transient Map attributes = new HashMap(); - - protected transient ArrayList lifecycleListeners = - new ArrayList(); - - protected UserSessionManager manager; - - HashMap filters = new HashMap(); - - HashMap servlets = new HashMap(); - - /** Mapper for filters. - */ - protected WebappFilterMapper webappFilterMapper; - - /** Internal mapper for request dispatcher, must have all - * context mappings. - */ - protected BaseMapper.ContextMapping mapper; - - // From localeEncodingMapping - Locale2Charset charsetMapper = new Locale2Charset(); - - TomcatLite lite; - - // Can use a separate injection config and framework - ObjectManager om; - - private String hostname; - - boolean initDone = false; - - boolean startDone = false; - - String defaultServlet = "org.apache.tomcat.servlets.file.WebdavServlet"; - String jspWildcardServlet = "org.apache.tomcat.servlets.jsp.WildcardTemplateServlet"; - String userSessionManager = "org.apache.tomcat.servlets.session.SimpleSessionManager"; - String jspcServlet = "org.apache.tomcat.servlets.jspc.JspcServlet"; - - // ------------------------------------------------- ServletContext Methods - public ServletContextImpl() { - } - - public void setTomcat(TomcatLite facade) { - this.lite = facade; - } - - /** - * Registry/framework interface associated with the context. - * Also available as a context attribute. - * @return - */ - public ObjectManager getObjectManager() { - if (om == null) { - om = lite.getObjectManager(); - } - return om; - } - - public void setObjectManager(ObjectManager om) { - this.om = om; - } - - public Locale2Charset getCharsetMapper() { - return charsetMapper; - } - - /** - * Set the context path, starting with "/" - "/" for ROOT - * @param path - */ - public void setContextPath(String path) { - this.contextPath = path; - log = Logger.getLogger("webapp" + path.replace('/', '.')); - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public String getHostname() { - return hostname; - } - - /** The directory where this app is based. May be null. - * - * @param basePath - */ - public void setBasePath(String basePath) { - this.basePath = basePath; - } - - public ServletContextConfig getContextConfig() { - return contextConfig; - } - - /** The directory where this app is based. - * - * @param basePath - */ - public String getBasePath() { - return basePath; - } - - public String getEncodedPath() { - return null; - } - - - public boolean getCookies() { - return false; - } - - - public ServletContext getServletContext() { - return this; - } - - public List getListeners() { - return lifecycleListeners; - } - - public void addListener(T listener) { - lifecycleListeners.add(listener); - } - - public void removeListener(EventListener listener) { - lifecycleListeners.remove(listener); - } - - public void addListener(Class listenerClass) { - } - - public void addListener(String className) { - } - - public T createListener(Class c) - throws ServletException { - return null; - } - - - public void declareRoles(String... roleNames) { - } - - public int getEffectiveMajorVersion() { - return 0; - } - - public int getEffectiveMinorVersion() { - return 0; - } - - - public Logger getLogger() { - return log; - } - - public long getUnloadDelay() { - return 0; - } - - public ServletConfigImpl getServletConfig(String jsp_servlet_name) { - return (ServletConfigImpl)servlets.get(jsp_servlet_name); - } - - public Map getServletConfigs() { - return servlets; - } - - /** - * Add a servlet to the context. - * Called from processWebAppData() - * - * @param servletConfig - */ - public void addServletConfig(ServletConfigImpl servletConfig) { - servlets.put(servletConfig.getServletName(), servletConfig); - } - - public boolean getPrivileged() { - return false; - } - - - public Map getFilters() { - return filters; - } - - - protected boolean getCrossContext() { - return true; - } - - public void addMimeType(String ext, String type) { - contentTypes.addContentType(ext, type); - } - - public WebappFilterMapper getFilterMapper() { - if (webappFilterMapper == null) { - Object customMapper = getObjectManager().get(WebappFilterMapper.class); - if (customMapper == null) { - webappFilterMapper = new WebappFilterMapper(); - } else { - webappFilterMapper = (WebappFilterMapper) customMapper; - } - webappFilterMapper.setServletContext(this); - } - - return webappFilterMapper ; - } - - public FilterConfigImpl getFilter(String name) { - return (FilterConfigImpl)filters.get(name); - } - - /** - * Return the value of the specified context attribute, if any; - * otherwise return null. - * - * @param name Name of the context attribute to return - */ - public Object getAttribute(String name) { - if ("ObjectManager".equals(name)) { - return getObjectManager(); - } - if ("context-listeners".equals(name)) { - return lifecycleListeners; - } - return (attributes.get(name)); - } - - /** - * Return an enumeration of the names of the context attributes - * associated with this context. - */ - public Enumeration getAttributeNames() { - return new Enumerator(attributes.keySet(), true); - } - - /** - * Return a ServletContext object that corresponds to a - * specified URI on the server. This method allows servlets to gain - * access to the context for various parts of the server, and as needed - * obtain RequestDispatcher objects or resources from the - * context. The given path must be absolute (beginning with a "/"), - * and is interpreted based on our virtual host's document root. - * - * @param uri Absolute URI of a resource on the server - */ - public ServletContext getContext(String uri) { - // TODO: support real uri ( http://host/path ) - // Validate the format of the specified argument - if ((uri == null) || (!uri.startsWith("/"))) - return (null); - - ServletContextImpl child = null; - try { - child = lite.getContext(this, uri); - } catch (IOException e) { - } catch (ServletException e) { - } - - if (child == null) - return (null); - - if (this.getCrossContext()) { - // If crossContext is enabled, can always return the context - return child.getServletContext(); - } else if (child == this) { - // Can still return the current context - return this.getServletContext(); - } else { - // Nothing to return - return (null); - } - } - - - /** - * Return the main path associated with this context. - */ - public String getContextPath() { - return contextPath; - } - - - /** - * Return the value of the specified initialization parameter, or - * null if this parameter does not exist. - * - * @param name Name of the initialization parameter to retrieve - */ - public String getInitParameter(final String name) { - return ((String) contextConfig.contextParam.get(name)); - } - - - /** - * Return the names of the context's initialization parameters, or an - * empty enumeration if the context has no initialization parameters. - */ - public Enumeration getInitParameterNames() { - return (new Enumerator(contextConfig.contextParam.keySet())); - } - - public void setContextParams(Map newParams) { - contextConfig.contextParam = (HashMap) newParams; - } - - /** - * Return the major version of the Java Servlet API that we implement. - */ - public int getMajorVersion() { - return 2; - } - - - /** - * Return the minor version of the Java Servlet API that we implement. - */ - public int getMinorVersion() { - return 5; - } - - - /** - * Return the MIME type of the specified file, or null if - * the MIME type cannot be determined. - * - * @param file Filename for which to identify a MIME type - */ - public String getMimeType(String file) { - return contentTypes.getMimeType(file); - } - - /** - * Return the real path for a given virtual path, if possible; otherwise - * return null. - * - * @param path The path to the desired resource - */ - public String getRealPath(String path) { - if (path == null) { - return null; - } - - File file = new File(basePath, path); - return (file.getAbsolutePath()); - } - - /** - * Return a RequestDispatcher object that acts as a - * wrapper for the named servlet. - * - * @param name Name of the servlet for which a dispatcher is requested - */ - public RequestDispatcher getNamedDispatcher(String name) { - if (name == null) return null; - ServletConfigImpl wrapper = - (ServletConfigImpl) this.getServletConfig(name); - if (wrapper == null) return null; - - return new RequestDispatcherImpl(wrapper, name); - } - - - /** - * Return a RequestDispatcher instance that acts as a - * wrapper for the resource at the given path. The path must begin - * with a "/" and is interpreted as relative to the current context root. - * - * @param path The path to the desired resource. - */ - public RequestDispatcher getRequestDispatcher(String path) { - if (path == null) return null; - - if (!path.startsWith("/")) - throw new IllegalArgumentException(path); - - path = UrlUtils.normalize(path); - if (path == null) return (null); - - - return new RequestDispatcherImpl(this, path); - } - - public RequestDispatcher getRequestDispatcher(String path, - int type, - String dispatcherPath) { - RequestDispatcher dispatcher = getRequestDispatcher(path); - //((RequestDispatcherImpl)dispatcher); - return dispatcher; - } - - ThreadLocal requestDispatcherStack = new ThreadLocal(); - - protected ClassLoader classLoader; - - private String classPath; - - -// protected RequestDispatcherImpl getRequestDispatcher() { -// ArrayList/**/ list = -// (ArrayList)requestDispatcherStack.get(); -// if (list == null) { -// list = new ArrayList(); -// requestDispatcherStack.set(list); -// } -// -// -// return null; -// } - - public void resetDispatcherStack() { - - } - - /** - * Return the URL to the resource that is mapped to a specified path. - * The path must begin with a "/" and is interpreted as relative to the - * current context root. - * - * @param path The path to the desired resource - * - * @exception MalformedURLException if the path is not given - * in the correct form - */ - public URL getResource(String path) - throws MalformedURLException { - - if (path == null || !path.startsWith("/")) { - throw new MalformedURLException("getResource() " + path); - } - - path = UrlUtils.normalize(path); - if (path == null) - return (null); - - String libPath = "/WEB-INF/lib/"; - if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) { - File jarFile = null; - jarFile = new File(basePath, path); - if (jarFile.exists()) { - return jarFile.toURL(); - } else { - return null; - } - } else { - File resFile = new File(basePath + path); - if (resFile.exists()) { - return resFile.toURL(); - } - } - - return (null); - - } - - /** - * Return the requested resource as an InputStream. The - * path must be specified according to the rules described under - * getResource. If no such resource can be identified, - * return null. - * - * @param path The path to the desired resource. - */ - public InputStream getResourceAsStream(String path) { - - path = UrlUtils.normalize(path); - if (path == null) - return (null); - - File resFile = new File(basePath + path); - if (!resFile.exists()) - return null; - - try { - return new FileInputStream(resFile); - } catch (FileNotFoundException e) { - return null; - } - - } - - - /** - * Return a Set containing the resource paths of resources member of the - * specified collection. Each path will be a String starting with - * a "/" character. The returned set is immutable. - * - * @param path Collection path - */ - public Set getResourcePaths(String path) { - - // Validate the path argument - if (path == null) { - return null; - } - if (!path.startsWith("/")) { - throw new IllegalArgumentException("getResourcePaths() " + path); - } - - path = UrlUtils.normalize(path); - if (path == null) - return (null); - - File f = new File(basePath + path); - File[] files = f.listFiles(); - if (files == null) return null; - if (!path.endsWith("/")) { - path = path + "/"; - } - - HashSet result = new HashSet(); - for (int i=0; i < files.length; i++) { - if (files[i].isDirectory() ) { - result.add(path + files[i].getName() + "/"); - } else { - result.add(path + files[i].getName()); - } - } - return result; - } - - - - /** - * Return the name and version of the servlet container. - */ - public String getServerInfo() { - return "Apache Tomcat Lite"; - } - - /** - * @deprecated As of Java Servlet API 2.1, with no direct replacement. - */ - public Servlet getServlet(String name) { - return (null); - } - - - /** - * Return the display name of this web application. - */ - public String getServletContextName() { - return contextConfig.displayName; - } - - - /** - * @deprecated As of Java Servlet API 2.1, with no direct replacement. - */ - public Enumeration getServletNames() { - return (new Enumerator(empty)); - } - - - /** - * @deprecated As of Java Servlet API 2.1, with no direct replacement. - */ - public Enumeration getServlets() { - return (new Enumerator(empty)); - } - - - /** - * Writes the specified message to a servlet log file. - * - * @param message Message to be written - */ - public void log(String message) { - this.getLogger().info(message); - } - - - /** - * Writes the specified exception and message to a servlet log file. - * - * @param exception Exception to be reported - * @param message Message to be written - * - * @deprecated As of Java Servlet API 2.1, use - * log(String, Throwable) instead - */ - public void log(Exception exception, String message) { - this.getLogger().log(Level.INFO, message, exception); - } - - - /** - * Writes the specified message and exception to a servlet log file. - * - * @param message Message to be written - * @param throwable Exception to be reported - */ - public void log(String message, Throwable throwable) { - this.getLogger().log(Level.INFO, message, throwable); - } - - /** - * Remove the context attribute with the specified name, if any. - * - * @param name Name of the context attribute to be removed - */ - public void removeAttribute(String name) { - - Object value = null; - boolean found = false; - - // Remove the specified attribute - // Check for read only attribute - found = attributes.containsKey(name); - if (found) { - value = attributes.get(name); - attributes.remove(name); - } else { - return; - } - - // Notify interested application event listeners - List listeners = this.getListeners(); - if (listeners.size() == 0) - return; - ServletContextAttributeEvent event = null; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof ServletContextAttributeListener)) - continue; - ServletContextAttributeListener listener = - (ServletContextAttributeListener) listeners.get(i); - try { - if (event == null) { - event = new ServletContextAttributeEvent(this.getServletContext(), - name, value); - - } - listener.attributeRemoved(event); - } catch (Throwable t) { - // FIXME - should we do anything besides log these? - log("ServletContextAttributeListener", t); - } - } - } - - - /** - * Bind the specified value with the specified context attribute name, - * replacing any existing value for that name. - * - * @param name Attribute name to be bound - * @param value New attribute value to be bound - */ - public void setAttribute(String name, Object value) { - // Name cannot be null - if (name == null) - throw new IllegalArgumentException - ("name == null"); - - // Null value is the same as removeAttribute() - if (value == null) { - removeAttribute(name); - return; - } - - Object oldValue = null; - boolean replaced = false; - - // Add or replace the specified attribute - synchronized (attributes) { - // Check for read only attribute - oldValue = attributes.get(name); - if (oldValue != null) - replaced = true; - attributes.put(name, value); - } - - // Notify interested application event listeners - List listeners = this.getListeners(); - if (listeners.size() == 0) - return; - ServletContextAttributeEvent event = null; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof ServletContextAttributeListener)) - continue; - ServletContextAttributeListener listener = - (ServletContextAttributeListener) listeners.get(i); - try { - if (event == null) { - if (replaced) - event = - new ServletContextAttributeEvent(this.getServletContext(), - name, oldValue); - else - event = - new ServletContextAttributeEvent(this.getServletContext(), - name, value); - - } - if (replaced) { - listener.attributeReplaced(event); - } else { - listener.attributeAdded(event); - } - } catch (Throwable t) { - // FIXME - should we do anything besides log these? - log("ServletContextAttributeListener error", t); - } - } - - } - - /** - * Clear all application-created attributes. - */ - void clearAttributes() { - // Create list of attributes to be removed - ArrayList list = new ArrayList(); - synchronized (attributes) { - Iterator iter = attributes.keySet().iterator(); - while (iter.hasNext()) { - list.add(iter.next()); - } - } - - // Remove application originated attributes - // (read only attributes will be left in place) - Iterator keys = list.iterator(); - while (keys.hasNext()) { - String key = (String) keys.next(); - removeAttribute(key); - } - } - - public void initFilters() throws ServletException { - Iterator fI = getFilters().values().iterator(); - while (fI.hasNext()) { - FilterConfigImpl fc = (FilterConfigImpl)fI.next(); - try { - fc.getFilter(); // will triger init() - } catch (Throwable e) { - log.log(Level.WARNING, getContextPath() + " Filter.init() " + - fc.getFilterName(), e); - } - - } - } - - public void initServlets() throws ServletException { - Iterator fI = getServletConfigs().values().iterator(); - Map/*>*/ onStartup = - new TreeMap/*>*/(); - while (fI.hasNext()) { - ServletConfigImpl fc = (ServletConfigImpl)fI.next(); - if (fc.getLoadOnStartup() > 0 ) { - Integer i = new Integer(fc.getLoadOnStartup()); - List/**/ old = (List)onStartup.get(i); - if (old == null) { - old = new ArrayList/**/(); - onStartup.put(i, old); - } - old.add(fc); - } - } - Iterator keys = onStartup.keySet().iterator(); - while (keys.hasNext()) { - Integer key = (Integer)keys.next(); - List/**/ servlets = (List)onStartup.get(key); - Iterator servletsI = servlets.iterator(); - while (servletsI.hasNext()) { - ServletConfigImpl fc = (ServletConfigImpl) servletsI.next(); - try { - fc.loadServlet(); - } catch (Throwable e) { - log.log(Level.WARNING, "Error initializing " + fc.getServletName(), e); - } - } - } - } - - public void initListeners() throws ServletException { - Iterator fI = contextConfig.listenerClass.iterator(); - while (fI.hasNext()) { - String listenerClass = (String)fI.next(); - try { - Object l = newInstance(listenerClass, "EventListener-" + listenerClass); - lifecycleListeners.add((EventListener) l); - } catch (Throwable e) { - log.log(Level.WARNING, "Error initializing listener " + listenerClass, e); - } - } - } - - public Object newInstance(String className, String bindName) throws ServletException { - try { - Class cls = getClassLoader().loadClass(className); - Object l = cls.newInstance(); - - // Injections and JMX support - if (bindName != null) { - getObjectManager().bind("Context=" + getContextPath() + "," + - bindName, l); - } - return l; - } catch (Throwable e) { - log.log(Level.WARNING, "Error initializing listener " + className, e); - throw new ServletException(e); - } - } - - public ClassLoader getClassLoader() { - return classLoader; - } - - public void addMapping(String path, String name) { - ServletConfigImpl wrapper = getServletConfig(name); - addMapping(path, wrapper); - } - - public void addMapping(String path, ServletConfigImpl wrapper) { - getEngine().getDispatcher().addWrapper(getContextMap(), path, - wrapper); - } - - - - public void setWelcomeFiles(String[] name) { - getContextMap().welcomeResources = name; - } - - public String[] getWelcomeFiles() { - return getContextMap().welcomeResources; - } - - public BaseMapper.ContextMapping getContextMap() { - if (mapper == null) { - mapper = new BaseMapper.ContextMapping(); - mapper.name = this.getContextPath(); - mapper.welcomeResources = getWelcomeFiles(); - } - return mapper; - } - - public void setSessionTimeout(int to) { - getManager().setSessionTimeout(to); - } - - /** - * Initialize the context from the parsed config. - * - * Note that WebAppData is serializable. - */ - public void processWebAppData(ServletContextConfig d) throws ServletException { - this.contextConfig = d; - - for (String k: d.mimeMapping.keySet()) { - addMimeType(k, d.mimeMapping.get(k)); - } - - String[] wFiles = (String[])d.welcomeFileList.toArray(new String[0]); - if (wFiles.length == 0) { - wFiles = new String[] {"index.html" }; - } - if (basePath != null) { - // TODO: configurable filesystem - getContextMap().resources = - new FileConnectorJavaIo(new File(getBasePath())); - } - setWelcomeFiles(wFiles); - - Iterator i2 = d.filters.values().iterator(); - while (i2.hasNext()) { - FilterData fd = (FilterData)i2.next(); - addFilter(fd.name, fd.className, fd.initParams); - } - - Iterator i3 = d.servlets.values().iterator(); - while (i3.hasNext()) { - ServletData sd = (ServletData) i3.next(); - // jsp-file - if (sd.className == null) { - if (sd.jspFile == null) { - log.log(Level.WARNING, "Missing servlet class for " + sd.name); - continue; - } - } - - ServletConfigImpl sw = - new ServletConfigImpl(this, sd.name, sd.className); - sw.setConfig(sd.initParams); - sw.setJspFile(sd.jspFile); - sw.setLoadOnStartup(sd.loadOnStartup); - //sw.setRunAs(sd.runAs); - sw.setSecurityRoleRef(sd.securityRoleRef); - - addServletConfig(sw); - } - - for (String k: d.servletMapping.keySet()) { - addMapping(k, d.servletMapping.get(k)); - } - - Iterator i5 = d.filterMappings.iterator(); - while (i5.hasNext()) { - FilterMappingData k = (FilterMappingData) i5.next(); - String[] disp = new String[k.dispatcher.size()]; - if (k.urlPattern != null) { - addFilterMapping(k.urlPattern, - k.filterName, - (String[])k.dispatcher.toArray(disp)); - } - if (k.servletName != null) { - addFilterServletMapping(k.servletName, - k.filterName, - (String[])k.dispatcher.toArray(disp)); - } - } - - for (String n: d.localeEncodingMapping.keySet()) { - getCharsetMapper().addCharsetMapping(n, - d.localeEncodingMapping.get(n)); - } - } - - public void addServlet(String servletName, String servletClass, - String jspFile, Map params) { - ServletConfigImpl sc = new ServletConfigImpl(this, servletName, - servletClass); - sc.setJspFile(jspFile); - sc.setConfig(params); - addServletConfig(sc); - } - - public ServletConfigImpl add(String servletName, Servlet servlet) { - ServletConfigImpl sc = new ServletConfigImpl(this, servletName, null); - sc.setServlet(servlet); - addServletConfig(sc); - return sc; - } - - public void addServletSec(String serlvetName, String runAs, Map roles) { - // TODO - } - - - - public void addFilterMapping(String path, String filterName, - String[] dispatcher) { - getFilterMapper().addMapping(filterName, - path, null, dispatcher, true); - - } - - public void addFilterServletMapping(String servlet, - String filterName, - String[] dispatcher) { - getFilterMapper().addMapping(filterName, - null, servlet, - dispatcher, true); - } - - /** - * Called from TomcatLite.init(), required before start. - * - * Will initialize defaults and load web.xml unless webAppData is - * already set and recent. No other processing is done except reading - * the config - you can add or alter it before start() is called. - * - * @throws ServletException - */ - public ServletContextImpl loadConfig() throws ServletException { - long t0 = System.currentTimeMillis(); - if (initDone) { - return this; - } - initDone = true; - // Load global init params from the facade - initEngineDefaults(); - - initTempDir(); - - if (getBasePath() == null || getBasePath().length() == 0) { - // dynamic context - no files or base path - contextConfig = new ServletContextConfig(); - } else { - ConfigLoader cfgLoader = null; - - initClassLoader(getBasePath()); - - if (lite.getDeployListener() != null) { - cfgLoader = (ConfigLoader) newInstance(lite.getDeployListener(), null); - } else { - cfgLoader = new ConfigLoader(); - } - - contextConfig = cfgLoader.loadConfig(getBasePath()); - if (contextConfig == null) { - String msg = "No configuration found, run " + - "'java -jar WarDeploy.jar " + getBasePath() + "'"; - System.err.println(msg); - throw new ServletException(msg); - } - - processWebAppData(contextConfig); - } - // if not defined yet: - addDefaultServlets(); - - long t1 = System.currentTimeMillis(); - - // At this point all config is loaded. Contexts are not yet init() - // - this will happen on start. - log.fine("Context.loadConfig() " + contextPath + " " + (t1-t0)); - return this; - } - - - protected void initTempDir() throws ServletException { - // We need a base path - at least for temp files, req. by spec - if (basePath == null) { - basePath = ("/".equals(contextPath)) ? - lite.getWork().getAbsolutePath() + "/ROOT" : - lite.getWork().getAbsolutePath() + contextPath; - } - - File f = new File(basePath + "/WEB-INF/tmp"); - f.mkdirs(); - setAttribute("javax.servlet.context.tempdir", f); - } - - /** - * Static file handler ( default ) - * *.jsp support - * - */ - protected void addDefaultServlets() throws ServletException { - if (servlets.get("default") == null) { - ServletConfigImpl fileS = new ServletConfigImpl(this, - "default", defaultServlet); - addServletConfig(fileS); - addMapping("/", fileS); - } - - // *.jsp support - if (servlets.get("jspwildcard") == null) { - ServletConfigImpl fileS = new ServletConfigImpl(this, - "jspwildcard", jspWildcardServlet); - fileS.initParams.put("mapper", JspLoader.class.getName()); - addServletConfig(fileS); - addMapping("*.jsp", fileS); - } - - ServletConfigImpl jspcS = new ServletConfigImpl(this, - "jspc", jspcServlet); - addServletConfig(jspcS); - } - - protected void initEngineDefaults() throws ServletException { - - // TODO: make this customizable, avoid loading it on startup - // Set the class name as default in the addon support - for (String sname: lite.ctxDefaultInitParam.keySet()) { - String path = lite.ctxDefaultInitParam.get(sname); - contextConfig.contextParam.put(sname, path); - } - - for (String sname: lite.preloadServlets.keySet()) { - String sclass = lite.preloadServlets.get(sname); - ServletConfigImpl fileS = new ServletConfigImpl(this, sname, sclass); - addServletConfig(fileS); - } - - for (String sname: lite.preloadMappings.keySet()) { - String path = lite.preloadMappings.get(sname); - ServletConfigImpl servletConfig = getServletConfig(sname); - addMapping(path, servletConfig); - } - } - - - private void addClasspathLib(ArrayList res, File directory) { - - if (!directory.isDirectory() || !directory.exists() - || !directory.canRead()) { - return; - } - - File[] jars = directory.listFiles(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.endsWith(".jar"); - } - }); - - for (int j = 0; j < jars.length; j++) { - try { - URL url = jars[j].toURL(); - res.add(url); - } catch (MalformedURLException e) { - } - } - } - - private void addClasspathDir(ArrayList res, File classesDir) { - - if (classesDir.isDirectory() && classesDir.exists() && - classesDir.canRead()) { - try { - URL url = classesDir.toURL(); - res.add(url); - } catch (MalformedURLException e) { - } - } - } - - - public void start() throws ServletException { - if (startDone) { - return; - } - String base = getBasePath(); - - // JMX should know about us ( TODO: is it too early ? ) - lite.notifyAdd(this); - - initListeners(); - - List listeners = this.getListeners(); - ServletContextEvent event = null; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof ServletContextListener)) - continue; - ServletContextListener listener = - (ServletContextListener) listeners.get(i); - if (event == null) { - event = new ServletContextEvent(this); - } - try { - // May add servlets/filters - listener.contextInitialized(event); - } catch (Throwable t) { - log.log(Level.WARNING, "Context.init() contextInitialized() error:", t); - } - } - - - initFilters(); - initServlets(); - - startDone = true; - } - - public String getClassPath() { - return classPath; - } - - private void initClassLoader(String base) { - ArrayList urls = new ArrayList(); - - addClasspathDir(urls, new File(base + "/WEB-INF/classes")); - addClasspathDir(urls, new File(base + "/WEB-INF/tmp")); - addClasspathLib(urls, new File(base + "/WEB-INF/lib")); - - URL[] urlsA = new URL[urls.size()]; - urls.toArray(urlsA); - StringBuilder cp = new StringBuilder(); - - for (URL cpUrl : urlsA) { - cp.append(":").append(cpUrl.getFile()); - } - classPath = cp.toString(); - URLClassLoader parentLoader = - getEngine().getContextParentLoader(); - // create a class loader. - // TODO: reimplement special 'deploy' dirs - - /* - Repository ctxRepo = new Repository(); - ctxRepo.setParentClassLoader(parentLoader); - ctxRepo.addURL(urlsA); - repository = ctxRepo; - */ - - classLoader = new URLClassLoader(urlsA, parentLoader); - } - - public UserSessionManager getManager() { - if (manager == null) { - try { - manager = (UserSessionManager) getObjectManager().get( - UserSessionManager.class); - } catch (Throwable t) { - t.printStackTrace(); - manager = null; - } - if (manager == null) { - try { - manager = (UserSessionManager) newInstance(userSessionManager, "UserSessionManager"); - } catch (ServletException e) { - log.log(Level.SEVERE, "Error creating session manager", e); - return null; - } - } - manager.setContext(this); - if (contextConfig.sessionTimeout > 0 ) { - manager.setSessionTimeout(contextConfig.sessionTimeout); - } - } - return manager; - } - - - // TODO: configurable ? init-params - public String getSessionCookieName() { - return "JSESSIONID"; - } - - - - public void destroy() throws ServletException { - // destroy filters - Iterator fI = filters.values().iterator(); - while(fI.hasNext()) { - FilterConfigImpl fc = (FilterConfigImpl) fI.next(); - try { - fc.getFilter().destroy(); - } catch (Exception e) { - e.printStackTrace(); - } - } - // destroy servlets - fI = servlets.values().iterator(); - while(fI.hasNext()) { - ServletConfigImpl fc = (ServletConfigImpl) fI.next(); - try { - fc.unload(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public TomcatLite getEngine() { - return lite; - } - - public String toString() { - return "{Context_path: " + getContextPath() - + ", dir=" + getBasePath() + "}"; - } - - public String findStatusPage(int status) { - if (contextConfig.errorPageCode.size() == 0) { - return null; - } - if (status == 200) { - return null; - } - - return (String) contextConfig.errorPageCode.get(Integer.toString(status)); - } - - public void handleStatusPage(ServletRequestImpl req, - ServletResponseImpl res, - int status, - String statusPage) { - String message = RequestUtil.filter(res.getMessage()); - if (message == null) - message = ""; - setErrorAttributes(req, status, message); - dispatchError(req, res, statusPage); - } - - protected void setErrorAttributes(ServletRequestImpl req, - int status, - String message) { - req.setAttribute("javax.servlet.error.status_code", - new Integer(status)); - if (req.getWrapper() != null) { - req.setAttribute("javax.servlet.error.servlet_name", - req.getWrapper().servletName); - } - req.setAttribute("javax.servlet.error.request_uri", - req.getRequestURI()); - req.setAttribute("javax.servlet.error.message", - message); - - } - - public void handleError(ServletRequestImpl req, - ServletResponseImpl res, - Throwable t) { - Throwable realError = t; - if (realError instanceof ServletException) { - realError = ((ServletException) realError).getRootCause(); - if (realError == null) { - realError = t; - } - } - //if (realError instanceof ClientAbortException ) { - - String errorPage = findErrorPage(t); - if ((errorPage == null) && (realError != t)) { - errorPage = findErrorPage(realError); - } - - if (errorPage != null) { - setErrorAttributes(req, 500, t.getMessage()); - req.setAttribute("javax.servlet.error.exception", realError); - req.setAttribute("javax.servlet.error.exception_type", - realError.getClass()); - dispatchError(req, res, errorPage); - } else { - log("Unhandled error", t); - if (t instanceof ServletException && - ((ServletException)t).getRootCause() != null) { - log("RootCause:", ((ServletException)t).getRootCause()); - } - if (res.getStatus() < 500) { - res.setStatus(500); - } - } - } - - protected void dispatchError(ServletRequestImpl req, - ServletResponseImpl res, - String errorPage) { - RequestDispatcher rd = - getRequestDispatcher(errorPage); - try { - // will clean up the buffer - rd.forward(req, res); - return; // handled - } catch (ServletException e) { - // TODO - } catch (IOException e) { - // TODO - } - } - - protected String findErrorPage(Throwable exception) { - if (contextConfig.errorPageException.size() == 0) { - return null; - } - if (exception == null) - return (null); - Class clazz = exception.getClass(); - String name = clazz.getName(); - while (!Object.class.equals(clazz)) { - String page = (String)contextConfig.errorPageException.get(name); - if (page != null) - return (page); - clazz = clazz.getSuperclass(); - if (clazz == null) - break; - name = clazz.getName(); - } - return (null); - - } - - public void addFilter(String filterName, String filterClass, - Map params) { - FilterConfigImpl fc = new FilterConfigImpl(this); - fc.setData(filterName, filterClass, params); - filters.put(filterName, fc); - } - - // That's tricky - this filter will have no name. We need to generate one - // because our code relies on names. - AtomicInteger autoName = new AtomicInteger(); - - public T createFilter(Class c) throws ServletException { - FilterConfigImpl fc = new FilterConfigImpl(this); - String filterName = "_tomcat_auto_filter_" + autoName.incrementAndGet(); - fc.setData(filterName, null, new HashMap()); - fc.setFilterClass(c); - filters.put(filterName, fc); - - try { - return (T) fc.createFilter(); - } catch (ClassCastException e) { - throw new ServletException(e); - } catch (ClassNotFoundException e) { - throw new ServletException(e); - } catch (IllegalAccessException e) { - throw new ServletException(e); - } catch (InstantiationException e) { - throw new ServletException(e); - } - } - - public T createServlet(Class c) throws ServletException { - String filterName = "_tomcat_auto_servlet_" + autoName.incrementAndGet(); - ServletConfigImpl fc = new ServletConfigImpl(this, filterName, null); - fc.setServletClass(c); - servlets.put(filterName, fc); - - try { - return (T) fc.newInstance(); - } catch (ClassCastException e) { - throw new ServletException(e); - } catch (IOException e) { - throw new ServletException(e); - } - } - - public boolean setInitParameter(String name, String value) { - HashMap params = contextConfig.contextParam; - return setInitParameter(this, params, name, value); - } - - static Set setInitParameters(ServletContextImpl ctx, - Map params, - Map initParameters) - throws IllegalArgumentException, IllegalStateException { - if (ctx.startDone) { - throw new IllegalStateException(); - } - Set result = new HashSet(); - for (String name: initParameters.keySet()) { - String value = initParameters.get(name); - if (name == null || value == null) { - throw new IllegalArgumentException(); - } - if (!setInitParameter(ctx, params, name, value)) { - result.add(name); - } - } - return result; - } - - /** - * true if the context initialization parameter with the given name and value was set successfully on this ServletContext, and false if it was not set because this ServletContext already contains a context initialization parameter with a matching name - * Throws: - * java.lang.IllegalStateException - if this ServletContext has already been initialized - */ - static boolean setInitParameter(ServletContextImpl ctx, Map params, - String name, String value) { - if (name == null || value == null) { - throw new IllegalArgumentException(); - } - if (ctx.startDone) { - throw new IllegalStateException(); - } - String oldValue = params.get(name); - if (oldValue != null) { - return false; - } else { - params.put(name, value); - return true; - } - } - -} - diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletInputStreamImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletInputStreamImpl.java deleted file mode 100644 index 5a0949085..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletInputStreamImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.IOException; - -import javax.servlet.ServletInputStream; - -import org.apache.tomcat.lite.io.IOInputStream; - - -/** - * Wrapper around BufferInputStream. - */ -public final class ServletInputStreamImpl extends ServletInputStream { - private IOInputStream ib; - - public ServletInputStreamImpl(IOInputStream ib) { - this.ib = ib; - } - - public long skip(long n) - throws IOException { - return ib.skip(n); - } - - public void mark(int readAheadLimit) - { - ib.mark(readAheadLimit); - } - - - public void reset() - throws IOException { - ib.reset(); - } - - public int read() - throws IOException { - return ib.read(); - } - - public int available() throws IOException { - return ib.available(); - } - - public int read(final byte[] b) throws IOException { - return ib.read(b, 0, b.length); - } - - - public int read(final byte[] b, final int off, final int len) - throws IOException { - return ib.read(b, off, len); - } - - - public int readLine(byte[] b, int off, int len) throws IOException { - return ib.readLine(b, off, len); - } - - public void close() throws IOException { - // no call to super.close ! - ib.close(); - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletOutputStreamImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletOutputStreamImpl.java deleted file mode 100644 index ccf622628..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletOutputStreamImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.IOException; - -import javax.servlet.ServletOutputStream; - -import org.apache.tomcat.lite.io.IOOutputStream; - - -/** - * Coyote implementation of the servlet output stream. - * - * @author Costin Manolache - * @author Remy Maucherat - */ -public final class ServletOutputStreamImpl extends ServletOutputStream { - - private IOOutputStream ob; - - public ServletOutputStreamImpl(IOOutputStream ob) { - this.ob = ob; - } - - public void write(int i) - throws IOException { - ob.write(i); - } - - - public void write(byte[] b) - throws IOException { - write(b, 0, b.length); - } - - - public void write(byte[] b, int off, int len) - throws IOException { - ob.write(b, off, len); - } - - - /** - * Will send the buffer to the client. - */ - public void flush() - throws IOException { - ob.flush(); - } - - public void close() - throws IOException { - ob.close(); - } - - public void print(String s) - throws IOException { - ob.print(s); - } -} - diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletReaderImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletReaderImpl.java deleted file mode 100644 index b3fcd9f9a..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletReaderImpl.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.BufferedReader; -import java.io.IOException; - - - -/** - * Coyote implementation of the buffred reader. - * - * @author Remy Maucherat - */ -public final class ServletReaderImpl extends BufferedReader { - - private BufferedReader ib; - - public ServletReaderImpl(BufferedReader ib) { - super(ib, 1); - this.ib = ib; - } - - public void close() - throws IOException { - ib.close(); - } - - - public int read() - throws IOException { - return ib.read(); - } - - - public int read(char[] cbuf) - throws IOException { - return ib.read(cbuf, 0, cbuf.length); - } - - - public int read(char[] cbuf, int off, int len) - throws IOException { - return ib.read(cbuf, off, len); - } - - - public long skip(long n) - throws IOException { - return ib.skip(n); - } - - - public boolean ready() - throws IOException { - return ib.ready(); - } - - - public boolean markSupported() { - return true; - } - - - public void mark(int readAheadLimit) - throws IOException { - ib.mark(readAheadLimit); - } - - - public void reset() - throws IOException { - ib.reset(); - } - - - // TODO: move the readLine functionality to base coyote IO - public String readLine() - throws IOException { - return ib.readLine(); - - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java deleted file mode 100644 index 8b9baa769..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestImpl.java +++ /dev/null @@ -1,1964 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.logging.Level; - -import javax.security.auth.Subject; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequestAttributeEvent; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.tomcat.lite.http.HttpRequest; -import org.apache.tomcat.lite.http.MappingData; -import org.apache.tomcat.lite.http.MultiMap; -import org.apache.tomcat.lite.http.ServerCookie; -import org.apache.tomcat.lite.http.MultiMap.Entry; -import org.apache.tomcat.lite.io.BBuffer; -import org.apache.tomcat.lite.io.CBuffer; -import org.apache.tomcat.lite.io.FastHttpDateFormat; -import org.apache.tomcat.lite.util.LocaleParser; -import org.apache.tomcat.servlets.session.UserSessionManager; -import org.apache.tomcat.servlets.util.Enumerator; -import org.apache.tomcat.servlets.util.RequestUtil; - - -/** - * - * Wrapper object for the request. - * - * @author Remy Maucherat - * @author Craig R. McClanahan - */ -public abstract class ServletRequestImpl implements HttpServletRequest { - - /** - * 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"; - - /** - * 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 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 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 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 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 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"; - - - /** - * The default Locale if none are specified. - */ - protected static Locale defaultLocale = Locale.getDefault(); - - // ApplicationFilterFactory. What's the use ??? - private static Integer REQUEST_INTEGER = new Integer(8); - - /** - * The match string for identifying a session ID parameter. - */ - private static final String match = ";" + SESSION_PARAMETER_NAME + "="; - - /** - * The set of cookies associated with this Request. - */ - protected Cookie[] cookies = null; - - - - - /** - * The attributes associated with this Request, keyed by attribute name. - */ - protected HashMap attributes = new HashMap(); - - /** - * The preferred Locales assocaited with this Request. - */ - protected ArrayList locales = new ArrayList(); - - - /** - * Authentication type. - */ - protected String authType = null; - - /** - * User principal. - */ - protected Principal userPrincipal = null; - - - /** - * The Subject associated with the current AccessControllerContext - */ - protected transient Subject subject = null; - - - /** - * The current dispatcher type. - */ - protected Object dispatcherType = null; - - /** - * ServletInputStream. - */ - protected ServletInputStreamImpl inputStream; - - - /** - * Using stream flag. - */ - protected boolean usingInputStream = false; - - - /** - * Using writer flag. - */ - protected boolean usingReader = false; - - - /** - * Session parsed flag. - */ - protected boolean sessionParsed = false; - - - /** - * Secure flag. - */ - protected boolean secure = false; - - - /** - * The currently active session for this request. - */ - protected HttpSession session = null; - - - /** - * The current request dispatcher path. - */ - protected Object requestDispatcherPath = null; - - - /** - * Was the requested session ID received in a cookie? - */ - protected boolean requestedSessionCookie = false; - - - /** - * The requested session ID (if any) for this request. - */ - protected String requestedSessionId = null; - - - /** - * Was the requested session ID received in a URL? - */ - protected boolean requestedSessionURL = false; - - - /** - * Parse locales. - */ - protected boolean localesParsed = false; - - - /** - * Associated context. - */ - private ServletContextImpl context = null; - - - - // --------------------------------------------------------- Public Methods - - /** - * Filter chain associated with the request. - */ - protected FilterChainImpl filterChain = new FilterChainImpl(); - - - // -------------------------------------------------------- Request Methods - - /** - * The response with which this request is associated. - */ - protected ServletResponseImpl response = new ServletResponseImpl(); - - /** - * URI byte to char converter (not recycled). - */ - // protected B2CConverter URIConverter = null; - - /** - * Associated wrapper. - */ - protected ServletConfigImpl wrapper = null; - - private HttpRequest httpRequest; - - /** New IO/buffer model - * @param req - */ - //protected Http11Connection con; - - ServletRequestImpl(HttpRequest req) { - setHttpRequest(req); - response.setRequest(this); - } - - -// /** -// * Return the Host within which this Request is being processed. -// */ -// public Host getHost() { -// if (getContext() == null) -// return null; -// return (Host) getContext().getParent(); -// //return ((Host) mappingData.host); -// } -// -// -// /** -// * Set the Host within which this Request is being processed. This -// * must be called as soon as the appropriate Host is identified, and -// * before the Request is passed to a context. -// * -// * @param host The newly associated Host -// */ -// public void setHost(Host host) { -// mappingData.host = host; -// } - - /** - * Add a Header to the set of Headers associated with this Request. - * - * @param name The new header name - * @param value The new header value - */ - public void addHeader(String name, String value) { - // Not used - } - - /** - * Add a Locale to the set of preferred Locales for this Request. The - * first added Locale will be the first one returned by getLocales(). - * - * @param locale The new preferred Locale - */ - public void addLocale(Locale locale) { - locales.add(locale); - } - - - /** - * Add a parameter name and corresponding set of values to this Request. - * (This is used when restoring the original request on a form based - * login). - * - * @param name Name of this request parameter - * @param values Corresponding values for this request parameter - */ - public void addParameter(String name, String values) { - httpRequest.addParameter(name, values); - } - - /** - * Clear the collection of Headers associated with this Request. - */ - public void clearHeaders() { - // Not used - } - - /** - * Clear the collection of Locales associated with this Request. - */ - public void clearLocales() { - locales.clear(); - } - - /** - * Clear the collection of parameters associated with this Request. - */ - public void clearParameters() { - // Not used - } - - - /** - * Create and return a ServletInputStream to read the content - * associated with this Request. - * - * @exception IOException if an input/output error occurs - */ - public ServletInputStream createInputStream() - throws IOException { - return inputStream; - } - - /** - * Perform whatever actions are required to flush and close the input - * stream or reader, in a single operation. - * - * @exception IOException if an input/output error occurs - */ - public void finishRequest() throws IOException { - // The reader and input stream don't need to be closed - } - - - /** - * Return the specified request attribute if it exists; otherwise, return - * null. - * - * @param name Name of the request attribute to return - */ - public Object getAttribute(String name) { - - if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) { - return (dispatcherType == null) - ? REQUEST_INTEGER - : dispatcherType; - } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) { - return (requestDispatcherPath == null) - ? getMappingData().requestPath.toString() - : requestDispatcherPath.toString(); - } - - Object attr=attributes.get(name); - - if(attr!=null) - return(attr); - -// attr = reqB.getAttribute(name); -// if(attr != null) -// return attr; -// if( isSSLAttribute(name) ) { -// reqB.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE, -// reqB); -// attr = reqB.getAttribute(ServletRequestImpl.CERTIFICATES_ATTR); -// if( attr != null) { -// attributes.put(ServletRequestImpl.CERTIFICATES_ATTR, attr); -// } -// attr = reqB.getAttribute(ServletRequestImpl.CIPHER_SUITE_ATTR); -// if(attr != null) { -// attributes.put(ServletRequestImpl.CIPHER_SUITE_ATTR, attr); -// } -// attr = reqB.getAttribute(ServletRequestImpl.KEY_SIZE_ATTR); -// if(attr != null) { -// attributes.put(ServletRequestImpl.KEY_SIZE_ATTR, attr); -// } -// attr = reqB.getAttribute(ServletRequestImpl.SSL_SESSION_ID_ATTR); -// if(attr != null) { -// attributes.put(ServletRequestImpl.SSL_SESSION_ID_ATTR, attr); -// } -// attr = attributes.get(name); -// } - return attr; - } - - /** - * Return the names of all request attributes for this Request, or an - * empty Enumeration if there are none. - */ - public Enumeration getAttributeNames() { - if (isSecure()) { - getAttribute(ServletRequestImpl.CERTIFICATES_ATTR); - } - return new Enumerator(attributes.keySet(), true); - } - - - /** - * Return the authentication type used for this Request. - */ - public String getAuthType() { - return (authType); - } - - - // ------------------------------------------------- Request Public Methods - - - /** - * Return the character encoding for this Request. - */ - public String getCharacterEncoding() { - return (httpRequest.getCharacterEncoding()); - } - - - /** - * Return the content length for this Request. - */ - public int getContentLength() { - return ((int) httpRequest.getContentLength()); - } - - -// /** -// * Return the object bound with the specified name to the internal notes -// * for this request, or null if no such binding exists. -// * -// * @param name Name of the note to be returned -// */ -// public Object getNote(String name) { -// return (notes.get(name)); -// } -// -// -// /** -// * Return an Iterator containing the String names of all notes bindings -// * that exist for this request. -// */ -// public Iterator getNoteNames() { -// return (notes.keySet().iterator()); -// } -// -// -// /** -// * Remove any object bound to the specified name in the internal notes -// * for this request. -// * -// * @param name Name of the note to be removed -// */ -// public void removeNote(String name) { -// notes.remove(name); -// } -// -// -// /** -// * Bind an object to a specified name in the internal notes associated -// * with this request, replacing any existing binding for this name. -// * -// * @param name Name to which the object should be bound -// * @param value Object to be bound to the specified name -// */ -// public void setNote(String name, Object value) { -// notes.put(name, value); -// } -// - - /** - * Return the content type for this Request. - */ - public String getContentType() { - return (httpRequest.getContentType()); - } - - - /** - * Return the Context within which this Request is being processed. - */ - public ServletContextImpl getContext() { - if (context == null) { - context = (ServletContextImpl) httpRequest.getMappingData().context; - } - return (this.context); - } - - - /** - * Return the portion of the request URI used to select the Context - * of the Request. - */ - public String getContextPath() { - return (getMappingData().contextPath.toString()); - } - - - /** - * Return the set of Cookies received with this Request. - */ - public Cookie[] getCookies() { - if (cookies == null) { - List serverCookies = httpRequest.getServerCookies(); - if (serverCookies.size() == 0) { - return null; - } - cookies = new Cookie[serverCookies.size()]; - for (int i = 0; i < serverCookies.size(); i++) { - ServerCookie scookie = serverCookies.get(i); - try { - // TODO: we could override all methods and - // return recyclable cookies, if we really wanted - Cookie cookie = new Cookie(scookie.getName().toString(), - scookie.getValue().toString()); - cookie.setPath(scookie.getPath().toString()); - cookie.setVersion(scookie.getVersion()); - String domain = scookie.getDomain().toString(); - if (domain != null) { - cookie.setDomain(scookie.getDomain().toString()); - } - cookies[i] = cookie; - } catch(IllegalArgumentException e) { - // Ignore bad cookie - } - } - } - return cookies; - } - - - /** - * Return the value of the specified date header, if any; otherwise - * return -1. - * - * @param name Name of the requested date header - * - * @exception IllegalArgumentException if the specified header value - * cannot be converted to a date - */ - public long getDateHeader(String name) { - return httpRequest.getDateHeader(name); - } - - /** - * Get filter chain associated with the request. - */ - public FilterChainImpl getFilterChain() { - return (this.filterChain); - } - - - // ------------------------------------------------- ServletRequest Methods - - /** - * Return the first value of the specified header, if any; otherwise, - * return null - * - * @param name Name of the requested header - */ - public String getHeader(String name) { - return httpRequest.getHeader(name); - } - - /** - * Return the names of all headers received with this request. - */ - public Enumeration getHeaderNames() { - return httpRequest.getMimeHeaders().names(); - } - - - /** - * Return all of the values of the specified header, if any; otherwise, - * return an empty enumeration. - * - * @param name Name of the requested header - */ - public Enumeration getHeaders(String name) { - Entry entry = httpRequest.getMimeHeaders().getEntry(name); - if (entry == null) { - return MultiMap.EMPTY; - } - return new MultiMap.IteratorEnumerator(entry.values.iterator()); - } - - /** - * Return the servlet input stream for this Request. The default - * implementation returns a servlet input stream created by - * createInputStream(). - * - * @exception IllegalStateException if getReader() has - * already been called for this request - * @exception IOException if an input/output error occurs - */ - public ServletInputStream getInputStream() throws IOException { - - if (usingReader) - throw new IllegalStateException - ("usingReader"); - - usingInputStream = true; - return inputStream; - - } - - - /** - * Return the value of the specified header as an integer, or -1 if there - * is no such header for this request. - * - * @param name Name of the requested header - * - * @exception IllegalArgumentException if the specified header value - * cannot be converted to an integer - */ - public int getIntHeader(String name) { - - String value = getHeader(name); - if (value == null) { - return (-1); - } else { - return (Integer.parseInt(value)); - } - - } - - - /** - * Returns the Internet Protocol (IP) address of the interface on - * which the request was received. - */ - public String getLocalAddr(){ - return httpRequest.localAddr().toString(); - } - - - /** - * Return the preferred Locale that the client will accept content in, - * based on the value for the first Accept-Language header - * that was encountered. If the request did not specify a preferred - * language, the server's default Locale is returned. - */ - public Locale getLocale() { - - if (!localesParsed) - parseLocales(); - - if (locales.size() > 0) { - return ((Locale) locales.get(0)); - } else { - return (defaultLocale); - } - - } - - - /** - * Return the set of preferred Locales that the client will accept - * content in, based on the values for any Accept-Language - * headers that were encountered. If the request did not specify a - * preferred language, the server's default Locale is returned. - */ - public Enumeration getLocales() { - - if (!localesParsed) - parseLocales(); - - if (locales.size() > 0) - return (new Enumerator(locales)); - ArrayList results = new ArrayList(); - results.add(defaultLocale); - return (new Enumerator(results)); - - } - - - /** - * Returns the host name of the Internet Protocol (IP) interface on - * which the request was received. - */ - public String getLocalName(){ - return httpRequest.localName().toString(); - } - - - /** - * Returns the Internet Protocol (IP) port number of the interface - * on which the request was received. - */ - public int getLocalPort(){ - return httpRequest.getLocalPort(); - } - - /** - * Return the server port responding to this Request. - */ - public int getServerPort() { - return (httpRequest.getServerPort()); - } - - /** - * Return mapping data. - */ - public MappingData getMappingData() { - return (httpRequest.getMappingData()); - } - - - - /** - * Return the HTTP request method used in this Request. - */ - public String getMethod() { - return httpRequest.method().toString(); - } - - - /** - * Return the value of the specified request parameter, if any; otherwise, - * return null. If there is more than one value defined, - * return only the first one. - * - * @param name Name of the desired request parameter - */ - public String getParameter(String name) { - return httpRequest.getParameter(name); - - } - - - /** - * Returns a Map of the parameters of this request. - * Request parameters are extra information sent with the request. - * For HTTP servlets, parameters are contained in the query string - * or posted form data. - * - * @return A Map containing parameter names as keys - * and parameter values as map values. - */ - public Map getParameterMap() { - return httpRequest.getParameterMap(); - } - - - /** - * Return the names of all defined request parameters for this request. - */ - public Enumeration getParameterNames() { - return httpRequest.getParameterNames(); - - } - - - /** - * Return the defined values for the specified request parameter, if any; - * otherwise, return null. - * - * @param name Name of the desired request parameter - */ - public String[] getParameterValues(String name) { - return httpRequest.getParameterValues(name); - - } - - - /** - * Return the path information associated with this Request. - */ - public String getPathInfo() { - CBuffer pathInfo = getMappingData().pathInfo; - if (pathInfo.length() == 0) { - return null; - } - return (getMappingData().pathInfo.toString()); - } - - - /** - * Return the extra path information for this request, translated - * to a real path. - */ - public String getPathTranslated() { - - if (getContext() == null) - return (null); - - if (getPathInfo() == null) { - return (null); - } else { - return (getContext().getServletContext().getRealPath(getPathInfo())); - } - - } - - /** - * Return the principal that has been authenticated for this Request. - */ - public Principal getPrincipal() { - return (userPrincipal); - } - - /** - * Return the protocol and version used to make this Request. - */ - public String getProtocol() { - return httpRequest.protocol().toString(); - } - - /** - * Return the query string associated with this request. - */ - public String getQueryString() { - String queryString = httpRequest.queryString().toString(); - if (queryString == null || queryString.equals("")) { - return (null); - } else { - return queryString; - } - } - - - /** - * Read the Reader wrapping the input stream for this Request. The - * default implementation wraps a BufferedReader around the - * servlet input stream returned by createInputStream(). - * - * @exception IllegalStateException if getInputStream() - * has already been called for this request - * @exception IOException if an input/output error occurs - */ - public BufferedReader getReader() throws IOException { - - if (usingInputStream) - throw new IllegalStateException - ("usingInputStream"); - - usingReader = true; - return httpRequest.getReader(); - - } - - /** - * Return the real path of the specified virtual path. - * - * @param path Path to be translated - * - * @deprecated As of version 2.1 of the Java Servlet API, use - * ServletContext.getRealPath(). - */ - public String getRealPath(String path) { - - if (getContext() == null) - return (null); - ServletContext servletContext = getContext(); // .getServletContext(); - if (servletContext == null) - return (null); - else { - try { - return (servletContext.getRealPath(path)); - } catch (IllegalArgumentException e) { - return (null); - } - } - - } - - - /** - * Return the remote IP address making this Request. - */ - public String getRemoteAddr() { - return httpRequest.remoteAddr().toString(); - } - - - /** - * Return the remote host name making this Request. - */ - public String getRemoteHost() { - return httpRequest.remoteHost().toString(); - } - - - /** - * Returns the Internet Protocol (IP) source port of the client - * or last proxy that sent the request. - */ - public int getRemotePort(){ - return httpRequest.getRemotePort(); - } - - - /** - * Return the name of the remote user that has been authenticated - * for this Request. - */ - public String getRemoteUser() { - - if (userPrincipal != null) { - return (userPrincipal.getName()); - } else { - return (null); - } - - } - - - /** - * Return the ServletRequest for which this object - * is the facade. This method must be implemented by a subclass. - */ - public HttpServletRequest getRequest() { - return this; - } - - public HttpRequest getHttpRequest() { - return httpRequest; - } - - public void setHttpRequest(HttpRequest req) { - this.httpRequest = req; - inputStream = new ServletInputStreamImpl(req.getBodyInputStream()); - } - - /** - * Return a RequestDispatcher that wraps the resource at the specified - * path, which may be interpreted as relative to the current request path. - * - * @param path Path of the resource to be wrapped - */ - public RequestDispatcher getRequestDispatcher(String path) { - - if (getContext() == null) - return (null); - - // If the path is already context-relative, just pass it through - if (path == null) - return (null); - else if (path.startsWith("/")) - return (getContext().getRequestDispatcher(path)); - - // Convert a request-relative path to a context-relative one - String servletPath = (String) getAttribute(RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR); - if (servletPath == null) - servletPath = getServletPath(); - - // Add the path info, if there is any - String pathInfo = getPathInfo(); - String requestPath = null; - - if (pathInfo == null) { - requestPath = servletPath; - } else { - requestPath = servletPath + pathInfo; - } - - int pos = requestPath.lastIndexOf('/'); - String relative = null; - if (pos >= 0) { - relative = RequestUtil.normalize - (requestPath.substring(0, pos + 1) + path); - } else { - relative = RequestUtil.normalize(requestPath + path); - } - - return (getContext().getRequestDispatcher(relative)); - - } - - - /** - * Return the session identifier included in this request, if any. - */ - public String getRequestedSessionId() { - return (requestedSessionId); - } - - - // ---------------------------------------------------- HttpRequest Methods - - - /** - * Return the request URI for this request. - */ - public String getRequestURI() { - return httpRequest.requestURI().toString(); - } - - /** - * Reconstructs the URL the client used to make the request. - * The returned URL contains a protocol, server name, port - * number, and server path, but it does not include query - * string parameters. - *

- * Because this method returns a StringBuffer, - * not a String, you can modify the URL easily, - * for example, to append query parameters. - *

- * This method is useful for creating redirect messages and - * for reporting errors. - * - * @return A StringBuffer object containing the - * reconstructed URL - */ - public StringBuffer getRequestURL() { - - StringBuffer url = new StringBuffer(); - String scheme = getScheme(); - int port = getServerPort(); - if (port < 0) - port = 80; // Work around java.net.URL bug - - url.append(scheme); - url.append("://"); - url.append(getServerName()); - if ((scheme.equals("http") && (port != 80)) - || (scheme.equals("https") && (port != 443))) { - url.append(':'); - url.append(port); - } - url.append(getRequestURI()); - - return (url); - - } - - - /** - * Return the Response with which this Request is associated. - */ - public ServletResponseImpl getResponse() { - return (this.response); - } - - - /** - * Return the scheme used to make this Request. - */ - public String getScheme() { - String scheme = httpRequest.scheme().toString(); - if (scheme == null) { - scheme = (isSecure() ? "https" : "http"); - } - return scheme; - } - - - /** - * Return the server name responding to this Request. - */ - public String getServerName() { - return httpRequest.getServerName(); - } - - - - /** - * Return the portion of the request URI used to select the servlet - * that will process this request. - */ - public String getServletPath() { - return (getMappingData().wrapperPath.toString()); - } - - /** - * Return the input stream associated with this Request. - */ - public InputStream getStream() { - return inputStream; - } - - - /** - * Return the principal that has been authenticated for this Request. - */ - public Principal getUserPrincipal() { - return userPrincipal; - } - - - /** - * Return the Wrapper within which this Request is being processed. - */ - public ServletConfigImpl getWrapper() { - return (this.wrapper); - } - - - /** - * Return true if the session identifier included in this - * request came from a cookie. - */ - public boolean isRequestedSessionIdFromCookie() { - - if (requestedSessionId != null) - return (requestedSessionCookie); - else - return (false); - - } - - - /** - * Return true if the session identifier included in this - * request came from the request URI. - * - * @deprecated As of Version 2.1 of the Java Servlet API, use - * isRequestedSessionIdFromURL() instead. - */ - public boolean isRequestedSessionIdFromUrl() { - return (isRequestedSessionIdFromURL()); - } - - - /** - * Return true if the session identifier included in this - * request came from the request URI. - */ - public boolean isRequestedSessionIdFromURL() { - - if (requestedSessionId != null) - return (requestedSessionURL); - else - return (false); - - } - - - /** - * Return true if the session identifier included in this - * request identifies a valid session. - */ - public boolean isRequestedSessionIdValid() { - - if (requestedSessionId == null) - return (false); - if (getContext() == null) - return (false); - UserSessionManager manager = getContext().getManager(); - if (manager == null) - return (false); - HttpSession session = null; - try { - session = manager.findSession(requestedSessionId); - } catch (IOException e) { - session = null; - } - if ((session != null) && manager.isValid(session)) - return (true); - else - return (false); - - } - - /** - * Was this request received on a secure connection? - */ - public boolean isSecure() { - return (secure); - } - - - /** - * Return true if the authenticated user principal - * possesses the specified role name. - * - * @param role Role name to be validated - */ - public boolean isUserInRole(String role) { - // Have we got an authenticated principal at all? - Principal userPrincipal = getPrincipal(); - if (userPrincipal == null) - return (false); - - // Identify the Realm we will use for checking role assignmenets - if (getContext() == null) - return (false); - - // Check for a role alias defined in a element - if (wrapper != null) { - String realRole = wrapper.getSecurityRoleRef(role); - if (realRole != null) { - role = realRole; - } - } - - if (role.equals(userPrincipal.getName())) { - return true; - } - - // TODO: check !!!! - // Check for a role defined directly as a - return false; - } - - /** - * Release all object references, and initialize instance variables, in - * preparation for reuse of this object. - */ - void recycle() { - - wrapper = null; - - dispatcherType = null; - requestDispatcherPath = null; - - authType = null; - usingInputStream = false; - usingReader = false; - userPrincipal = null; - subject = null; - sessionParsed = false; - locales.clear(); - localesParsed = false; - secure = false; - - attributes.clear(); - //notes.clear(); - cookies = null; - - if (session != null) { - getContext().getManager().endAccess(session); - } - setContext(null); - session = null; - requestedSessionCookie = false; - requestedSessionId = null; - requestedSessionURL = false; - - //getMappingData().recycle(); - // httpRequest.recycle(); - - response.recycle(); - } - - - - /** - * Remove the specified request attribute if it exists. - * - * @param name Name of the request attribute to remove - */ - public void removeAttribute(String name) { - Object value = null; - boolean found = false; - - // Remove the specified attribute - // Check for read only attribute - // requests are per thread so synchronization unnecessary -// if (readOnlyAttributes.containsKey(name)) { -// return; -// } - found = attributes.containsKey(name); - if (found) { - value = attributes.get(name); - attributes.remove(name); - } else { - return; - } - - // Notify interested application event listeners - List listeners = getContext().getListeners(); - if (listeners.size() == 0) - return; - ServletRequestAttributeEvent event = null; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof ServletRequestAttributeListener)) - continue; - ServletRequestAttributeListener listener = - (ServletRequestAttributeListener) listeners.get(i); - try { - if (event == null) { - event = - new ServletRequestAttributeEvent(getContext().getServletContext(), - getRequest(), name, value); - } - listener.attributeRemoved(event); - } catch (Throwable t) { - getContext().getLogger().log(Level.WARNING, "ServletRequestAttributeListner.attributeRemoved()", t); - // Error valve will pick this execption up and display it to user - attributes.put( ServletRequestImpl.EXCEPTION_ATTR, t ); - } - } - } - - - /** - * Set the specified request attribute to the specified value. - * - * @param name Name of the request attribute to set - * @param value The associated value - */ - public void setAttribute(String name, Object value) { - - // Name cannot be null - if (name == null) - throw new IllegalArgumentException - ("setAttribute() name == null"); - - // Null value is the same as removeAttribute() - if (value == null) { - removeAttribute(name); - return; - } - - if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) { - dispatcherType = value; - return; - } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) { - requestDispatcherPath = value; - return; - } - - Object oldValue = null; - boolean replaced = false; - - // Add or replace the specified attribute - // Check for read only attribute - // requests are per thread so synchronization unnecessary -// if (readOnlyAttributes.containsKey(name)) { -// return; -// } - - oldValue = attributes.put(name, value); - if (oldValue != null) { - replaced = true; - } - - // Pass special attributes to the native layer -// if (name.startsWith("org.apache.tomcat.")) { -// reqB.setAttribute(name, value); -// } -// - // Notify interested application event listeners - List listeners = getContext().getListeners(); - if (listeners.size() == 0) - return; - ServletRequestAttributeEvent event = null; - - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof ServletRequestAttributeListener)) - continue; - ServletRequestAttributeListener listener = - (ServletRequestAttributeListener) listeners.get(i); - try { - if (event == null) { - if (replaced) - event = - new ServletRequestAttributeEvent(getContext().getServletContext(), - getRequest(), name, oldValue); - else - event = - new ServletRequestAttributeEvent(getContext().getServletContext(), - getRequest(), name, value); - } - if (replaced) { - listener.attributeReplaced(event); - } else { - listener.attributeAdded(event); - } - } catch (Throwable t) { - getContext().getLogger().log(Level.WARNING, "ServletRequestAttributeListener error", t); - // Error valve will pick this execption up and display it to user - attributes.put( ServletRequestImpl.EXCEPTION_ATTR, t ); - } - } - } - - - // --------------------------------------------- HttpServletRequest Methods - - - /** - * Set the authentication type used for this request, if any; otherwise - * set the type to null. Typical values are "BASIC", - * "DIGEST", or "SSL". - * - * @param type The authentication type used - */ - public void setAuthType(String type) { - this.authType = type; - } - - - /** - * Overrides the name of the character encoding used in the body of - * this request. This method must be called prior to reading request - * parameters or reading input using getReader(). - * - * @param enc The character encoding to be used - * - * @exception UnsupportedEncodingException if the specified encoding - * is not supported - * - * @since Servlet 2.3 - */ - public void setCharacterEncoding(String enc) - throws UnsupportedEncodingException { - - // Ensure that the specified encoding is valid - byte buffer[] = new byte[1]; - buffer[0] = (byte) 'a'; - String dummy = new String(buffer, enc); - - // Save the validated encoding - httpRequest.setCharacterEncoding(enc); - - } - - /** - * Set the Context within which this Request is being processed. This - * must be called as soon as the appropriate Context is identified, because - * it identifies the value to be returned by getContextPath(), - * and thus enables parsing of the request URI. - * - * @param context The newly associated Context - */ - public void setContext(ServletContextImpl context) { - this.context = context; - } - - - /** - * Set the context path for this Request. This will normally be called - * when the associated Context is mapping the Request to a particular - * Wrapper. - * - * @param path The context path - */ - public void setContextPath(String path) { - - if (path == null) { - getMappingData().contextPath.set(""); - } else { - getMappingData().contextPath.set(path); - } - - } - - /** - * Set the path information for this Request. This will normally be called - * when the associated Context is mapping the Request to a particular - * Wrapper. - * - * @param path The path information - */ - public void setPathInfo(String path) { - getMappingData().pathInfo.set(path); - } - - - /** - * Set a flag indicating whether or not the requested session ID for this - * request came in through a cookie. This is normally called by the - * HTTP Connector, when it parses the request headers. - * - * @param flag The new flag - */ - public void setRequestedSessionCookie(boolean flag) { - - this.requestedSessionCookie = flag; - - } - - - /** - * Set the requested session ID for this request. This is normally called - * by the HTTP Connector, when it parses the request headers. - * - * @param id The new session id - */ - public void setRequestedSessionId(String id) { - - this.requestedSessionId = id; - - } - - - /** - * Set a flag indicating whether or not the requested session ID for this - * request came in through a URL. This is normally called by the - * HTTP Connector, when it parses the request headers. - * - * @param flag The new flag - */ - public void setRequestedSessionURL(boolean flag) { - - this.requestedSessionURL = flag; - - } - - /** - * Set the servlet path for this Request. This will normally be called - * when the associated Context is mapping the Request to a particular - * Wrapper. - * - * @param path The servlet path - */ - public void setServletPath(String path) { - if (path != null) - getMappingData().wrapperPath.set(path); - } - - - /** - * Set the input stream associated with this Request. - * - * @param stream The new input stream - */ - public void setStream(InputStream stream) { - // Ignore - } - - - /** - * Set the Principal who has been authenticated for this Request. This - * value is also used to calculate the value to be returned by the - * getRemoteUser() method. - * - * @param principal The user Principal - */ - public void setUserPrincipal(Principal principal) { - - if (System.getSecurityManager() != null){ - HttpSession session = getSession(false); - if ( (subject != null) && - (!subject.getPrincipals().contains(principal)) ){ - subject.getPrincipals().add(principal); - } else if (session != null && - session.getAttribute(ServletRequestImpl.SUBJECT_ATTR) == null) { - subject = new Subject(); - subject.getPrincipals().add(principal); - } - if (session != null){ - session.setAttribute(ServletRequestImpl.SUBJECT_ATTR, subject); - } - } - - this.userPrincipal = principal; - } - - - /** - * Set the Wrapper within which this Request is being processed. This - * must be called as soon as the appropriate Wrapper is identified, and - * before the Request is ultimately passed to an application servlet. - * @param wrapper The newly associated Wrapper - */ - public void setWrapper(ServletConfigImpl wrapper) { - this.wrapper = wrapper; - } - - - public String toString() { - return httpRequest.requestURI().toString(); - } - - - /** - * Configures the given JSESSIONID cookie. - * - * @param cookie The JSESSIONID cookie to be configured - */ - protected void configureSessionCookie(Cookie cookie) { - cookie.setMaxAge(-1); - String contextPath = null; - if (//!connector.getEmptySessionPath() && - (getContext() != null)) { - contextPath = getContext().getEncodedPath(); - } - if ((contextPath != null) && (contextPath.length() > 0)) { - cookie.setPath(contextPath); - } else { - cookie.setPath("/"); - } - if (isSecure()) { - cookie.setSecure(true); - } - } - - - /** - * Return the session associated with this Request, creating one - * if necessary. - */ - public HttpSession getSession() { - return getSession(true); - } - - - public HttpSession getSession(boolean create) { - - // There cannot be a session if no context has been assigned yet - if (getContext() == null) - return (null); - - - // Return the requested session if it exists and is valid - UserSessionManager manager = null; - if (getContext() != null) - manager = getContext().getManager(); - if (manager == null) - return (null); // Sessions are not supported - - // Return the current session if it exists and is valid - if ((session != null) && !manager.isValid(session)) - session = null; - if (session != null) - return (session); - - - if (requestedSessionId != null) { - try { - session = manager.findSession(requestedSessionId); - } catch (IOException e) { - session = null; - } - if ((session != null) && !manager.isValid(session)) - session = null; - if (session != null) { - manager.access(session); - return (session); - } - } - - // Create a new session if requested and the response is not committed - if (!create) - return (null); - if ((getContext() != null) && (response != null) && - getContext().getCookies() && - getResponse().isCommitted()) { - throw new IllegalStateException - ("isCommited()"); - } - - // Attempt to reuse session id if one was submitted in a cookie - // Do not reuse the session id if it is from a URL, to prevent possible - // phishing attacks - if (// connector.getEmptySessionPath() && - isRequestedSessionIdFromCookie()) { - session = manager.createSession(getRequestedSessionId()); - } else { - session = manager.createSession(null); - } - - // Creating a new session cookie based on that session - if ((session != null) && (getContext() != null) - && getContext().getCookies()) { - Cookie cookie = new Cookie(ServletRequestImpl.SESSION_COOKIE_NAME, - session.getId()); - configureSessionCookie(cookie); - response.addCookie(cookie); - } - - if (session != null) { - manager.access(session); - return (session); - } else { - return (null); - } - - } - - - /** - * Parse request locales. - */ - protected void parseLocales() { - - localesParsed = true; - - Enumeration values = getHeaders("accept-language"); - - while (values.hasMoreElements()) { - String value = values.nextElement().toString(); - parseLocalesHeader(value); - } - - } - - /** - * Parse accept-language header value. - */ - protected void parseLocalesHeader(String value) { - - TreeMap locales = new LocaleParser().parseLocale(value); - // Process the quality values in highest->lowest order (due to - // negating the Double value when creating the key) - Iterator keys = locales.keySet().iterator(); - while (keys.hasNext()) { - Double key = (Double) keys.next(); - ArrayList list = (ArrayList) locales.get(key); - Iterator values = list.iterator(); - while (values.hasNext()) { - Locale locale = (Locale) values.next(); - addLocale(locale); - } - } - - } - - - /** - * Parse session id in URL. Done in request for performance. - * TODO: should be done in manager - */ - protected void parseSessionCookiesId() { - String sessionCookieName = getContext().getSessionCookieName(); - - // Parse session id from cookies - ServerCookie scookie = - httpRequest.getCookie(sessionCookieName); - if (scookie == null) { - return; - } - // Override anything requested in the URL - if (!isRequestedSessionIdFromCookie()) { - // Accept only the first session id cookie - //scookie.getValue().convertToAscii(); - - setRequestedSessionId - (scookie.getValue().toString()); - setRequestedSessionCookie(true); - setRequestedSessionURL(false); - } else { - if (!isRequestedSessionIdValid()) { - // Replace the session id until one is valid - //scookie.getValue().convertToAscii(); - setRequestedSessionId - (scookie.getValue().toString()); - } - } - } - - /** - * Parse session id in URL. - */ - protected void parseSessionId() { - ServletRequestImpl request = this; - BBuffer uriBC = httpRequest.getMsgBytes().url(); - int semicolon = uriBC.indexOf(match, 0, match.length(), 0); - - if (semicolon > 0) { - - // Parse session ID, and extract it from the decoded request URI - int start = uriBC.getStart(); - int end = uriBC.getEnd(); - - int sessionIdStart = semicolon + match.length(); - int semicolon2 = uriBC.indexOf(';', sessionIdStart); - if (semicolon2 >= 0) { - request.setRequestedSessionId - (new String(uriBC.array(), start + sessionIdStart, - semicolon2 - sessionIdStart)); - // Extract session ID from request URI - byte[] buf = uriBC.array(); - for (int i = 0; i < end - start - semicolon2; i++) { - buf[start + semicolon + i] - = buf[start + i + semicolon2]; - } - uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon); - } else { - request.setRequestedSessionId - (new String(uriBC.array(), start + sessionIdStart, - (end - start) - sessionIdStart)); - uriBC.setEnd(start + semicolon); - } - request.setRequestedSessionURL(true); - - } else { - request.setRequestedSessionId(null); - request.setRequestedSessionURL(false); - } - - } - - - - /** - * Test if a given name is one of the special Servlet-spec SSL attributes. - */ - static boolean isSSLAttribute(String name) { - return ServletRequestImpl.CERTIFICATES_ATTR.equals(name) || - ServletRequestImpl.CIPHER_SUITE_ATTR.equals(name) || - ServletRequestImpl.KEY_SIZE_ATTR.equals(name) || - ServletRequestImpl.SSL_SESSION_ID_ATTR.equals(name); - } - - - - public ServletContext getServletContext() { - return getContext(); - } - - - public boolean isAsyncStarted() { - return httpRequest.isAsyncStarted(); - } - - - public boolean isAsyncSupported() { - return false; - } - - - public void setAsyncTimeout(long timeout) { - httpRequest.setAsyncTimeout(timeout); - } - - - public boolean authenticate(HttpServletResponse response) - throws IOException, ServletException { - return false; - } - - public void login(String username, String password) throws ServletException { - } - - - public void logout() throws ServletException { - } - - - public long getAsyncTimeout() { - return 0; - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestWrapperImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestWrapperImpl.java deleted file mode 100644 index 05abaef34..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletRequestWrapperImpl.java +++ /dev/null @@ -1,944 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpSession; - -import org.apache.tomcat.servlets.session.UserSessionManager; -import org.apache.tomcat.servlets.util.Enumerator; -import org.apache.tomcat.servlets.util.RequestUtil; - - -/** - * Wrapper around a javax.servlet.http.HttpServletRequest - * that transforms an application request object (which might be the original - * one passed to a servlet, or might be based on the 2.3 - * javax.servlet.http.HttpServletRequestWrapper class) - * back into an internal org.apache.catalina.HttpRequest. - *

- * WARNING: Due to Java's lack of support for multiple - * inheritance, all of the logic in ApplicationRequest is - * duplicated in ApplicationHttpRequest. Make sure that you - * keep these two classes in synchronization when making changes! - * - * @author Craig R. McClanahan - * @author Remy Maucherat - */ -public class ServletRequestWrapperImpl extends HttpServletRequestWrapper { - - - // ------------------------------------------------------- Static Variables - - - /** - * The set of attribute names that are special for request dispatchers. - */ - protected static final String specials[] = - { RequestDispatcherImpl.INCLUDE_REQUEST_URI_ATTR, - RequestDispatcherImpl.INCLUDE_CONTEXT_PATH_ATTR, - RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR, - RequestDispatcherImpl.INCLUDE_PATH_INFO_ATTR, - RequestDispatcherImpl.INCLUDE_QUERY_STRING_ATTR, - RequestDispatcherImpl.FORWARD_REQUEST_URI_ATTR, - RequestDispatcherImpl.FORWARD_CONTEXT_PATH_ATTR, - RequestDispatcherImpl.FORWARD_SERVLET_PATH_ATTR, - RequestDispatcherImpl.FORWARD_PATH_INFO_ATTR, - RequestDispatcherImpl.FORWARD_QUERY_STRING_ATTR }; - - - // ----------------------------------------------------------- Constructors - - - /** - * Construct a new wrapped request around the specified servlet request. - * - * @param request The servlet request being wrapped - */ - public ServletRequestWrapperImpl(HttpServletRequest request, - ServletContextImpl context, - boolean crossContext) { - - super(request); - this.context = context; - this.crossContext = crossContext; - setRequest(request); - - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * The context for this request. - */ - protected ServletContextImpl context = null; - - - /** - * The context path for this request. - */ - protected String contextPath = null; - - - /** - * If this request is cross context, since this changes session accesss - * behavior. - */ - protected boolean crossContext = false; - - - /** - * The current dispatcher type. - */ - protected Object dispatcherType = null; - - - /** - * Descriptive information about this implementation. - */ - protected static final String info = - "org.apache.catalina.core.ApplicationHttpRequest/1.0"; - - - /** - * The request parameters for this request. This is initialized from the - * wrapped request, but updates are allowed. - */ - protected Map parameters = null; - - - /** - * Have the parameters for this request already been parsed? - */ - private boolean parsedParams = false; - - - /** - * The path information for this request. - */ - protected String pathInfo = null; - - - /** - * The query parameters for the current request. - */ - private String queryParamString = null; - - - /** - * The query string for this request. - */ - protected String queryString = null; - - - /** - * The current request dispatcher path. - */ - protected Object requestDispatcherPath = null; - - - /** - * The request URI for this request. - */ - protected String requestURI = null; - - - /** - * The servlet path for this request. - */ - protected String servletPath = null; - - - /** - * The currently active session for this request. - */ - protected HttpSession session = null; - - - /** - * Special attributes. - */ - protected Object[] specialAttributes = new Object[specials.length]; - - - // ------------------------------------------------- ServletRequest Methods - - - /** - * Override the getAttribute() method of the wrapped request. - * - * @param name Name of the attribute to retrieve - */ - public Object getAttribute(String name) { - - if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) { - return dispatcherType; - } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) { - if ( requestDispatcherPath != null ){ - return requestDispatcherPath.toString(); - } else { - return null; - } - } - - int pos = getSpecial(name); - if (pos == -1) { - return getRequest().getAttribute(name); - } else { - if ((specialAttributes[pos] == null) - && (specialAttributes[5] == null) && (pos >= 5)) { - // If it's a forward special attribute, and null, it means this - // is an include, so we check the wrapped request since - // the request could have been forwarded before the include - return getRequest().getAttribute(name); - } else { - return specialAttributes[pos]; - } - } - - } - - - /** - * Override the getAttributeNames() method of the wrapped - * request. - */ - public Enumeration getAttributeNames() { - return (new AttributeNamesEnumerator()); - } - - - /** - * Override the removeAttribute() method of the - * wrapped request. - * - * @param name Name of the attribute to remove - */ - public void removeAttribute(String name) { - - if (!removeSpecial(name)) - getRequest().removeAttribute(name); - - } - - - /** - * Override the setAttribute() method of the - * wrapped request. - * - * @param name Name of the attribute to set - * @param value Value of the attribute to set - */ - public void setAttribute(String name, Object value) { - - if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) { - dispatcherType = value; - return; - } else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) { - requestDispatcherPath = value; - return; - } - - if (!setSpecial(name, value)) { - getRequest().setAttribute(name, value); - } - - } - - - /** - * Return a RequestDispatcher that wraps the resource at the specified - * path, which may be interpreted as relative to the current request path. - * - * @param path Path of the resource to be wrapped - */ - public RequestDispatcher getRequestDispatcher(String path) { - - if (context == null) - return (null); - - // If the path is already context-relative, just pass it through - if (path == null) - return (null); - else if (path.startsWith("/")) - return (context.getServletContext().getRequestDispatcher(path)); - - // Convert a request-relative path to a context-relative one - String servletPath = - (String) getAttribute(RequestDispatcherImpl.INCLUDE_SERVLET_PATH_ATTR); - if (servletPath == null) - servletPath = getServletPath(); - - // Add the path info, if there is any - String pathInfo = getPathInfo(); - String requestPath = null; - - if (pathInfo == null) { - requestPath = servletPath; - } else { - requestPath = servletPath + pathInfo; - } - - int pos = requestPath.lastIndexOf('/'); - String relative = null; - if (pos >= 0) { - relative = RequestUtil.normalize - (requestPath.substring(0, pos + 1) + path); - } else { - relative = RequestUtil.normalize(requestPath + path); - } - - return (context.getServletContext().getRequestDispatcher(relative)); - - } - - - // --------------------------------------------- HttpServletRequest Methods - - - /** - * Override the getContextPath() method of the wrapped - * request. - */ - public String getContextPath() { - - return (this.contextPath); - - } - - - /** - * Override the getParameter() method of the wrapped request. - * - * @param name Name of the requested parameter - */ - public String getParameter(String name) { - - parseParameters(); - - Object value = parameters.get(name); - if (value == null) - return (null); - else if (value instanceof String[]) - return (((String[]) value)[0]); - else if (value instanceof String) - return ((String) value); - else - return (value.toString()); - - } - - - /** - * Override the getParameterMap() method of the - * wrapped request. - */ - public Map getParameterMap() { - - parseParameters(); - return (parameters); - - } - - - /** - * Override the getParameterNames() method of the - * wrapped request. - */ - public Enumeration getParameterNames() { - - parseParameters(); - return (new Enumerator(parameters.keySet())); - - } - - - /** - * Override the getParameterValues() method of the - * wrapped request. - * - * @param name Name of the requested parameter - */ - public String[] getParameterValues(String name) { - - parseParameters(); - Object value = parameters.get(name); - if (value == null) - return ((String[]) null); - else if (value instanceof String[]) - return ((String[]) value); - else if (value instanceof String) { - String values[] = new String[1]; - values[0] = (String) value; - return (values); - } else { - String values[] = new String[1]; - values[0] = value.toString(); - return (values); - } - - } - - - /** - * Override the getPathInfo() method of the wrapped request. - */ - public String getPathInfo() { - - return (this.pathInfo); - - } - - - /** - * Override the getQueryString() method of the wrapped - * request. - */ - public String getQueryString() { - - return (this.queryString); - - } - - - /** - * Override the getRequestURI() method of the wrapped - * request. - */ - public String getRequestURI() { - - return (this.requestURI); - - } - - - /** - * Override the getRequestURL() method of the wrapped - * request. - */ - public StringBuffer getRequestURL() { - - StringBuffer url = new StringBuffer(); - String scheme = getScheme(); - int port = getServerPort(); - if (port < 0) - port = 80; // Work around java.net.URL bug - - url.append(scheme); - url.append("://"); - url.append(getServerName()); - if ((scheme.equals("http") && (port != 80)) - || (scheme.equals("https") && (port != 443))) { - url.append(':'); - url.append(port); - } - url.append(getRequestURI()); - - return (url); - - } - - - /** - * Override the getServletPath() method of the wrapped - * request. - */ - public String getServletPath() { - - return (this.servletPath); - - } - - - /** - * Return the session associated with this Request, creating one - * if necessary. - */ - public HttpSession getSession() { - return (getSession(true)); - } - - - /** - * Return the session associated with this Request, creating one - * if necessary and requested. - * - * @param create Create a new session if one does not exist - */ - public HttpSession getSession(boolean create) { - - if (crossContext) { - - // There cannot be a session if no context has been assigned yet - if (context == null) - return (null); - UserSessionManager manager = context.getManager(); - // Return the current session if it exists and is valid - if (session != null && manager.isValid(session)) { - return session; - } - - HttpSession other = super.getSession(false); - if (create && (other == null)) { - // First create a session in the first context: the problem is - // that the top level request is the only one which can - // create the cookie safely - other = super.getSession(true); - } - if (other != null) { - HttpSession localSession = null; - try { - localSession = - manager.findSession(other.getId()); - } catch (IOException e) { - // Ignore - } - if (localSession == null && create) { - localSession = - context.getManager().createSession(other.getId()); - } - if (localSession != null) { - context.getManager().access(localSession); - session = localSession; - return session; - } - } - return null; - - } else { - return super.getSession(create); - } - - } - - - /** - * Returns true if the request specifies a JSESSIONID that is valid within - * the context of this ApplicationHttpRequest, false otherwise. - * - * @return true if the request specifies a JSESSIONID that is valid within - * the context of this ApplicationHttpRequest, false otherwise. - */ - public boolean isRequestedSessionIdValid() { - - if (crossContext) { - - String requestedSessionId = getRequestedSessionId(); - if (requestedSessionId == null) - return (false); - if (context == null) - return (false); - UserSessionManager manager = context.getManager(); - if (manager == null) - return (false); - HttpSession session = null; - try { - session = manager.findSession(requestedSessionId); - } catch (IOException e) { - session = null; - } - if ((session != null) && manager.isValid(session)) { - return (true); - } else { - return (false); - } - - } else { - return super.isRequestedSessionIdValid(); - } - } - - - // -------------------------------------------------------- Package Methods - - - /** - * Recycle this request - */ - public void recycle() { - if (session != null) { - context.getManager().endAccess(session); - } - } - - - /** - * Return descriptive information about this implementation. - */ - public String getInfo() { - - return (info); - - } - - - /** - * Perform a shallow copy of the specified Map, and return the result. - * - * @param orig Origin Map to be copied - */ - Map copyMap(Map orig) { - - if (orig == null) - return (new HashMap()); - HashMap dest = new HashMap(); - Iterator keys = orig.keySet().iterator(); - while (keys.hasNext()) { - String key = (String) keys.next(); - dest.put(key, orig.get(key)); - } - return (dest); - - } - - - /** - * Set the context path for this request. - * - * @param contextPath The new context path - */ - void setContextPath(String contextPath) { - - this.contextPath = contextPath; - - } - - - /** - * Set the path information for this request. - * - * @param pathInfo The new path info - */ - void setPathInfo(String pathInfo) { - - this.pathInfo = pathInfo; - - } - - - /** - * Set the query string for this request. - * - * @param queryString The new query string - */ - void setQueryString(String queryString) { - - this.queryString = queryString; - - } - - - /** - * Set the request that we are wrapping. - * - * @param request The new wrapped request - */ - void setRequest(HttpServletRequest request) { - - super.setRequest(request); - - // Initialize the attributes for this request - dispatcherType = request.getAttribute(ServletRequestImpl.DISPATCHER_TYPE_ATTR); - requestDispatcherPath = - request.getAttribute(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR); - - // Initialize the path elements for this request - contextPath = request.getContextPath(); - pathInfo = request.getPathInfo(); - queryString = request.getQueryString(); - requestURI = request.getRequestURI(); - servletPath = request.getServletPath(); - - } - - - /** - * Set the request URI for this request. - * - * @param requestURI The new request URI - */ - void setRequestURI(String requestURI) { - - this.requestURI = requestURI; - - } - - - /** - * Set the servlet path for this request. - * - * @param servletPath The new servlet path - */ - void setServletPath(String servletPath) { - - this.servletPath = servletPath; - - } - - - /** - * Parses the parameters of this request. - * - * If parameters are present in both the query string and the request - * content, they are merged. - */ - void parseParameters() { - - if (parsedParams) { - return; - } - - parameters = new HashMap(); - parameters = copyMap(getRequest().getParameterMap()); - mergeParameters(); - parsedParams = true; - } - - - /** - * Save query parameters for this request. - * - * @param queryString The query string containing parameters for this - * request - */ - void setQueryParams(String queryString) { - this.queryParamString = queryString; - } - - - // ------------------------------------------------------ Protected Methods - - - /** - * Is this attribute name one of the special ones that is added only for - * included servlets? - * - * @param name Attribute name to be tested - */ - protected boolean isSpecial(String name) { - - for (int i = 0; i < specials.length; i++) { - if (specials[i].equals(name)) - return (true); - } - return (false); - - } - - - /** - * Get a special attribute. - * - * @return the special attribute pos, or -1 if it is not a special - * attribute - */ - protected int getSpecial(String name) { - for (int i = 0; i < specials.length; i++) { - if (specials[i].equals(name)) { - return (i); - } - } - return (-1); - } - - - /** - * Set a special attribute. - * - * @return true if the attribute was a special attribute, false otherwise - */ - protected boolean setSpecial(String name, Object value) { - for (int i = 0; i < specials.length; i++) { - if (specials[i].equals(name)) { - specialAttributes[i] = value; - return (true); - } - } - return (false); - } - - - /** - * Remove a special attribute. - * - * @return true if the attribute was a special attribute, false otherwise - */ - protected boolean removeSpecial(String name) { - for (int i = 0; i < specials.length; i++) { - if (specials[i].equals(name)) { - specialAttributes[i] = null; - return (true); - } - } - return (false); - } - - - /** - * Merge the two sets of parameter values into a single String array. - * - * @param values1 First set of values - * @param values2 Second set of values - */ - protected String[] mergeValues(Object values1, Object values2) { - - ArrayList results = new ArrayList(); - - if (values1 == null) - ; - else if (values1 instanceof String) - results.add(values1); - else if (values1 instanceof String[]) { - String values[] = (String[]) values1; - for (int i = 0; i < values.length; i++) - results.add(values[i]); - } else - results.add(values1.toString()); - - if (values2 == null) - ; - else if (values2 instanceof String) - results.add(values2); - else if (values2 instanceof String[]) { - String values[] = (String[]) values2; - for (int i = 0; i < values.length; i++) - results.add(values[i]); - } else - results.add(values2.toString()); - - String values[] = new String[results.size()]; - return ((String[]) results.toArray(values)); - - } - - - // ------------------------------------------------------ Private Methods - - - /** - * Merge the parameters from the saved query parameter string (if any), and - * the parameters already present on this request (if any), such that the - * parameter values from the query string show up first if there are - * duplicate parameter names. - */ - private void mergeParameters() { - - if ((queryParamString == null) || (queryParamString.length() < 1)) - return; - - HashMap queryParameters = new HashMap(); - String encoding = getCharacterEncoding(); - if (encoding == null) - encoding = "ISO-8859-1"; - try { - RequestUtil.parseParameters - (queryParameters, queryParamString, encoding); - } catch (Exception e) { - ; - } - Iterator keys = parameters.keySet().iterator(); - while (keys.hasNext()) { - String key = (String) keys.next(); - Object value = queryParameters.get(key); - if (value == null) { - queryParameters.put(key, parameters.get(key)); - continue; - } - queryParameters.put - (key, mergeValues(value, parameters.get(key))); - } - parameters = queryParameters; - - } - - - // ----------------------------------- AttributeNamesEnumerator Inner Class - - - /** - * Utility class used to expose the special attributes as being available - * as request attributes. - */ - protected class AttributeNamesEnumerator implements Enumeration { - - protected int pos = -1; - protected int last = -1; - protected Enumeration parentEnumeration = null; - protected String next = null; - - public AttributeNamesEnumerator() { - parentEnumeration = getRequest().getAttributeNames(); - for (int i = 0; i < specialAttributes.length; i++) { - if (getAttribute(specials[i]) != null) { - last = i; - } - } - } - - public boolean hasMoreElements() { - return ((pos != last) || (next != null) - || ((next = findNext()) != null)); - } - - public Object nextElement() { - if (pos != last) { - for (int i = pos + 1; i <= last; i++) { - if (getAttribute(specials[i]) != null) { - pos = i; - return (specials[i]); - } - } - } - String result = next; - if (next != null) { - next = findNext(); - } else { - throw new NoSuchElementException(); - } - return result; - } - - protected String findNext() { - String result = null; - while ((result == null) && (parentEnumeration.hasMoreElements())) { - String current = (String) parentEnumeration.nextElement(); - if (!isSpecial(current)) { - result = current; - } - } - return result; - } - - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseImpl.java deleted file mode 100644 index c432361fe..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseImpl.java +++ /dev/null @@ -1,1297 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Locale; -import java.util.TimeZone; -import java.util.Vector; - -import javax.servlet.ServletOutputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.tomcat.lite.http.HttpResponse; -import org.apache.tomcat.lite.http.HttpWriter; -import org.apache.tomcat.lite.http.MultiMap; -import org.apache.tomcat.lite.http.ServerCookie; -import org.apache.tomcat.lite.http.MultiMap.Entry; -import org.apache.tomcat.lite.io.CBuffer; -import org.apache.tomcat.lite.io.FastHttpDateFormat; -import org.apache.tomcat.lite.io.IOWriter; - -/** - * Wrapper object for the Coyote response. - * - * @author Remy Maucherat - * @author Craig R. McClanahan - * @version $Id$ - */ - -public class ServletResponseImpl - implements HttpServletResponse { - - /** - * Format for http response header date field - * From DateTool - */ - public static final String HTTP_RESPONSE_DATE_HEADER = - "EEE, dd MMM yyyy HH:mm:ss zzz"; - - // ----------------------------------------------------------- Constructors - - - // Package - only ServletRequestImpl should call it. - ServletResponseImpl() { - } - - - /** - * The date format we will use for creating date headers. - */ - protected SimpleDateFormat format = null; - - - /** - * The associated output buffer. - */ - protected HttpWriter outputBuffer; - - - /** - * The associated output stream. - */ - protected ServletOutputStreamImpl outputStream; - - - /** - * The associated writer. - */ - protected PrintWriter writer; - - - /** - * The application commit flag. - */ - protected boolean appCommitted = false; - - - /** - * The included flag. - */ - protected boolean included = false; - - - /** - * The characterEncoding flag - */ - private boolean isCharacterEncodingSet = false; - - /** - * The error flag. - */ - protected boolean error = false; - - - /** - * The set of Cookies associated with this Response. - * Only used in facade - base object uses ServerCookie - */ - protected ArrayList cookies = new ArrayList(); - - - /** - * Using output stream flag. - */ - protected boolean usingOutputStream = false; - - - /** - * Using writer flag. - */ - protected boolean usingWriter = false; - - - protected ServletRequestImpl req = null; - - - protected CBuffer tmpUrlBuffer = CBuffer.newInstance(); - - private HttpResponse resB; - - - // Cached/derived information - reflected in headers - protected static Locale DEFAULT_LOCALE = Locale.getDefault(); - - public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1"; - - protected Locale locale = DEFAULT_LOCALE; - - // XXX - protected boolean commited = false; - protected String contentType = null; - - /** - * Has the charset been explicitly set. - */ - protected boolean charsetSet = false; - protected String characterEncoding = DEFAULT_CHARACTER_ENCODING; - - - // --------------------------------------------------------- Public Methods - - /** - * Release all object references, and initialize instance variables, in - * preparation for reuse of this object. - */ - void recycle() { - - usingOutputStream = false; - usingWriter = false; - appCommitted = false; - commited = false; - included = false; - error = false; - isCharacterEncodingSet = false; - - cookies.clear(); - - outputBuffer.recycle(); - - //resB.recycle(); - } - - - // ------------------------------------------------------- Response Methods - - - /** - * Return the number of bytes actually written to the output stream. - */ -// public int getContentCount() { -// return outputBuffer.getBytesWritten() + outputBuffer.getCharsWritten(); -// } - - - /** - * Set the application commit flag. - * - * @param appCommitted The new application committed flag value - */ - public void setAppCommitted(boolean appCommitted) { - this.appCommitted = appCommitted; - } - - -// /** -// * Application commit flag accessor. -// */ -// public boolean isAppCommitted() { -// return (this.appCommitted || isCommitted() || isSuspended() -// || ((getHttpResponse().getContentLength() > 0) -// && (getContentCount() >= getHttpResponse().getContentLength()))); -// } - - - /** - * Return the "processing inside an include" flag. - */ - public boolean getIncluded() { - return included; - } - - - /** - * Set the "processing inside an include" flag. - * - * @param included true if we are currently inside a - * RequestDispatcher.include(), else false - */ - public void setIncluded(boolean included) { - this.included = included; - } - - - /** - * Return the Request with which this Response is associated. - */ - public ServletRequestImpl getRequest() { - return (this.req); - } - - /** - * Set the Request with which this Response is associated. - * - * @param request The new associated request - */ - public void setRequest(ServletRequestImpl request) { - this.req = (ServletRequestImpl) request; - } - - - /** - * Return the output stream associated with this Response. - */ - public OutputStream getStream() { - return outputStream; - } - - - /** - * Set the output stream associated with this Response. - * - * @param stream The new output stream - */ - public void setStream(OutputStream stream) { - // This method is evil - } - - - /** - * Set the suspended flag. - * - * @param suspended The new suspended flag value - */ - public void setSuspended(boolean suspended) throws IOException { - //coyoteResponse.setCommitted(true); - flushBuffer(); - outputBuffer.setSuspended(suspended); - } - - - /** - * Suspended flag accessor. - */ - public boolean isSuspended() { - return outputBuffer.isSuspended(); - } - - - /** - * Set the error flag. - */ - public void setError() { - error = true; - } - - - /** - * Error flag accessor. - */ - public boolean isError() { - return error; - } - - - /** - * Create and return a ServletOutputStream to write the content - * associated with this Response. - * - * @exception IOException if an input/output error occurs - */ - public ServletOutputStream createOutputStream() - throws IOException { - // Probably useless - return outputStream; - } - - /** - * Return the content type that was set or calculated for this response, - * or null if no content type was set. - */ - public String getContentType() { - String ret = contentType; - - if (ret != null - && characterEncoding != null - && charsetSet) { - ret = ret + ";charset=" + characterEncoding; - } - - return ret; - } - - - // ------------------------------------------------ ServletResponse Methods - - - /** - * Flush the buffer and commit this response. - * - * @exception IOException if an input/output error occurs - */ - public void flushBuffer() - throws IOException { - outputBuffer.flush(); - } - - - /** - * Return the actual buffer size used for this Response. - */ - public int getBufferSize() { - return outputBuffer.getBufferSize(); - } - - - /** - * Return the character encoding used for this Response. - */ - public String getCharacterEncoding() { - return characterEncoding; - } - - - /** - * Return the servlet output stream associated with this Response. - * - * @exception IllegalStateException if getWriter has - * already been called for this response - * @exception IOException if an input/output error occurs - */ - public ServletOutputStream getOutputStream() - throws IOException { - - if (usingWriter) - throw new IllegalStateException - ("usingWriter"); - - usingOutputStream = true; - return outputStream; - - } - - public HttpWriter getOutputBuffer() { - return outputBuffer; - } - - - /** - * Return the Locale assigned to this response. - */ - public Locale getLocale() { - return locale; - } - - - /** - * Return the writer associated with this Response. - * - * @exception IllegalStateException if getOutputStream has - * already been called for this response - * @exception IOException if an input/output error occurs - */ - public PrintWriter getWriter() - throws IOException { - - if (usingOutputStream) - throw new IllegalStateException - ("usingOutputStream"); - - /* - * If the response's character encoding has not been specified as - * described in getCharacterEncoding (i.e., the method - * just returns the default value ISO-8859-1), - * getWriter updates it to ISO-8859-1 - * (with the effect that a subsequent call to getContentType() will - * include a charset=ISO-8859-1 component which will also be - * reflected in the Content-Type response header, thereby satisfying - * the Servlet spec requirement that containers must communicate the - * character encoding used for the servlet response's writer to the - * client). - */ - setCharacterEncoding(getCharacterEncoding()); - - usingWriter = true; - // Otherwise it'll be set on first write - encoding - // should be fixed. - outputBuffer.checkConverter(); - - if (writer == null) { - writer = new ServletWriterImpl(outputBuffer); - } - return writer; - - } - - - /** - * Has the output of this response already been committed? - */ - public boolean isCommitted() { - return getHttpResponse().isCommitted(); - } - - /** - * Clear any content written to the buffer. - * - * @exception IllegalStateException if this response has already - * been committed - */ - public void reset() { - - if (included) - return; // Ignore any call from an included servlet - - if (isCommitted()) - throw new IllegalStateException("isCommitted"); - - resB.recycle(); // reset headers, status code, message - //req.getConnector().reset(this); - contentType = null; - locale = DEFAULT_LOCALE; - characterEncoding = DEFAULT_CHARACTER_ENCODING; - charsetSet = false; - - outputBuffer.reset(); - } - - - /** - * Reset the data buffer but not any status or header information. - * - * @exception IllegalStateException if the response has already - * been committed - */ - public void resetBuffer() { - - if (isCommitted()) - throw new IllegalStateException("isCommitted"); - - outputBuffer.reset(); - - } - - - /** - * Set the buffer size to be used for this Response. - * - * @param size The new buffer size - * - * @exception IllegalStateException if this method is called after - * output has been committed for this response - */ - public void setBufferSize(int size) { - - if (isCommitted() || outputBuffer.getWrittenSinceFlush() > 0 || - getHttpResponse().getBodyOutputStream().getWrittenSinceFlush() > 0) - throw new IllegalStateException - ("isCommitted || !isNew"); - - outputBuffer.setBufferSize(size); - - } - - - /** - * Set the content length (in bytes) for this Response. - * Ignored for writers if non-ISO-8859-1 encoding ( we could add more - * encodings that are constant. - */ - public void setContentLength(int length) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - // writers can use variable-length encoding. - if (usingWriter && !"ISO-8859-1".equals(getCharacterEncoding())) { - return; - } - getHttpResponse().setContentLength(length); - - } - - - /** - * Set the content type for this Response. - * - * @param type The new content type - */ - public void setContentType(String type) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - // Ignore charset if getWriter() has already been called - if (usingWriter) { - if (type != null) { - int index = type.indexOf(";"); - if (index != -1) { - type = type.substring(0, index); - } - } - } - - getHttpResponse().setContentType(type); - - // Check to see if content type contains charset - if (type != null) { - int index = type.indexOf(";"); - if (index != -1) { - int len = type.length(); - index++; - while (index < len && Character.isSpace(type.charAt(index))) { - index++; - } - if (index+7 < len - && type.charAt(index) == 'c' - && type.charAt(index+1) == 'h' - && type.charAt(index+2) == 'a' - && type.charAt(index+3) == 'r' - && type.charAt(index+4) == 's' - && type.charAt(index+5) == 'e' - && type.charAt(index+6) == 't' - && type.charAt(index+7) == '=') { - isCharacterEncodingSet = true; - } - } - } - } - - - /* - * Overrides the name of the character encoding used in the body - * of the request. This method must be called prior to reading - * request parameters or reading input using getReader(). - * - * @param charset String containing the name of the chararacter encoding. - */ - public void setCharacterEncoding(String charset) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - // Ignore any call made after the getWriter has been invoked - // The default should be used - if (usingWriter) - return; - - if (isCommitted()) - return; - if (charset == null) - return; - - characterEncoding = charset; - charsetSet=true; - isCharacterEncodingSet = true; - } - - - - /** - * Set the Locale that is appropriate for this response, including - * setting the appropriate character encoding. - * - * @param locale The new locale - */ - public void setLocale(Locale locale) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - if (locale == null) { - return; // throw an exception? - } - - // Save the locale for use by getLocale() - this.locale = locale; - - // Set the contentLanguage for header output - String contentLanguage = locale.getLanguage(); - if ((contentLanguage != null) && (contentLanguage.length() > 0)) { - String country = locale.getCountry(); - StringBuffer value = new StringBuffer(contentLanguage); - if ((country != null) && (country.length() > 0)) { - value.append('-'); - value.append(country); - } - contentLanguage = value.toString(); - } - resB.setHeader("Content-Language", contentLanguage); - - // Ignore any call made after the getWriter has been invoked. - // The default should be used - if (usingWriter) - return; - - if (isCharacterEncodingSet) { - return; - } - - Locale2Charset cm = req.getContext().getCharsetMapper(); - String charset = cm.getCharset( locale ); - if ( charset != null ){ - setCharacterEncoding(charset); - } - - } - - - // --------------------------------------------------- HttpResponse Methods - - - /** - * Return an array of all cookies set for this response, or - * a zero-length array if no cookies have been set. - */ - public Cookie[] getCookies() { - return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()])); - } - - - /** - * Return the value for the specified header, or null if this - * header has not been set. If more than one value was added for this - * name, only the first is returned; use getHeaderValues() to retrieve all - * of them. - * - * @param name Header name to look up - */ - public String getHeader(String name) { - return getHttpResponse().getHeader(name); - } - - - /** - * Return an array of all the header names set for this response, or - * a zero-length array if no headers have been set. - */ - public Collection getHeaderNames() { - return getHttpResponse().getHeaderNames(); - } - - public Collection getHeaders(String name) { - return null; - } - - /** - * Return an array of all the header values associated with the - * specified header name, or an zero-length array if there are no such - * header values. - * - * @param name Header name to look up - */ - public String[] getHeaderValues(String name) { - Entry entry = getHttpResponse().getMimeHeaders().getEntry(name); - if (entry == null) { - return new String[] {}; - } - int size = entry.values.size(); - String[] resultArray = new String[size]; - for (int i = 0; i < size; i++) { - resultArray[i] = entry.values.get(i).getValue().toString(); - } - return resultArray; - - } - - - /** - * Return the error message that was set with sendError() - * for this Response. - */ - public String getMessage() { - return getHttpResponse().getMessage(); - } - - - /** - * Return the HTTP status code associated with this Response. - */ - public int getStatus() { - return getHttpResponse().getStatus(); - } - - - /** - * Reset this response, and specify the values for the HTTP status code - * and corresponding message. - * - * @exception IllegalStateException if this response has already been - * committed - */ - public void reset(int status, String message) { - reset(); - setStatus(status, message); - } - - - // -------------------------------------------- HttpServletResponse Methods - - - /** - * Add the specified Cookie to those that will be included with - * this Response. - * - * @param cookie Cookie to be added - */ - public void addCookie(final Cookie cookie) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - cookies.add(cookie); - - final StringBuffer sb = new StringBuffer(); - ServerCookie.appendCookieValue - (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(), - cookie.getPath(), cookie.getDomain(), cookie.getComment(), - cookie.getMaxAge(), cookie.getSecure(), false); - - // the header name is Set-Cookie for both "old" and v.1 ( RFC2109 ) - // RFC2965 is not supported by browsers and the Servlet spec - // asks for 2109. - addHeader("Set-Cookie", sb.toString()); - - } - - - /** - * Add the specified date header to the specified value. - * - * @param name Name of the header to set - * @param value Date value to be set - */ - public void addDateHeader(String name, long value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) { - return; - } - - if (format == null) { - format = new SimpleDateFormat(HTTP_RESPONSE_DATE_HEADER, - Locale.US); - format.setTimeZone(TimeZone.getTimeZone("GMT")); - } - - addHeader(name, FastHttpDateFormat.formatDate(value, format)); - - } - - - /** - * Add the specified header to the specified value. - * - * @param name Name of the header to set - * @param value Value to be set - */ - public void addHeader(String name, String value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - getHttpResponse().addHeader(name, value); - - } - - - /** - * Add the specified integer header to the specified value. - * - * @param name Name of the header to set - * @param value Integer value to be set - */ - public void addIntHeader(String name, int value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - addHeader(name, "" + value); - - } - - - /** - * Has the specified header been set already in this response? - * - * @param name Name of the header to check - */ - public boolean containsHeader(String name) { - // Need special handling for Content-Type and Content-Length due to - // special handling of these in coyoteResponse - char cc=name.charAt(0); - if(cc=='C' || cc=='c') { - if(name.equalsIgnoreCase("Content-Type")) { - // Will return null if this has not been set - return getContentType() != null; - } - if(name.equalsIgnoreCase("Content-Length")) { - // -1 means not known and is not sent to client - return (getHttpResponse().getContentLength() != -1); - } - } - - return getHttpResponse().containsHeader(name); - } - - - /** - * Encode the session identifier associated with this response - * into the specified redirect URL, if necessary. - * - * @param url URL to be encoded - */ - public String encodeRedirectURL(String url) { - req.getHttpRequest().toAbsolute(url, tmpUrlBuffer); - if (isEncodeable(tmpUrlBuffer.toString())) { - return (appendSessionId(url, req.getSession().getId())); - } else { - return (url); - } - - } - - - /** - * Encode the session identifier associated with this response - * into the specified redirect URL, if necessary. - * - * @param url URL to be encoded - * - * @deprecated As of Version 2.1 of the Java Servlet API, use - * encodeRedirectURL() instead. - */ - public String encodeRedirectUrl(String url) { - return (encodeRedirectURL(url)); - } - - - /** - * Encode the session identifier associated with this response - * into the specified URL, if necessary. - * - * @param url URL to be encoded - */ - public String encodeURL(String url) { - req.getHttpRequest().toAbsolute(url, tmpUrlBuffer); - String absolute = tmpUrlBuffer.toString(); - if (isEncodeable(absolute)) { - // W3c spec clearly said - if (url.equalsIgnoreCase("")){ - url = absolute; - } - return (appendSessionId(url, req.getSession().getId())); - } else { - return (url); - } - - } - - - /** - * Encode the session identifier associated with this response - * into the specified URL, if necessary. - * - * @param url URL to be encoded - * - * @deprecated As of Version 2.1 of the Java Servlet API, use - * encodeURL() instead. - */ - public String encodeUrl(String url) { - return (encodeURL(url)); - } - - - /** - * Send an error response with the specified status and a - * default message. - * - * @param status HTTP status code to send - * - * @exception IllegalStateException if this response has - * already been committed - * @exception IOException if an input/output error occurs - */ - public void sendError(int status) - throws IOException { - sendError(status, null); - } - - - /** - * Send an error response with the specified status and message. - * - * @param status HTTP status code to send - * @param message Corresponding message to send - * - * @exception IllegalStateException if this response has - * already been committed - * @exception IOException if an input/output error occurs - */ - public void sendError(int status, String message) - throws IOException { - - if (isCommitted()) - throw new IllegalStateException - ("isCommitted"); - - // Ignore any call from an included servlet - if (included) - return; - - setError(); - - getHttpResponse().setStatus(status); - getHttpResponse().setMessage(message); - - // Clear any data content that has been buffered - resetBuffer(); - - // Cause the response to be finished (from the application perspective) - String statusPage = req.getContext().findStatusPage(status); - - if (statusPage != null) { - req.getContext().handleStatusPage(req, this, status, statusPage); - } else { - // Send a default message body. - // TODO: maybe other mechanism to customize default. - defaultStatusPage(status, message); - } - setSuspended(true); - } - - /** - * Default handler for status code != 200 - */ - void defaultStatusPage(int status, String message) - throws IOException { - setContentType("text/html"); - if (status > 400 && status < 600) { - if (!getHttpResponse().isCommitted()) { - resetBuffer(); - getOutputBuffer().write("

Status: " + - status + "

Message: " + message + - "

"); - getOutputBuffer().flush(); - } - } - } - - - - /** - * Send a temporary redirect to the specified redirect location URL. - * - * @param location Location URL to redirect to - * - * @exception IllegalStateException if this response has - * already been committed - * @exception IOException if an input/output error occurs - */ - public void sendRedirect(String location) - throws IOException { - - if (isCommitted()) - throw new IllegalStateException - ("isCommitted"); - - // Ignore any call from an included servlet - if (included) - return; - - // Clear any data content that has been buffered - resetBuffer(); - - // Generate a temporary redirect to the specified location - try { - req.getHttpRequest().toAbsolute(location, tmpUrlBuffer); - setStatus(SC_FOUND); - resB.getMimeHeaders().setValue("Location").set(tmpUrlBuffer); - } catch (IllegalArgumentException e) { - setStatus(SC_NOT_FOUND); - } - - // Cause the response to be finished (from the application perspective) - setSuspended(true); - - } - - - /** - * Set the specified date header to the specified value. - * - * @param name Name of the header to set - * @param value Date value to be set - */ - public void setDateHeader(String name, long value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) { - return; - } - - if (format == null) { - format = new SimpleDateFormat(HTTP_RESPONSE_DATE_HEADER, - Locale.US); - format.setTimeZone(TimeZone.getTimeZone("GMT")); - } - - setHeader(name, FastHttpDateFormat.formatDate(value, format)); - - } - - - /** - * Set the specified header to the specified value. - * - * @param name Name of the header to set - * @param value Value to be set - */ - public void setHeader(String name, String value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - getHttpResponse().setHeader(name, value); - - } - - - /** - * Set the specified integer header to the specified value. - * - * @param name Name of the header to set - * @param value Integer value to be set - */ - public void setIntHeader(String name, int value) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - setHeader(name, "" + value); - - } - - - /** - * Set the HTTP status to be returned with this response. - * - * @param status The new HTTP status - */ - public void setStatus(int status) { - setStatus(status, null); - } - - - /** - * Set the HTTP status and message to be returned with this response. - * - * @param status The new HTTP status - * @param message The associated text message - * - * @deprecated As of Version 2.1 of the Java Servlet API, this method - * has been deprecated due to the ambiguous meaning of the message - * parameter. - */ - public void setStatus(int status, String message) { - - if (isCommitted()) - return; - - // Ignore any call from an included servlet - if (included) - return; - - getHttpResponse().setStatus(status); - getHttpResponse().setMessage(message); - - } - - - // ------------------------------------------------------ Protected Methods - - - /** - * Return true if the specified URL should be encoded with - * a session identifier. This will be true if all of the following - * conditions are met: - *
    - *
  • The request we are responding to asked for a valid session - *
  • The requested session ID was not received via a cookie - *
  • The specified URL points back to somewhere within the web - * application that is responding to this request - *
- * - * @param location Absolute URL to be validated - */ - protected boolean isEncodeable(final String location) { - - if (location == null) - return (false); - - // Is this an intra-document reference? - if (location.startsWith("#")) - return (false); - - // Are we in a valid session that is not using cookies? - final ServletRequestImpl hreq = req; - final HttpSession session = hreq.getSession(false); - if (session == null) - return (false); - if (hreq.isRequestedSessionIdFromCookie()) - return (false); - - // Is this a valid absolute URL? - URL url = null; - try { - url = new URL(location); - } catch (MalformedURLException e) { - return (false); - } - - // Does this URL match down to (and including) the context path? - if (!hreq.getScheme().equalsIgnoreCase(url.getProtocol())) - return (false); - if (!hreq.getServerName().equalsIgnoreCase(url.getHost())) - return (false); - int serverPort = hreq.getServerPort(); - if (serverPort == -1) { - if ("https".equals(hreq.getScheme())) - serverPort = 443; - else - serverPort = 80; - } - int urlPort = url.getPort(); - if (urlPort == -1) { - if ("https".equals(url.getProtocol())) - urlPort = 443; - else - urlPort = 80; - } - if (serverPort != urlPort) - return (false); - - String contextPath = req.getContext().getContextPath(); - if (contextPath != null) { - String file = url.getFile(); - if ((file == null) || !file.startsWith(contextPath)) - return (false); - if( file.indexOf(";jsessionid=" + session.getId()) >= 0 ) - return (false); - } - - // This URL belongs to our web application, so it is encodeable - return (true); - - } - - - - /** - * Return the specified URL with the specified session identifier - * suitably encoded. - * - * @param url URL to be encoded with the session id - * @param sessionId Session id to be included in the encoded URL - */ - protected String appendSessionId(String url, String sessionId) { - - if ((url == null) || (sessionId == null)) - return (url); - - String path = url; - String query = ""; - String anchor = ""; - int question = url.indexOf('?'); - if (question >= 0) { - path = url.substring(0, question); - query = url.substring(question); - } - int pound = path.indexOf('#'); - if (pound >= 0) { - anchor = path.substring(pound); - path = path.substring(0, pound); - } - StringBuffer sb = new StringBuffer(path); - if( sb.length() > 0 ) { // jsessionid can't be first. - sb.append(";jsessionid="); - sb.append(sessionId); - } - sb.append(anchor); - sb.append(query); - return (sb.toString()); - - } - - public HttpResponse getHttpResponse() { - return resB; - } - - - void setHttpResponse(HttpResponse resB) { - this.resB = resB; - outputBuffer = resB.getBodyWriter(); - outputStream = new ServletOutputStreamImpl(resB.getBodyOutputStream()); - } - - - -} - diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseIncludeWrapper.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseIncludeWrapper.java deleted file mode 100644 index 02be62e70..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletResponseIncludeWrapper.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.IOException; -import java.util.Locale; - -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - - -/** - * Wrapper around the response object received as parameter to - * RequestDispatcher.include(). - * - * @author Costin Manolache - */ -public class ServletResponseIncludeWrapper extends HttpServletResponseWrapper { - public ServletResponseIncludeWrapper(ServletResponse current) { - super((HttpServletResponse) current); - } - - // Not overriden: - /* - public boolean containsHeader(String name) - public String encodeRedirectUrl(String url) - public String encodeRedirectURL(String url) - public String encodeUrl(String url) - public String encodeURL(String url) - public void flushBuffer() throws IOException - public int getBufferSize() - public String getCharacterEncoding() - public String getContentType() - public Locale getLocale() - public ServletOutputStream getOutputStream() throws IOException - public ServletResponse getResponse() - public PrintWriter getWriter() throws IOException - public boolean isCommitted() - public void resetBuffer() - public void setCharacterEncoding(String charset) - public void setResponse(ServletResponse response) - */ - - public void reset() { - if (getResponse().isCommitted()) - getResponse().reset(); - else - throw new IllegalStateException(); - } - - public void setContentLength(int len) { - } - - public void setContentType(String type) { - } - - public void setLocale(Locale loc) { - } - - public void setBufferSize(int size) { - } - - public void addCookie(Cookie cookie) { - } - - public void addDateHeader(String name, long value) { - } - - public void addHeader(String name, String value) { - } - - public void addIntHeader(String name, int value) { - } - - public void sendError(int sc) throws IOException { - } - - public void sendError(int sc, String msg) throws IOException { - } - - public void sendRedirect(String location) throws IOException { - } - - public void setDateHeader(String name, long value) { - } - - public void setHeader(String name, String value) { - } - - public void setIntHeader(String name, int value) { - } - - public void setStatus(int sc) { - } - - public void setStatus(int sc, String msg) { - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletWriterImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletWriterImpl.java deleted file mode 100644 index c74d24e42..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/ServletWriterImpl.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; - -/** - * Coyote implementation of the servlet writer. - * - * @author Remy Maucherat - */ -public class ServletWriterImpl - extends PrintWriter { - - - // -------------------------------------------------------------- Constants - - - private static final char[] LINE_SEP = { '\r', '\n' }; - - - // ----------------------------------------------------- Instance Variables - - - protected Writer ob; - protected boolean error = false; - - - // ----------------------------------------------------------- Constructors - - - public ServletWriterImpl(Writer ob) { - super(ob); - this.ob = ob; - } - - - // --------------------------------------------------------- Public Methods - - - /** - * Prevent cloning the facade. - */ - protected Object clone() - throws CloneNotSupportedException { - throw new CloneNotSupportedException(); - } - - - // -------------------------------------------------------- Package Methods - - - /** - * Clear facade. - */ - void clear() { - ob = null; - } - - - /** - * Recycle. - */ - void recycle() { - error = false; - } - - - // --------------------------------------------------------- Writer Methods - - - public void flush() { - - if (error) - return; - - try { - ob.flush(); - } catch (IOException e) { - error = true; - } - - } - - - public void close() { - - // We don't close the PrintWriter - super() is not called, - // so the stream can be reused. We close ob. - try { - ob.close(); - } catch (IOException ex ) { - ; - } - error = false; - - } - - - public boolean checkError() { - flush(); - return error; - } - - - public void write(int c) { - - if (error) - return; - - try { - ob.write(c); - } catch (IOException e) { - error = true; - } - - } - - - public void write(char buf[], int off, int len) { - - if (error) - return; - - try { - ob.write(buf, off, len); - } catch (IOException e) { - error = true; - } - - } - - - public void write(char buf[]) { - write(buf, 0, buf.length); - } - - - public void write(String s, int off, int len) { - - if (error) - return; - - try { - ob.write(s, off, len); - } catch (IOException e) { - error = true; - } - - } - - - public void write(String s) { - write(s, 0, s.length()); - } - - - // ---------------------------------------------------- PrintWriter Methods - - - public void print(boolean b) { - if (b) { - write("true"); - } else { - write("false"); - } - } - - - public void print(char c) { - write(c); - } - - - public void print(int i) { - write(String.valueOf(i)); - } - - - public void print(long l) { - write(String.valueOf(l)); - } - - - public void print(float f) { - write(String.valueOf(f)); - } - - - public void print(double d) { - write(String.valueOf(d)); - } - - - public void print(char s[]) { - write(s); - } - - - public void print(String s) { - if (s == null) { - s = "null"; - } - write(s); - } - - - public void print(Object obj) { - write(String.valueOf(obj)); - } - - - public void println() { - write(LINE_SEP); - } - - - public void println(boolean b) { - print(b); - println(); - } - - - public void println(char c) { - print(c); - println(); - } - - - public void println(int i) { - print(i); - println(); - } - - - public void println(long l) { - print(l); - println(); - } - - - public void println(float f) { - print(f); - println(); - } - - - public void println(double d) { - print(d); - println(); - } - - - public void println(char c[]) { - print(c); - println(); - } - - - public void println(String s) { - print(s); - println(); - } - - - public void println(Object o) { - print(o); - println(); - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/TomcatLite.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/TomcatLite.java deleted file mode 100644 index 933bdb7d5..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/TomcatLite.java +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -import org.apache.tomcat.integration.ObjectManager; -import org.apache.tomcat.integration.simple.SimpleObjectManager; -import org.apache.tomcat.lite.http.DefaultHttpConnector; -import org.apache.tomcat.lite.http.Dispatcher; -import org.apache.tomcat.lite.http.HttpChannel; -import org.apache.tomcat.lite.http.HttpConnector; -import org.apache.tomcat.lite.http.HttpRequest; -import org.apache.tomcat.lite.http.HttpResponse; -import org.apache.tomcat.lite.http.MappingData; -import org.apache.tomcat.lite.http.HttpChannel.HttpService; -import org.apache.tomcat.lite.io.CBuffer; -import org.apache.tomcat.lite.io.MemoryIOConnector; -import org.apache.tomcat.lite.io.WrappedException; - -/** - * Helper allowing to run servlets using Tomcat lite http server. - * - * This is not a full servlet engine - just a small subset allowing - * easier transition or reuse. - * - * @author Costin Manolache - */ -public class TomcatLite implements Runnable { - - static ServletApi api = ServletApi.get(); - - private String serverDirName; - private File workDir; - - // all contexts - hostMapper knows about hostnames and how they are mapped. - // this shouldn't be needed if we want to delegate ctx management - private ArrayList contexts = new ArrayList(); - - URLClassLoader contextParentLoader; - Logger log = Logger.getLogger("TomcatLite"); - //BaseMapper hostMapper = new BaseMapper(); - - // Servlets to preload in each context, configurable from CLI or API - Map preloadServlets = new HashMap(); - Map preloadMappings = new HashMap(); - - Map ctxDefaultInitParam = new HashMap(); - - ObjectManager om; - - private HttpConnector httpConnector; - - static String SERVLETS_PACKAGE = "org.apache.tomcat.servlets"; - - // can be set to ConfigLoader to skip auto-parsing web.xml - private String deployListener = - "org.apache.tomcat.servlets.config.deploy.WarDeploy"; - - int port = 8080; - - public TomcatLite() { - } - - public TomcatLite(ObjectManager om) { - this.setObjectManager(om); - } - - // --------------- start/stop --------------- - - public static ObjectManager defaultObjectManager() { - SimpleObjectManager cfg = new SimpleObjectManager(); - return cfg; - } - /** - * Return the object manager associated with this tomcat. - * If none set, create a minimal one with the default - * values. - */ - public ObjectManager getObjectManager() { - if (om == null) { - om = defaultObjectManager(); - om.bind("TomcatLite", this); - } - return om; - } - - public void setObjectManager(ObjectManager om) { - this.om = om; - } - - public void setPort(int port) { - this.port = port; - } - - public List/**/ getWebapps() { - return contexts; - } - - public URLClassLoader getContextParentLoader() { - if (contextParentLoader == null) { - - ClassLoader parent = this.getClass().getClassLoader(); - contextParentLoader = new URLClassLoader(new URL[] {}, - parent); - - /*if (engineRepo == null) { - engineRepo = new Repository(); - engineRepo.setParentClassLoader(parent); - } - - contextParentLoader = - engineRepo.getClassLoader(); - */ - } - return contextParentLoader; - } - - public void start() throws IOException { - long t0 = System.currentTimeMillis(); - - // start all contexts - // init all contexts - Iterator i1 = contexts.iterator(); - while (i1.hasNext()) { - ServletContextImpl ctx = (ServletContextImpl) i1.next(); - try { - ctx.start(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - long t1 = System.currentTimeMillis(); - log.fine("Engine.start() " + (t1-t0)); - } - - - /** - * Add a context - used for IntrospectionUtils. - * - * ContextPath:ContextBaseDir - */ - public void setContext(String c) throws ServletException { - String[] pathDir = c.split(":", 2); - String base = pathDir[0].trim(); - if (base.length() == 0) { - addServletContext("", pathDir[1], null); - } else { - addServletContext("", pathDir[1], base); - } - } - - public void setServletContexts(List c) throws ServletException { - for (ServletContext ctx: c) { - addServletContext((ServletContextImpl) ctx); - } - } - - public void setDeployListener(String deploy) { - this.deployListener = deploy; - } - - public String getDeployListener() { - return deployListener; - } - - public void setPreload(String servletNameClass) { - String[] nv = servletNameClass.split(":"); - preloadServlets.put(nv[0], nv[1]); - } - - public void addPreload(String servletName, String servletClassName) { - preloadServlets.put(servletName, servletClassName); - } - - public void setDefaultInitParam(String nameValue) { - String[] nv = nameValue.split(":"); - ctxDefaultInitParam.put(nv[0], nv[1]); - } - - public void addDefaultInitParam(String name, String value) { - ctxDefaultInitParam.put(name, value); - } - - public void setPreloadMappings(String servletPath) { - String[] nv = servletPath.split(":"); - preloadMappings.put(nv[0], nv[1]); - } - - public void addPreloadMapping(String servletName, String path) { - preloadMappings.put(servletName, path); - } - - public void stop() { - Iterator i1 = contexts.iterator(); - while (i1.hasNext()) { - ServletContextImpl ctx = (ServletContextImpl) i1.next(); - try { - ctx.destroy(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - try { - stopConnector(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - // -------------- Context add/remove -------------- - - public static String[] DEFAULT_WELCOME = { "index.html" }; - - public void addServletContext(ServletContextImpl ctx) throws ServletException { - ctx.setTomcat(this); - - getDispatcher().addContext(ctx.getHostname(), - ctx.getContextPath(), ctx, null, null, ctxService); - - contexts.add(ctx); - - getObjectManager().bind("ServletContext:" + - ctx.getHostname() + ctx.getContextPath(), - ctx); - - } - - /** - * Add a context. - * - * web.xml will be read as part of init, and the initialization will be - * part of start or lazy. - * - * @param hostname - "" - * if default host, or string to be matched with Host header - * @param basePath = directory where the webapp is installed - * @param path - - * context path, "/" for root, "/examples", etc - * @return a servlet context - * @throws ServletException - */ - public ServletContextImpl addServletContext(String hostname, - String basePath, - String path) - throws ServletException - { - ServletContextImpl ctx = api.newContext(); - ctx.setContextPath(path); - ctx.setBasePath(basePath); - addServletContext(ctx); - return ctx; - } - - public static ServletRequestImpl getFacade(HttpRequest req) { - ServletRequestImpl sreq = (ServletRequestImpl) req.wrapperRequest; - if (sreq == null) { - sreq = api.newRequest(req); - req.wrapperRequest = sreq; - req.nativeRequest = req.getHttpChannel(); // TODO ? - - sreq.getResponse().setHttpResponse(req.getHttpChannel().getResponse()); - } - return sreq; - } - - public void removeServletContext(ServletContext sctx) - throws ServletException - { - ServletContextImpl ctx = (ServletContextImpl) sctx; - // TODO: destroy all servlets and filters - // TODO: clean up any other reference to the context or its loader - notifyRemove(ctx); - } - - public Dispatcher getDispatcher() { - return getHttpConnector().getDispatcher(); - } - - /** - * Required for ServletContext.getContext(uri); - * @throws ServletException - * @throws IOException - */ - public ServletContextImpl getContext(ServletContextImpl impl, String uri) - throws IOException, ServletException { - MappingData md = new MappingData(); - CBuffer hostMB = CBuffer.newInstance(); - CBuffer urlMB = CBuffer.newInstance(); - hostMB.set(impl.getHostname()); - urlMB.set(uri); - getDispatcher().map(hostMB, urlMB, md); - return (ServletContextImpl) md.context; - } - - HttpService ctxService = new HttpService() { - - @Override - public void service(HttpRequest httpReq, HttpResponse httpRes) - throws IOException { - HttpChannel client = httpReq.getHttpChannel(); - - ServletRequestImpl req = getFacade(client.getRequest()); - ServletResponseImpl res = req.getResponse(); - - try { - TomcatLite.this.service(req, res); - - - if (!req.isAsyncStarted()) { - // Recycle the facade objects - - // low level recycled by connector - - // Not an actual flush - only goes to next - res.getOutputBuffer().push(); - - req.recycle(); - } - } catch (IOException ex) { - throw ex; - } catch (Throwable t) { - throw new WrappedException(t); - } - } - }; - - /** - * Service a request. - * The response is not flushed, and we don't recycle at the end. - */ - public void service(ServletRequestImpl req, ServletResponseImpl res) - throws Exception, IOException { - - // TODO: move later - req.parseSessionId(); - - MappingData mapRes = req.getMappingData(); - ServletContextImpl ctx = (ServletContextImpl)mapRes.context; - try { - // context wrapper; - mapRes.service = null; - - getDispatcher().map(ctx.getContextMap(), req.getHttpRequest().decodedURI(), mapRes); - - // Possible redirect - CBuffer redirectPathMB = mapRes.redirectPath; - if (redirectPathMB.length() != 0) { - CBuffer redirectPath = CBuffer.newInstance(); - req.getHttpRequest().getUrlEncoding() - .urlEncode(redirectPathMB, - redirectPath, req.getHttpRequest().getCharEncoder()); - - String query = req.getQueryString(); - if (req.isRequestedSessionIdFromURL()) { - // This is not optimal, but as this is not very common, it - // shouldn't matter - redirectPath.append(";") - .append(ServletRequestImpl.SESSION_PARAMETER_NAME) - .append("=") - .append(req.getRequestedSessionId()); - } - if (query != null) { - // This is not optimal, but as this is not very common, it - // shouldn't matter - redirectPath.append("?").append(query); - } - res.sendRedirect(redirectPath.toString()); - return; - } - - req.setContext(ctx); - req.parseSessionCookiesId(); - - // bind class loader - Thread.currentThread().setContextClassLoader(ctx.getClassLoader()); - - ServletConfigImpl h = (ServletConfigImpl) mapRes.getServiceObject(); - if (h != null) { - req.setWrapper((ServletConfigImpl)mapRes.getServiceObject()); - h.serviceServlet(ctx, req, res, h, mapRes ); - } - } catch (Throwable t) { - log.log(Level.INFO, ctx.contextPath + ": " + req.getRequest() + - ": User exception in servlet ", t); - } finally { - if(mapRes != null ) - mapRes.recycle(); - } - } - - - // ------------ Notifications for JMX ---------------- - - void notifyAdd(Object o) { - } - - void notifyRemove(Object o) { - } - - public void setServerDir(String dir) { - this.serverDirName = dir; - } - - public File getWork() { - if (workDir == null) { - if (serverDirName == null) { - serverDirName = "./"; - } - File rootDirFile = new File(serverDirName); - workDir = new File(rootDirFile, "tomcat-work"); - if (workDir.exists()) { - workDir.mkdirs(); - } - } - return workDir; - } - - /** - * Load all context configs, loads the connector - * - * @throws ServletException - * @throws IOException - */ - public void init() throws ServletException, IOException { - if (contexts.size() == 0) { - setContext("/:./webapps/ROOT"); - } - Iterator i1 = contexts.iterator(); - while (i1.hasNext()) { - ServletContextImpl ctx = (ServletContextImpl) i1.next(); - try { - ctx.loadConfig(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - public void startConnector() throws IOException { - getHttpConnector().setPort(port); - getHttpConnector().start(); - } - - public void stopConnector() throws Exception { - getHttpConnector().stop(); - } - - public void run() { - try { - execute(); - } catch (ServletException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void execute() throws ServletException, IOException { - init(); - start(); - startConnector(); - } - - void setHttpConnector(HttpConnector httpConnector) { - this.httpConnector = httpConnector; - } - - public HttpConnector getHttpConnector() { - if (httpConnector == null) { - httpConnector = DefaultHttpConnector.get(); - } - return httpConnector; - } - - HttpConnector local; - - public HttpConnector getLocalConnector() { - if (local == null) { - local = new HttpConnector(new MemoryIOConnector()); - } - return local; - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/WebappFilterMapper.java b/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/WebappFilterMapper.java deleted file mode 100644 index 9fcfc7314..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/lite/servlet/WebappFilterMapper.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.apache.tomcat.lite.util.URLEncoder; -import org.apache.tomcat.servlets.util.RequestUtil; - -/** - * First filter after the context and servlet are mapped. It will add - * web.xml-defined filters. - * - * costin: This is another mapping - done in RequestDispatcher or initial - * mapping. - * Also: StandardHostValve - sets attribute for error pages, - * StandardWrapperValve - mapping per invocation - * - * @author Greg Murray - * @author Remy Maucherat - */ -public class WebappFilterMapper implements Filter { - - - // -------------------------------------------------------------- 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"; - - - // ----------------------------------------------------------- Constructors - ServletContextImpl servletContext; - - public WebappFilterMapper() { - } - - public WebappFilterMapper(ServletContextImpl impl) { - servletContext = impl; - } - - public void setServletContext(ServletContextImpl sc) { - servletContext = sc; - } - - // --------------------------------------------------------- Public Methods - - ArrayList filterMaps = new ArrayList(); - - public void addMapping(String filterName, - String url, - String servletName, - String type[], boolean isMatchAfter) { - FilterMap map = new FilterMap(); - map.setURLPattern(url); - map.setFilterName(filterName); - map.setServletName(servletName); - if (isMatchAfter) { - filterMaps.add(map); - } else { - filterMaps.add(0, map); - } - } - - /** - * 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) { - - // If there is no servlet to execute, return null - if (servlet == null) - return (null); - - // 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; - - // Create and initialize a filter chain object - FilterChainImpl filterChain = null; - if ((request instanceof ServletRequestImpl)) { - ServletRequestImpl req = (ServletRequestImpl) request; - filterChain = (FilterChainImpl) req.getFilterChain(); - filterChain.release(); - } else { - // Security: Do not recycle - filterChain = new FilterChainImpl(); - } - - filterChain.setServlet(wrapper, servlet); - - // If there are no filter mappings, we are done - if ((filterMaps.size() == 0)) - return (filterChain); - - // Acquire the information we will need to match filter mappings - String servletName = wrapper.getServletName(); - - int n = 0; - - // TODO(costin): optimize: separate in 2 lists, one for url-mapped, one for - // servlet-name. Maybe even separate list for dispatcher and - // non-dispatcher - - // TODO(costin): optimize: set the FilterConfig in the FilterMap, to - // avoid second hash lookup - - // Add the relevant path-mapped filters to this filter chain - for (int i = 0; i < filterMaps.size(); i++) { - FilterMap filterMap = (FilterMap)filterMaps.get(i); - if (!matchDispatcher(filterMap ,dispatcher)) { - continue; - } - if (!matchFiltersURL(filterMap, requestPath)) - continue; - FilterConfigImpl filterConfig = - servletContext.getFilter(filterMap.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.size(); i++) { - FilterMap filterMap = (FilterMap)filterMaps.get(i); - if (!matchDispatcher(filterMap ,dispatcher)) { - continue; - } - if (!matchFiltersServlet(filterMap, servletName)) - continue; - FilterConfigImpl filterConfig = - servletContext.getFilter(filterMap.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; - } - - - // -------------------- Map elements ----------------------- - - public static 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; - - /** - * The URL pattern this mapping matches. - */ - private String urlPattern = null; - - /** - * The servlet name this mapping matches. - */ - private String servletName = null; - - - - public String getFilterName() { - return (this.filterName); - } - - public void setFilterName(String filterName) { - this.filterName = filterName; - } - - - public String getServletName() { - return (this.servletName); - } - - public void setServletName(String servletName) { - this.servletName = servletName; - } - - - public String getURLPattern() { - return (this.urlPattern); - } - - public void setURLPattern(String urlPattern) { - this.urlPattern = URLEncoder.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 void init(FilterConfig filterConfig) throws ServletException { - } - - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) - throws IOException, ServletException { - } - - - public void destroy() { - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ConfigLoader.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ConfigLoader.java deleted file mode 100644 index b35666878..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ConfigLoader.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.config; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; - -public class ConfigLoader { - - public ServletContextConfig loadConfig(String basePath) { - - - String fileName = basePath + ServletContextConfig.SERIALIZED_PATH; - File f = new File(fileName); - if (f.exists()) { - ServletContextConfig contextConfig = new ServletContextConfig(); - try { - ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f)); - contextConfig = (ServletContextConfig) ois.readObject(); - return contextConfig; - } catch (Throwable e) { - System.err.println("Ignoring invalid .ser config " + e); - // ignore - } - } - - return null; - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ServletContextConfig.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ServletContextConfig.java deleted file mode 100644 index 3b056e275..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/ServletContextConfig.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * - */ -package org.apache.tomcat.servlets.config; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Struct representation of webapp configuration. - * - * All the data in web.xml, annotations, etc should be represented - * here. This class is serializable - but can be saved/loaded as - * json or any 'pojo' persistence. - * - * - * Public fields to make it easy to access it, we can add accessors. - * Naming should match the web.xml element name. - * - * @author Costin Manolache - */ -public class ServletContextConfig implements Serializable { - - public static final String SERIALIZED_PATH = "/WEB-INF/deploy_web.ser"; - private static final long serialVersionUID = 1728492145981883124L; - - public static final int CURRENT_VERSION = 1; - - public int version = CURRENT_VERSION; - - /** - * Main config ( web.xml ) path and timestamp - touch it to reload. - */ - public List fileName = new ArrayList(); - public long timestamp; - - public boolean full; - - public String displayName; - - public HashMap contextParam = new HashMap(); - - public HashMap mimeMapping = new HashMap(); // extension -> mime-type - - public ArrayList listenerClass = new ArrayList(); - - public ArrayList welcomeFileList = new ArrayList(); - - // code -> location - public HashMap errorPageCode= new HashMap(); - - // exception -> location - public HashMap errorPageException= new HashMap(); - - public HashMap localeEncodingMapping= new HashMap(); // locale -> encoding - - // public HashMap tagLibs; // uri->location - // jsp-property-group - - // securityConstraint - public ArrayList securityConstraint = new ArrayList(); - - // loginConfig - public String authMethod; - public String realmName; - public String formLoginPage; - public String formErrorPage; - - public ArrayList securityRole = new ArrayList(); - - // envEntry - public ArrayList envEntry = new ArrayList(); - - // ejbRef - // ejbLocalRef - // serviceRef - // resourceRef - // resourceEnvRef - // message-destination - // message-destinationRef - public HashMap filters = new HashMap(); - public HashMap servlets = new HashMap(); - - public int sessionTimeout; - public boolean distributable; - - public HashMap servletMapping = new HashMap(); // url -> servlet - public ArrayList filterMappings = new ArrayList(); - public boolean metadataComplete = false; - - - // Normalized - public static class FilterMappingData implements Serializable { - private static final long serialVersionUID = -4533568066713041994L; - public String filterName; - - // Only one of the 2 - public String urlPattern; - public String servletName; - - // REQUEST, FORWARD, INCLUDE, ERROR, ASYNC - public List dispatcher = new ArrayList(); - } - - public static class EnvEntryData implements Serializable { - private static final long serialVersionUID = 7023847615343715257L; - public String envEntryName; - public String envEntryType; - public String envEntryValue; - } - - public static class ServiceData implements Serializable { - public String name; - public String className; - - public Map initParams = new HashMap(); - - public boolean asyncSupported = false; - } - - public static class FilterData extends ServiceData implements Serializable { - private static final long serialVersionUID = -535820271746973166L; - } - - public static class ServletData extends ServiceData implements Serializable { - private static final long serialVersionUID = -3216904178501185930L; - - public ServletData() { - } - public ServletData(String servletName, String servletClass) { - this.className = servletClass; - this.name = servletName; - } - - public String jspFile; - public int loadOnStartup = -1; - public String runAs; - public Map securityRoleRef = new HashMap(); // roleName -> [roleLink] - public boolean multipartConfig = false; - - public List declaresRoles = new ArrayList(); - - } - - public static class WebResourceCollectionData implements Serializable { - public String webResourceName; - public ArrayList urlPattern = new ArrayList(); - public ArrayList httpMethod = new ArrayList(); - } - - public static class SecurityConstraintData implements Serializable { - private static final long serialVersionUID = -4780214921810871769L; - - public ArrayList roleName = new ArrayList(); // auth-constraint/role - - public ArrayList webResourceCollection = - new ArrayList(); - public String transportGuarantee; - - } -} \ No newline at end of file diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/AnnotationsProcessor.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/AnnotationsProcessor.java deleted file mode 100644 index 86b0e4dce..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/AnnotationsProcessor.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.config.deploy; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import org.apache.tomcat.servlets.config.ServletContextConfig; -import org.apache.tomcat.servlets.config.ServletContextConfig.FilterData; -import org.apache.tomcat.servlets.config.ServletContextConfig.FilterMappingData; -import org.apache.tomcat.servlets.config.ServletContextConfig.ServiceData; -import org.apache.tomcat.servlets.config.ServletContextConfig.ServletData; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.Type; -import org.objectweb.asm.tree.AnnotationNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; - - -// TODO: move to 'tools' dir, don't include in runtime -// ( same for xml processor ) - use binary -// - -// TODO: stupid ordering rules - probably will require merging configs -// and other ugliness. - -// TODO: the even more brain-damaged ServletContextInitializer and -// HandlesTypes - which requires recording all annotations for all classes, -// and worse - all the hierarchy to detect annotations on super. - -/** - * Post-compile or deploy tool: will scan classes and jars and - * generate an annotation file. - * - * Will process: - * - annotations - for each class - * - find tld descriptors - * - web.xml and fragments - * - * Output: a .ser file, for faster tomcat startup and a 'compete' - * web.xml file. - * - * Tomcat should not read all classes each time it starts, or - * depend on bcel at runtime. - * - * Servlet spec makes the worst use of annotations by requiring - * scanning all classes. This should be a compile-time tool only ! - * - * @author Costin Manolache - */ -public class AnnotationsProcessor { - - String baseDir; - ServletContextConfig cfg; - - - - public AnnotationsProcessor(ServletContextConfig cfg2) { - this.cfg = cfg2; - } - - public void processWebapp(String baseN) throws IOException { - if (!baseN.endsWith("/")) { - baseN = baseN + "/"; - } - processDir(baseN + "classes"); - - File lib = new File(baseN + "lib"); - if (!lib.isDirectory()) { - return; - } - File[] files = lib.listFiles(); - if (files == null) { - return; - } - - for (File f: files) { - if (!f.isDirectory() && f.getName().endsWith(".jar")) { - processJar(f.getCanonicalPath()); - } - } - } - - public void processJar(String path) throws IOException { - JarFile jar = new JarFile(path); - Enumeration entries = jar.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - if (name.endsWith(".class")) { - processClass(jar.getInputStream(entry), - "", name); - } else if (name.equals("META-INF/services/javax.servlet.ServletContainerInitializer")) { - - } - - } - } - - public void processDir(String base) throws IOException { - // TODO: keep track of files to avoid loops - processDir(new File(base)); - } - - public void processDir(File base) throws IOException { - if (!base.isDirectory()) { - return; - } - String baseN = base.getCanonicalPath(); - if (!baseN.endsWith("/")) { - baseN = baseN + "/"; - } - - File[] files = base.listFiles(); - if (files != null) { - for (File f: files) { - if (f.isDirectory()) { - System.err.println(f); - processDir(f); - } else if (f.getName().endsWith(".class")) { - try { - processClass(new FileInputStream(f), base.getCanonicalPath(), - f.getCanonicalPath()); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - - } - - private static Map asmList2Map(List list) { - Map values = new HashMap(); - for (int i = 0; i < list.size(); i+= 2) { - String name = (String) list.get(i); - Object val = list.get(i + 1); - values.put(name, val); - } - return values; - } - - private static Map annotationMap(List annL) { - Map values = new HashMap(); - if (annL != null) { - for (Object annO: annL) { - AnnotationNode ann = (AnnotationNode) annO; - String name = Type.getType(ann.desc).toString(); - values.put(name, ann); - } - } - return values; - } - - - - public void processClass(InputStream classStream, - String base, - String classFile) throws IOException { - String classPath = classFile.substring(base.length() + 1); - classPath = classPath.substring(0, classPath.length() - ".class".length()); - classPath = classPath.replace("/", "."); - - ClassReader classReader = new ClassReader(classStream); - ClassNode cN = new ClassNode(); - classReader.accept(cN, - ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG + ClassReader.SKIP_FRAMES); - - String className = cN.name; - - Map annotations = annotationMap(cN.visibleAnnotations); - - processServlets(className, annotations, cN); - processWebFilter(className, annotations); - - AnnotationNode listenerA = annotations.get("javax.servlet.annotation.WebListener"); - if (listenerA != null) { - // TODO: checks - cfg.listenerClass.add(className); - } - - -// for (AnnotationNode mN : annotations.values()) { -// String ann = Type.getType(mN.desc).toString(); -// Map values = asmList2Map(mN.values); -// -// if ("javax.servlet.annotation.HandlesTypes".equals(ann)) { -// } else if ("javax.servlet.annotation.MultipartConfig".equals(ann)) { -// } else if ("javax.annotation.security.RunAs".equals(ann)) { -// } else if ("javax.annotation.security.DeclareRoles".equals(ann)) { -// } else if ("javax.annotation.security.RolesAllowed".equals(ann)) { -// } else if ("javax.annotation.security.DenyAll".equals(ann)) { -// } else if ("javax.annotation.security.PermitAll".equals(ann)) { -// } else if ("javax.servlet.annotation.WebFilter".equals(ann)) { -// } else if ("javax.servlet.annotation.WebServlet".equals(ann)) { -// // in WebServlet -// } else if ("javax.servlet.annotation.WebListener".equals(ann)) { -// } else if ("javax.servlet.annotation.WebInitParam".equals(ann)) { -// // In WebServlet, (WebFilter) -// } else { -// System.err.println("\n" + className + " " + Type.getType(mN.desc)); -// } -// } - - } - - private void processServlets(String className, - Map annotations, ClassNode cn) { - - AnnotationNode webServletA = - annotations.get("javax.servlet.annotation.WebServlet"); - if (webServletA != null) { - ServletData sd = new ServletData(); - // TODO: validity checks (implements servlet, etc) - Map params = asmList2Map(webServletA.values); - - processService(className, webServletA, - sd, params); - - if (params.containsKey("loadOnStartup")) { - sd.loadOnStartup = (Integer)params.get("loadOnStartup"); - } - if (annotations.get("javax.servlet.annotation.MultipartConfig") != null) { - sd.multipartConfig = true; - } - - AnnotationNode declareA = annotations.get("javax.annotation.security.DeclareRoles"); - if (declareA != null) { - Map runAsParams = asmList2Map(declareA.values); - ArrayList roles = (ArrayList) runAsParams.get("value"); - for (Object r: roles) { - sd.declaresRoles.add((String) r); - } - } - - AnnotationNode runAsA = annotations.get("javax.annotation.security.RunAs"); - if (runAsA != null) { - Map runAsParams = asmList2Map(runAsA.values); - - sd.runAs = (String) runAsParams.get("value"); - } - - cfg.servlets.put(sd.name, sd); - - ArrayList urls = (ArrayList) params.get("urlPatterns"); - if (urls == null) { - urls = (ArrayList) params.get("value"); - } - - for (Object urlO: urls) { - cfg.servletMapping.put((String) urlO, - sd.name); - } - - // TODO: collect them, add on each of the URLs - // TODO: also on methods - AnnotationNode rolesA = annotations.get("javax.annotation.security.RolesAllowed"); - if (rolesA != null) { - - } - for (Object o: cn.methods) { - MethodNode methodNode = (MethodNode) o; - System.err.println(methodNode.desc); - } - - - - } - } - - private void processWebFilter(String className, - Map annotations) { - AnnotationNode webFilterA = annotations.get("javax.servlet.annotation.WebServlet"); - if (webFilterA != null) { - // TODO: validity checks (implements servlet, etc) - - FilterData sd = new FilterData(); - Map params = asmList2Map(webFilterA.values); - - processService(className, webFilterA, sd, params); - - if (params.containsKey("asyncSupported")) { - sd.asyncSupported = (Boolean) params.get("asyncSupported"); - } - - cfg.filters.put(sd.name, sd); - - ArrayList urls = (ArrayList) params.get("urlPatterns"); - if (urls == null) { - urls = (ArrayList) params.get("value"); - } - for (Object urlO: urls) { - FilterMappingData fmap = new FilterMappingData(); - fmap.filterName = sd.name; - fmap.urlPattern = (String) urlO; - - cfg.filterMappings.add(fmap); - } - } - } - - private ServiceData processService(String className, - AnnotationNode webServletA, ServiceData sd, Map params) { - - sd.name = (String) params.get("name"); - if (sd.name == null) { - sd.name = className; - } - sd.className = className; - - if (params.containsKey("initParams")) { - ArrayList initParamL = (ArrayList) params.get("initParams"); - for (Object initParamO: initParamL) { - AnnotationNode initParamA = (AnnotationNode) initParamO; - - Map initParams = asmList2Map(initParamA.values); - sd.initParams.put((String) initParams.get("name"), - (String) initParams.get("value")); - } - } - - if (params.containsKey("asyncSupported")) { - sd.asyncSupported = (Boolean) params.get("asyncSupported"); - } - return sd; - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/DomUtil.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/DomUtil.java deleted file mode 100644 index 64e287033..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/config/deploy/DomUtil.java +++ /dev/null @@ -1,240 +0,0 @@ -package org.apache.tomcat.servlets.config.deploy; - - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.util.logging.Logger; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - - -/** - * Few simple utils to read DOM - * - * @author Costin Manolache - */ -public class DomUtil { - private static Logger log= - Logger.getLogger( DomUtil.class.getName() ); - - // -------------------- DOM utils -------------------- - - /** Get the trimed text content of a node or null if there is no text - */ - public static String getContent(Node n ) { - if( n==null ) return null; - Node n1=DomUtil.getChild(n, Node.TEXT_NODE); - - if( n1==null ) return null; - - String s1=n1.getNodeValue(); - return s1.trim(); - } - - /** Get the first element child. - * @param parent lookup direct childs - * @param name name of the element. If null return the first element. - */ - public static Node getChild( Node parent, String name ) { - if( parent==null ) return null; - Node first=parent.getFirstChild(); - if( first==null ) return null; - - for (Node node = first; node != null; - node = node.getNextSibling()) { - //System.out.println("getNode: " + name + " " + node.getNodeName()); - if( node.getNodeType()!=Node.ELEMENT_NODE) - continue; - if( name != null && - name.equals( node.getNodeName() ) ) { - return node; - } - if( name == null ) { - return node; - } - } - return null; - } - - public static String getAttribute(Node element, String attName ) { - NamedNodeMap attrs=element.getAttributes(); - if( attrs==null ) return null; - Node attN=attrs.getNamedItem(attName); - if( attN==null ) return null; - return attN.getNodeValue(); - } - - public static void setAttribute(Node node, String attName, String val) { - NamedNodeMap attributes=node.getAttributes(); - Node attNode=node.getOwnerDocument().createAttribute(attName); - attNode.setNodeValue( val ); - attributes.setNamedItem(attNode); - } - - public static void removeAttribute( Node node, String attName ) { - NamedNodeMap attributes=node.getAttributes(); - attributes.removeNamedItem(attName); - } - - - /** Set or replace the text value - */ - public static void setText(Node node, String val) { - Node chld=DomUtil.getChild(node, Node.TEXT_NODE); - if( chld == null ) { - Node textN=node.getOwnerDocument().createTextNode(val); - node.appendChild(textN); - return; - } - // change the value - chld.setNodeValue(val); - } - - /** Find the first direct child with a given attribute. - * @param parent - * @param elemName name of the element, or null for any - * @param attName attribute we're looking for - * @param attVal attribute value or null if we just want any - */ - public static Node findChildWithAtt(Node parent, String elemName, - String attName, String attVal) { - - Node child=DomUtil.getChild(parent, Node.ELEMENT_NODE); - if( attVal== null ) { - while( child!= null && - ( elemName==null || elemName.equals( child.getNodeName())) && - DomUtil.getAttribute(child, attName) != null ) { - child=getNext(child, elemName, Node.ELEMENT_NODE ); - } - } else { - while( child!= null && - ( elemName==null || elemName.equals( child.getNodeName())) && - ! attVal.equals( DomUtil.getAttribute(child, attName)) ) { - child=getNext(child, elemName, Node.ELEMENT_NODE ); - } - } - return child; - } - - - /** Get the first child's content ( ie it's included TEXT node ). - */ - public static String getChildContent( Node parent, String name ) { - Node first=parent.getFirstChild(); - if( first==null ) return null; - for (Node node = first; node != null; - node = node.getNextSibling()) { - //System.out.println("getNode: " + name + " " + node.getNodeName()); - if( name.equals( node.getNodeName() ) ) { - return getContent( node ); - } - } - return null; - } - - /** Get the first direct child with a given type - */ - public static Node getChild( Node parent, int type ) { - Node n=parent.getFirstChild(); - while( n!=null && type != n.getNodeType() ) { - n=n.getNextSibling(); - } - if( n==null ) return null; - return n; - } - - /** Get the next sibling with the same name and type - */ - public static Node getNext( Node current ) { - String name=current.getNodeName(); - int type=current.getNodeType(); - return getNext( current, name, type); - } - - /** Return the next sibling with a given name and type - */ - public static Node getNext( Node current, String name, int type) { - Node first=current.getNextSibling(); - if( first==null ) return null; - - for (Node node = first; node != null; - node = node.getNextSibling()) { - - if( type >= 0 && node.getNodeType() != type ) continue; - //System.out.println("getNode: " + name + " " + node.getNodeName()); - if( name==null ) - return node; - if( name.equals( node.getNodeName() ) ) { - return node; - } - } - return null; - } - - public static class NullResolver implements EntityResolver { - public InputSource resolveEntity (String publicId, - String systemId) - throws SAXException, IOException - { -// if( log.isTraceEnabled()) -// log.trace("ResolveEntity: " + publicId + " " + systemId); - return new InputSource(new StringReader("")); - } - } - -// public static void setAttributes( Object o, Node parent) -// { -// NamedNodeMap attrs=parent.getAttributes(); -// if( attrs==null ) return; -// -// for (int i=0; i entries = jar.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - if (name.equals("META-INF/web-fragment.xml")) { - processFragment(jar.getInputStream(entry)); - } - } - } - - private void processFragment(InputStream inputStream) throws IOException { - readWebXml(inputStream, "web-fragment"); - - } - - public void readWebXml(String baseDir) throws IOException { - readWebXml(baseDir, "web-app"); - } - - public void readWebXml(String baseDir, String topName) throws IOException { - try { - File webXmlFile = new File(baseDir); - if (!webXmlFile.exists()) { - return; - } - d.fileName.add(webXmlFile.getCanonicalPath()); - - FileInputStream fileInputStream = new FileInputStream(webXmlFile); - readWebXml(fileInputStream, topName); - } catch (Exception e) { - e.printStackTrace(); - throw new IOException(e.getMessage()); - } - } - - public void readWebXml(InputStream fileInputStream, String topName) - throws IOException { - try { - - Document document = DomUtil.readXml(fileInputStream); - Node webappNode = DomUtil.getChild(document, topName); - - String fullS = DomUtil.getAttribute(webappNode, "full"); - if (fullS != null && fullS.equalsIgnoreCase("true")) { - d.full = true; - } - String metaCompleteS = DomUtil.getAttribute(webappNode, "full"); - if ("true".equalsIgnoreCase(metaCompleteS)) { - d.metadataComplete = true; - } - - d.displayName = DomUtil.getAttribute(webappNode, "display-name"); - - // Process each child of web-app - Node confNode = DomUtil.getChild(webappNode, "filter"); - while (confNode != null ) { - processFilter(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "filter-mapping"); - while (confNode != null ) { - processFilterMapping(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "context-param"); - while (confNode != null ) { - String n = DomUtil.getChildContent(confNode, "param-name").trim(); - String v = DomUtil.getChildContent(confNode, "param-value").trim(); - d.contextParam.put(n, v); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "mime-mapping"); - while (confNode != null ) { - String n = DomUtil.getChildContent(confNode, "extension"); - String t = DomUtil.getChildContent(confNode, "mime-type"); - d.mimeMapping.put(n, t); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "error-page"); - while (confNode != null ) { - processErrorPage(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "jsp-config"); - while (confNode != null ) { - processJspConfig(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "servlet"); - while (confNode != null ) { - processServlet(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "servlet-mapping"); - while (confNode != null ) { - processServletMapping(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "listener"); - while (confNode != null ) { - String lClass = DomUtil.getChildContent(confNode, "listener-class"); - d.listenerClass.add(lClass); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "security-constraint"); - while (confNode != null ) { - processSecurityConstraint(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "login-config"); - while (confNode != null ) { - processLoginConfig(confNode); - confNode = DomUtil.getNext(confNode); - if (confNode != null) - throw new ServletException("Multiple login-config"); - } - - confNode = DomUtil.getChild(webappNode, "session-config"); - while (confNode != null ) { - String n = DomUtil.getChildContent(confNode, "session-timeout"); - int stout = Integer.parseInt(n); - d.sessionTimeout = stout; - confNode = DomUtil.getNext(confNode); - if (confNode != null) - throw new ServletException("Multiple session-config"); - } - - confNode = DomUtil.getChild(webappNode, "welcome-file-list"); - while (confNode != null ) { - Node wf = DomUtil.getChild(confNode, "welcome-file"); - while (wf != null) { - String file = DomUtil.getContent(wf); - d.welcomeFileList.add(file); - wf = DomUtil.getNext(wf); - } - // more sections ? - confNode = DomUtil.getNext(confNode); - } - - // Not supported right now - TODO: collect, have jndi plugin - confNode = DomUtil.getChild(webappNode, "env-entry"); - while (confNode != null ) { - processEnvEntry(confNode); - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(webappNode, "locale-encoding-mapping-list"); - while (confNode != null ) { - confNode = DomUtil.getNext(confNode); - String n = DomUtil.getChildContent(confNode, "locale"); - String t = DomUtil.getChildContent(confNode, "encoding"); - d.localeEncodingMapping.put(n, t); - } - - confNode = DomUtil.getChild(webappNode, "distributable"); - while (confNode != null ) { - d.distributable = true; - confNode = DomUtil.getNext(confNode); - } - - confNode = DomUtil.getChild(confNode, "security-role"); - while (confNode != null ) { - String n = DomUtil.getChildContent(confNode, "role-name"); - d.securityRole.add(n); - confNode = DomUtil.getNext(confNode); - } - - } catch (Exception e) { - e.printStackTrace(); - throw new IOException(e.getMessage()); - } - } - - private void processJspConfig(Node confNode) { - Node tagLib = DomUtil.getChild(confNode, "taglib"); - while (tagLib != null) { - String uri = DomUtil.getChildContent(tagLib, "taglib-uri"); - String l = DomUtil.getChildContent(tagLib, "taglib-location"); - //d.tagLibs.put(uri, l); - tagLib = DomUtil.getNext(tagLib); - } - - tagLib = DomUtil.getChild(confNode, "jsp-property-group"); - while (tagLib != null) { - // That would be the job of the JSP servlet to process. - tagLib = DomUtil.getNext(tagLib); - } - } - - private void processEnvEntry(Node confNode) { - EnvEntryData ed = new EnvEntryData(); - ed.envEntryName = DomUtil.getChildContent(confNode,"env-entry-name"); - ed.envEntryType = DomUtil.getChildContent(confNode,"env-entry-type"); - ed.envEntryValue = DomUtil.getChildContent(confNode,"env-entry-value"); - d.envEntry.add(ed); - } - - private void processLoginConfig(Node confNode) { - d.authMethod = DomUtil.getChildContent(confNode,"auth-method"); - d.realmName = DomUtil.getChildContent(confNode,"auth-method"); - Node formNode = DomUtil.getChild(confNode, "form-login-config"); - if (formNode != null) { - d.formLoginPage = DomUtil.getChildContent(formNode,"form-login-page"); - d.formErrorPage = DomUtil.getChildContent(formNode,"form-error-page"); - } - } - - private void processSecurityConstraint(Node confNode) { - SecurityConstraintData sd = new SecurityConstraintData(); - Node cn = DomUtil.getChild(confNode, "web-resource-collection"); - while (cn != null) { - WebResourceCollectionData wrd = new WebResourceCollectionData(); - wrd.webResourceName = DomUtil.getChildContent(cn, "web-resource-name"); - Node scn = DomUtil.getChild(cn,"url-pattern"); - while (scn != null) { - wrd.urlPattern.add(DomUtil.getContent(scn)); - scn = DomUtil.getNext(scn); - } - scn = DomUtil.getChild(cn,"http-method"); - while (scn != null) { - wrd.httpMethod.add(DomUtil.getContent(scn)); - scn = DomUtil.getNext(scn); - } - cn = DomUtil.getNext(cn); - sd.webResourceCollection.add(wrd); - } - - d.securityConstraint.add(sd); - } - - private void processErrorPage(Node confNode) { - String name = DomUtil.getChildContent(confNode,"location"); - String c = DomUtil.getChildContent(confNode,"error-code"); - String t = DomUtil.getChildContent(confNode,"exception-type"); - if (c != null) { - d.errorPageCode.put(c, name); - } - if (t != null) { - d.errorPageException.put(t, name); - } - } - - private void processServlet(Node confNode) throws ServletException { - ServletData sd = new ServletData(); - - sd.name = DomUtil.getChildContent(confNode,"servlet-name"); - sd.className = DomUtil.getChildContent(confNode,"servlet-class"); - sd.jspFile = DomUtil.getChildContent(confNode,"jsp-file"); - - processInitParams(confNode, sd.initParams); - - d.servlets.put( sd.name, sd ); - - String los = DomUtil.getChildContent(confNode, "load-on-startup"); - if (los != null ) { - sd.loadOnStartup = Integer.parseInt(los); - } - - Node sn = DomUtil.getChild(confNode, "security-role-ref"); - while (sn != null ) { - String roleName = DomUtil.getChildContent(sn, "role-name"); - String roleLink = DomUtil.getChildContent(sn, "role-link"); - if (roleLink == null) { - sd.securityRoleRef.put(roleName, ""); - } else { - sd.securityRoleRef.put(roleName, roleLink); - } - sn = DomUtil.getNext(sn); - } - } - - private void processInitParams(Node confNode, Map initParams) { - Node initN = DomUtil.getChild(confNode, "init-param"); - while (initN != null ) { - String n = DomUtil.getChildContent(initN, "param-name"); - String v = DomUtil.getChildContent(initN, "param-value"); - initParams.put(n, v); - initN = DomUtil.getNext(initN); - } - } - - private void processServletMapping(Node confNode) { - String name = DomUtil.getChildContent(confNode,"servlet-name"); - Node dataN = DomUtil.getChild(confNode, "url-pattern"); - while (dataN != null) { - String path = DomUtil.getContent(dataN).trim(); - dataN = DomUtil.getNext(dataN); - - if (! (path.startsWith("/") || path.startsWith("*"))) { - // backward compat - path = "/" + path; - } - d.servletMapping.put(path, name); - } - } - - private void processFilterMapping(Node confNode) { - String filterName = DomUtil.getChildContent(confNode,"filter-name"); - // multiple - ArrayList dispatchers = new ArrayList(); - Node dataN = DomUtil.getChild(confNode, "dispatcher"); - while (dataN != null ) { - String d = DomUtil.getContent(dataN); - dispatchers.add(d); - dataN = DomUtil.getNext(dataN); - } - - // Multiple url-pattern and servlet-name in one - // mapping rule. Need to be applied in order. - dataN = DomUtil.getChild(confNode, "url-pattern"); - while (dataN != null ) { - FilterMappingData fm = new FilterMappingData(); - fm.filterName = filterName; - fm.dispatcher = dispatchers; - String path = DomUtil.getContent(dataN); - dataN = DomUtil.getNext(dataN); - fm.urlPattern = path; - d.filterMappings.add(fm); - } - dataN = DomUtil.getChild(confNode, "servlet-name"); - while (dataN != null ) { - FilterMappingData fm = new FilterMappingData(); - fm.filterName = filterName; - fm.dispatcher = dispatchers; - String sn = DomUtil.getContent(dataN); - dataN = DomUtil.getNext(dataN); - fm.servletName = sn; - d.filterMappings.add(fm); - } - } - - private void processFilter(Node confNode) { - String name = DomUtil.getChildContent(confNode,"filter-name"); - String sclass = DomUtil.getChildContent(confNode,"filter-class"); - - FilterData fd = new FilterData(); - processInitParams(confNode, fd.initParams); - fd.name = name; - fd.className = sclass; - d.filters.put(name, fd); - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/CopyUtils.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/CopyUtils.java deleted file mode 100644 index 5ebf38a77..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/CopyUtils.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Reader; - -import javax.servlet.ServletOutputStream; - -public class CopyUtils { - protected static int input = 2048; - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The resource info - * @param writer The writer to write to - * - * @exception IOException if an input/output error occurs - */ - public static void copy(InputStream is, - PrintWriter writer, - String fileEncoding) - throws IOException { - - IOException exception = null; - - InputStream resourceInputStream = is; - - Reader reader; - if (fileEncoding == null) { - reader = new InputStreamReader(resourceInputStream); - } else { - reader = new InputStreamReader(resourceInputStream, - fileEncoding); - } - - // Copy the input stream to the output stream - exception = copyRange(reader, writer); - - // Clean up the reader - try { - reader.close(); - } catch (Throwable t) { - ; - } - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The resource information - * @param ostream The output stream to write to - * - * @exception IOException if an input/output error occurs - */ - public static void copy(InputStream is, OutputStream ostream) - throws IOException { - - IOException exception = null; - InputStream resourceInputStream = null; - - resourceInputStream = is; - - InputStream istream = new BufferedInputStream - (resourceInputStream, input); - - // Copy the input stream to the output stream - exception = CopyUtils.copyRange(istream, ostream); - - // Clean up the input stream - try { - istream.close(); - } catch (Throwable t) { - ; - } - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - } - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param istream The input stream to read from - * @param ostream The output stream to write to - * @return Exception which occurred during processing - */ - public static IOException copyRange(InputStream istream, - OutputStream ostream) { - - // Copy the input stream to the output stream - IOException exception = null; - byte buffer[] = new byte[input]; - int len = buffer.length; - while (true) { - try { - len = istream.read(buffer); - if (len == -1) - break; - ostream.write(buffer, 0, len); - } catch (IOException e) { - exception = e; - len = -1; - break; - } - } - return exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param reader The reader to read from - * @param writer The writer to write to - * @return Exception which occurred during processing - */ - public static IOException copyRange(Reader reader, PrintWriter writer) { - - // Copy the input stream to the output stream - IOException exception = null; - char buffer[] = new char[input]; - int len = buffer.length; - while (true) { - try { - len = reader.read(buffer); - if (len == -1) - break; - writer.write(buffer, 0, len); - } catch (IOException e) { - exception = e; - len = -1; - break; - } - } - return exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param istream The input stream to read from - * @param ostream The output stream to write to - * @param start Start of the range which will be copied - * @param end End of the range which will be copied - * @return Exception which occurred during processing - */ - public static IOException copyRange(InputStream istream, - ServletOutputStream ostream, - long start, long end) { - - try { - istream.skip(start); - } catch (IOException e) { - return e; - } - - IOException exception = null; - long bytesToRead = end - start + 1; - - byte buffer[] = new byte[input]; - int len = buffer.length; - while ( (bytesToRead > 0) && (len >= buffer.length)) { - try { - len = istream.read(buffer); - if (bytesToRead >= len) { - ostream.write(buffer, 0, len); - bytesToRead -= len; - } else { - ostream.write(buffer, 0, (int) bytesToRead); - bytesToRead = 0; - } - } catch (IOException e) { - exception = e; - len = -1; - } - if (len < buffer.length) - break; - } - - return exception; - - } - - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param reader The reader to read from - * @param writer The writer to write to - * @param start Start of the range which will be copied - * @param end End of the range which will be copied - * @return Exception which occurred during processing - */ - public static IOException copyRange(Reader reader, PrintWriter writer, - long start, long end) { - - try { - reader.skip(start); - } catch (IOException e) { - return e; - } - - IOException exception = null; - long bytesToRead = end - start + 1; - - char buffer[] = new char[input]; - int len = buffer.length; - while ( (bytesToRead > 0) && (len >= buffer.length)) { - try { - len = reader.read(buffer); - if (bytesToRead >= len) { - writer.write(buffer, 0, len); - bytesToRead -= len; - } else { - writer.write(buffer, 0, (int) bytesToRead); - bytesToRead = 0; - } - } catch (IOException e) { - exception = e; - len = -1; - } - if (len < buffer.length) - break; - } - - return exception; - - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/DefaultServlet.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/DefaultServlet.java deleted file mode 100644 index 4015bf76e..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/DefaultServlet.java +++ /dev/null @@ -1,1099 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.Reader; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.StringTokenizer; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tomcat.lite.util.CopyUtils; -import org.apache.tomcat.lite.util.Dir2Html; -import org.apache.tomcat.lite.util.Range; -import org.apache.tomcat.lite.util.URLEncoder; - -/** - * The default resource-serving servlet for most web applications, - * used to serve static resources such as HTML pages and images. - * - * @author Craig R. McClanahan - * @author Remy Maucherat - * @author Costin Manolache - */ -public class DefaultServlet extends HttpServlet { - - - // ----------------------------------------------------- Instance Variables - - /** - * Should we generate directory listings? - */ - protected boolean listings = true; - - /** - * Array containing the safe characters set. - */ - protected static URLEncoder urlEncoder; - - /** - * Allow a readme file to be included. - */ - protected String readmeFile = null; - - // TODO: find a better default - /** - * The input buffer size to use when serving resources. - */ - protected static int input = 2048; - - /** - * The output buffer size to use when serving resources. - */ - protected int output = 2048; - - /** - * File encoding to be used when reading static files. If none is specified - * the platform default is used. - */ - protected String fileEncoding = null; - - static ThreadLocal formatTL = new ThreadLocal(); - - Dir2Html dir2Html = new Dir2Html(); - /** - * Full range marker. - */ - protected static ArrayList FULL = new ArrayList(); - - // Context base dir - protected File basePath; - protected String basePathName; - - // ----------------------------------------------------- Static Initializer - - - /** - * GMT timezone - all HTTP dates are on GMT - */ - static { - urlEncoder = new URLEncoder(); - urlEncoder.addSafeCharacter('-'); - urlEncoder.addSafeCharacter('_'); - urlEncoder.addSafeCharacter('.'); - urlEncoder.addSafeCharacter('*'); - urlEncoder.addSafeCharacter('/'); - } - - - /** - * MIME multipart separation string - */ - protected static final String mimeSeparation = "TOMCAT_MIME_BOUNDARY"; - - - // --------------------------------------------------------- Public Methods - /** - * Finalize this servlet. - */ - public void destroy() { - } - - /** - * Initialize this servlet. - */ - public void init() throws ServletException { - - String realPath = getServletContext().getRealPath("/"); - basePath = new File(realPath); - try { - basePathName = basePath.getCanonicalPath(); - } catch (IOException e) { - basePathName = basePath.getAbsolutePath(); - } - log("Init default serviet, base: " + basePathName); - - // Set our properties from the initialization parameters - String value = null; - try { - value = getServletConfig().getInitParameter("input"); - input = Integer.parseInt(value); - } catch (Throwable t) { - ; - } - try { - value = getServletConfig().getInitParameter("listings"); - if (value != null ) - listings = (new Boolean(value)).booleanValue(); - } catch (Throwable t) { - ; - } - try { - value = getServletConfig().getInitParameter("output"); - output = Integer.parseInt(value); - } catch (Throwable t) { - ; - } - fileEncoding = getServletConfig().getInitParameter("fileEncoding"); - - readmeFile = getServletConfig().getInitParameter("readmeFile"); - - - // Sanity check on the specified buffer sizes - if (input < 256) - input = 256; - if (output < 256) - output = 256; - } - - public void setBasePath(String s) { - this.basePathName = s; - this.basePath = new File(s); - } - - public String getBasePath() { - return basePathName; - } - - public void setInput(int i) { - this.input = i; - } - - public void setListings(boolean b) { - this.listings = b; - } - - public void setReadme(String s) { - readmeFile = s; - } - - public void setFileEncoding(String s) { - fileEncoding = s; - } - - - public void loadDefaultMime() throws IOException { - File mimeF = new File("/etc/mime.types"); - boolean loaded =false; - if (!mimeF.exists()) { - loaded =true; - loadMimeFile( new FileInputStream(mimeF)); - } - mimeF = new File("/etc/httpd/mime.types"); - if (mimeF.exists()) { - loaded =true; - loadMimeFile( new FileInputStream(mimeF)); - } - if (!loaded) { - throw new IOException("mime.types not found"); - } - } - - public void loadMimeFile(InputStream is) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - String line = null; - while((line = reader.readLine()) != null) { - line = line.trim(); - if (line.length() == 0) continue; - if (line.startsWith("#")) continue; - String[] parts = line.split("\\w+"); - String type = parts[0]; - for (int i=1; i < parts.length; i++) { - String ext = parts[i]; - if (!ext.equals("")) { - addMimeType(type, ext); - System.err.println(type + " = " + ext); - } else { - System.err.println("XXX " + ext); - } - } - } - - } - - private void addMimeType(String type, String ext) { - - } - // ------------------------------------------------------ Protected Methods - - public static final String INCLUDE_REQUEST_URI_ATTR = - "javax.servlet.include.request_uri"; - public static final String INCLUDE_SERVLET_PATH_ATTR = - "javax.servlet.include.servlet_path"; - public static final String INCLUDE_PATH_INFO_ATTR = - "javax.servlet.include.path_info"; - public static final String INCLUDE_CONTEXT_PATH_ATTR = - "javax.servlet.include.context_path"; - - - /** - * Return the relative path associated with this servlet. - * Multiple sources are used - include attribute, servlet path, etc - * - * @param request The servlet request we are processing - */ - public static String getRelativePath(HttpServletRequest request) { - - // Are we being processed by a RequestDispatcher.include()? - if (request.getAttribute(INCLUDE_REQUEST_URI_ATTR) != null) { - String result = (String) request.getAttribute( - INCLUDE_PATH_INFO_ATTR); - if (result == null) - result = (String) request.getAttribute( - INCLUDE_SERVLET_PATH_ATTR); - if ((result == null) || (result.equals(""))) - result = "/"; - return (result); - } - - // No, extract the desired path directly from the request - // For 'default' servlet, the path info contains the path - // if this is mapped to serve a subset of the files - we - // need both - - String result = request.getPathInfo(); - if (result == null) { - result = request.getServletPath(); - } else { - result = request.getServletPath() + result; - } - if ((result == null) || (result.equals(""))) { - result = "/"; - } - return (result); - } - - protected void doGet(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - serveResource(request, response, true); - - } - - - protected void doHead(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - serveResource(request, response, false); - - } - - - protected void doPost(HttpServletRequest request, - HttpServletResponse response) - throws IOException, ServletException { - // TODO: not allowed ? - doGet(request, response); - } - - - - - /** - * Check if the conditions specified in the optional If headers are - * satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes The resource information - * @return boolean true if the resource meets all the specified conditions, - * and false if any of the conditions is not satisfied, in which case - * request processing is stopped - */ - protected boolean checkIfHeaders(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - - return checkIfMatch(request, response, resourceAttributes) - && checkIfModifiedSince(request, response, resourceAttributes) - && checkIfNoneMatch(request, response, resourceAttributes) - && checkIfUnmodifiedSince(request, response, resourceAttributes); - - } - - - /** - * Get the ETag associated with a file. - * - * @param resourceAttributes The resource information - */ - protected String getETag(File resourceAttributes) { - return "W/\"" + resourceAttributes.length() + "-" - + resourceAttributes.lastModified() + "\""; - } - - LRUFileCache fileCache; - - public void setFileCacheSize(int size) { - if (fileCache == null) { - fileCache = new LRUFileCache(); - } - fileCache.cacheSize = size; - } - - public int getFileCacheSize() { - if (fileCache ==null ) return 0; - return fileCache.cacheSize; - } - - static class LRUFileCache extends LinkedHashMap { - int cacheSize; - public LRUFileCache() { - } -// protected boolean removeEldestEntity(Map.Entry eldest) { -// return size() > cacheSize; -// } - } - - public void renderDir(HttpServletRequest request, - HttpServletResponse response, - File resFile, - String fileEncoding, - boolean content, - String relativePath) throws IOException { - - String contentType = "text/html;charset=" + fileEncoding; - - ServletOutputStream ostream = null; - PrintWriter writer = null; - - if (content) { - // Trying to retrieve the servlet output stream - try { - ostream = response.getOutputStream(); - } catch (IllegalStateException e) { - // If it fails, we try to get a Writer instead if we're - // trying to serve a text file - if ( (contentType == null) - || (contentType.startsWith("text")) ) { - writer = response.getWriter(); - } else { - throw e; - } - } - - } - - // Set the appropriate output headers - response.setContentType(contentType); - - InputStream renderResult = null; - - if (content) { - // Serve the directory browser - renderResult = - dir2Html.render(request.getContextPath(), resFile, relativePath); - } - - - // Copy the input stream to our output stream (if requested) - if (content) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null) { - CopyUtils.copy(renderResult, ostream); - } else { - CopyUtils.copy(renderResult, writer, fileEncoding); - } - } - - - } - - - /** - * Serve the specified resource, optionally including the data content. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param content Should the content be included? - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - protected void serveResource(HttpServletRequest request, - HttpServletResponse response, - boolean content) - throws IOException, ServletException { - - // Identify the requested resource path - checks include attributes - String path = getRelativePath(request); - - // TODO: Check the file cache to avoid a bunch of FS accesses. - - File resFile = new File(basePath, path); - - if (!resFile.exists()) { - send404(request, response); - return; - } - - boolean isDir = resFile.isDirectory(); - - if (isDir) { - getServletContext(); - // Skip directory listings if we have been configured to - // suppress them - if (!listings) { - response.sendError(HttpServletResponse.SC_NOT_FOUND, - request.getRequestURI()); - return; - } - renderDir(request, response, resFile, fileEncoding, content, - path); - - return; - } - - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (path.endsWith("/") || (path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - INCLUDE_REQUEST_URI_ATTR); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - - // Check if the conditions specified in the optional If headers are - // satisfied. - - // Checking If headers. The method will generate the - boolean included = - (request.getAttribute(INCLUDE_CONTEXT_PATH_ATTR) != null); - if (!included - && !checkIfHeaders(request, response, resFile)) { - return; - } - - - // Find content type. - String contentType = getServletContext().getMimeType(resFile.getName()); - - long contentLength = -1L; - - // ETag header - response.setHeader("ETag", getETag(resFile)); - - // TODO: remove the sync, optimize - it's from ResourceAttribute - String lastModifiedHttp = lastModifiedHttp(resFile); - - // Last-Modified header - response.setHeader("Last-Modified", lastModifiedHttp); - - // Get content length - contentLength = resFile.length(); - // Special case for zero length files, which would cause a - // (silent) ISE when setting the output buffer size - if (contentLength == 0L) { - content = false; - } - - ServletOutputStream ostream = null; - PrintWriter writer = null; - - if (content) { - - // Trying to retrieve the servlet output stream - - try { - ostream = response.getOutputStream(); - } catch (IllegalStateException e) { - // If it fails, we try to get a Writer instead if we're - // trying to serve a text file - if ( (contentType == null) - || (contentType.startsWith("text")) ) { - writer = response.getWriter(); - } else { - throw e; - } - } - } - - // Parse range specifier - - ArrayList ranges = parseRange(request, response, resFile); - - if ( ( ((ranges == null) || (ranges.isEmpty())) - && (request.getHeader("Range") == null) ) - || (ranges == FULL) ) { - - processSingleRange(response, content, resFile, contentType, - ostream, writer, ranges, contentLength); - } else { - - if ((ranges == null) || (ranges.isEmpty())) - return; - - // Partial content response. - - response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); - if (ranges.size() == 1) { - - processSingleRange(response, content, resFile, contentType, - ostream, writer, ranges, contentLength); - - } else { - - processMultiRange(response, content, resFile, contentType, - ostream, writer, ranges); - - } - - } - - } - - - private void processMultiRange(HttpServletResponse response, - boolean content, - File resFile, - String contentType, - ServletOutputStream ostream, - PrintWriter writer, - ArrayList ranges) throws IOException { - response.setContentType("multipart/byteranges; boundary=" - + mimeSeparation); - - if (content) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null) { - copyRanges(resFile, ostream, ranges.iterator(), - contentType); - } else { - copyRanges(resFile, writer, ranges.iterator(), - contentType); - } - } - } - - - private void processSingleRange(HttpServletResponse response, boolean content, File resFile, String contentType, ServletOutputStream ostream, PrintWriter writer, ArrayList ranges, - long contentLength) throws IOException { - Range range = null; - long length = contentLength; - - if (ranges != null && ranges.size() > 0) { - range = (Range) ranges.get(0); - response.addHeader("Content-Range", "bytes " - + range.start - + "-" + range.end + "/" - + range.length); - length = range.end - range.start + 1; - } - if (length < Integer.MAX_VALUE) { - response.setContentLength((int) length); - } else { - // Set the content-length as String to be able to use a long - response.setHeader("content-length", "" + length); - } - - if (contentType != null) { - response.setContentType(contentType); - } - - if (content) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - InputStream is = null; - try { - is = new FileInputStream(resFile); - if (ostream != null) { - if (range == null) { - CopyUtils.copy(is, ostream); - } else { - CopyUtils.copyRange(is, ostream, range.start, range.end); - } - } else {Reader reader; - if (fileEncoding == null) { - reader = new InputStreamReader(is); - } else { - reader = new InputStreamReader(is, - fileEncoding); - } - if (range == null) { - CopyUtils.copyRange(reader, writer); - } else { - CopyUtils.copyRange(reader, writer, range.start, range.end); - } - } - } finally { - is.close(); - } - } - } - - - public static String lastModifiedHttp(File resFile) { - String lastModifiedHttp = null; - SimpleDateFormat format = (SimpleDateFormat)formatTL.get(); - if (format == null) { - format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", - Locale.US); - formatTL.set(format); - } - lastModifiedHttp = format.format(new Date(resFile.lastModified())); - return lastModifiedHttp; - } - - - protected static void send404(HttpServletRequest request, HttpServletResponse response) throws IOException { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - INCLUDE_REQUEST_URI_ATTR); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } else { - // We're included, and the response.sendError() below is going - // to be ignored by the resource that is including us. - // Therefore, the only way we can let the including resource - // know is by including warning message in response - response.getWriter().write("Not found"); - // skip the URI - just to be safe. - } - - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - - - - /** - * Parse the range header. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @return Vector of ranges - */ - protected ArrayList parseRange(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - // if it has an IfRange and the file is newer, retur FULL - ArrayList result = processIfRange(request, resourceAttributes); - if ( result != null ) return result; - - long fileLength = resourceAttributes.length(); - if (fileLength == 0) - return null; - - // Retrieving the range header (if any is specified - String rangeHeader = request.getHeader("Range"); - - if (rangeHeader == null) - return null; - // bytes is the only range unit supported (and I don't see the point - // of adding new ones). - if (!rangeHeader.startsWith("bytes")) { - return sendRangeNotSatisfiable(response, fileLength); - } - - rangeHeader = rangeHeader.substring(6); - - // Vector which will contain all the ranges which are successfully - // parsed. - result = Range.parseRanges(fileLength, rangeHeader); - if (result == null) { - sendRangeNotSatisfiable(response, fileLength); - } - return result; - } - - - private ArrayList sendRangeNotSatisfiable(HttpServletResponse response, - long fileLength) - throws IOException { - response.addHeader("Content-Range", "bytes */" + fileLength); - response.sendError - (HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); - return null; - } - - - - private ArrayList processIfRange(HttpServletRequest request, - File resourceAttributes) { - // Checking If-Range - String headerValue = request.getHeader("If-Range"); - - if (headerValue != null) { - - long headerValueTime = (-1L); - try { - headerValueTime = request.getDateHeader("If-Range"); - } catch (Exception e) { - ; - } - - String eTag = getETag(resourceAttributes); - long lastModified = resourceAttributes.lastModified(); - - if (headerValueTime == (-1L)) { - - // If the ETag the client gave does not match the entity - // etag, then the entire entity is returned. - if (!eTag.equals(headerValue.trim())) - return FULL; - - } else { - - // If the timestamp of the entity the client got is older than - // the last modification date of the entity, the entire entity - // is returned. - if (lastModified > (headerValueTime + 1000)) - return FULL; - - } - - } - return null; - } - - - // -------------------------------------------------------- protected Methods - - - /** - * Check if the if-match condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceInfo File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfMatch(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - - String eTag = getETag(resourceAttributes); - String headerValue = request.getHeader("If-Match"); - if (headerValue != null) { - if (headerValue.indexOf('*') == -1) { - - StringTokenizer commaTokenizer = new StringTokenizer - (headerValue, ","); - boolean conditionSatisfied = false; - - while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { - String currentToken = commaTokenizer.nextToken(); - if (currentToken.trim().equals(eTag)) - conditionSatisfied = true; - } - - // If none of the given ETags match, 412 Precodition failed is - // sent back - if (!conditionSatisfied) { - response.sendError - (HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - - } - } - return true; - - } - - - /** - * Check if the if-modified-since condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceInfo File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfModifiedSince(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - try { - long headerValue = request.getDateHeader("If-Modified-Since"); - long lastModified = resourceAttributes.lastModified(); - if (headerValue != -1) { - - // If an If-None-Match header has been specified, if modified since - // is ignored. - if ((request.getHeader("If-None-Match") == null) - && (lastModified <= headerValue + 1000)) { - // The entity has not been modified since the date - // specified by the client. This is not an error case. - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - return false; - } - } - } catch(IllegalArgumentException illegalArgument) { - return true; - } - return true; - - } - - - /** - * Check if the if-none-match condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceInfo File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfNoneMatch(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - - String eTag = getETag(resourceAttributes); - String headerValue = request.getHeader("If-None-Match"); - if (headerValue != null) { - - boolean conditionSatisfied = false; - - if (!headerValue.equals("*")) { - - StringTokenizer commaTokenizer = - new StringTokenizer(headerValue, ","); - - while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { - String currentToken = commaTokenizer.nextToken(); - if (currentToken.trim().equals(eTag)) - conditionSatisfied = true; - } - - } else { - conditionSatisfied = true; - } - - if (conditionSatisfied) { - - // For GET and HEAD, we should respond with - // 304 Not Modified. - // For every other method, 412 Precondition Failed is sent - // back. - if ( ("GET".equals(request.getMethod())) - || ("HEAD".equals(request.getMethod())) ) { - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - return false; - } else { - response.sendError - (HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - } - } - return true; - - } - - - /** - * Check if the if-unmodified-since condition is satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceInfo File object - * @return boolean true if the resource meets the specified condition, - * and false if the condition is not satisfied, in which case request - * processing is stopped - */ - protected boolean checkIfUnmodifiedSince(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - try { - long lastModified = resourceAttributes.lastModified(); - long headerValue = request.getDateHeader("If-Unmodified-Since"); - if (headerValue != -1) { - if ( lastModified > (headerValue + 1000)) { - // The entity has not been modified since the date - // specified by the client. This is not an error case. - response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); - return false; - } - } - } catch(IllegalArgumentException illegalArgument) { - return true; - } - return true; - - } - - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The ResourceInfo object - * @param ostream The output stream to write to - * @param ranges Enumeration of the ranges the client wanted to retrieve - * @param contentType Content type of the resource - * @exception IOException if an input/output error occurs - */ - protected void copyRanges(File cacheEntry, ServletOutputStream ostream, - Iterator ranges, String contentType) - throws IOException { - - IOException exception = null; - - while ( (exception == null) && (ranges.hasNext()) ) { - - InputStream resourceInputStream = new FileInputStream(cacheEntry); - InputStream istream = - new BufferedInputStream(resourceInputStream, input); - - Range currentRange = (Range) ranges.next(); - - // Writing MIME header. - ostream.println(); - ostream.println("--" + mimeSeparation); - if (contentType != null) - ostream.println("Content-Type: " + contentType); - ostream.println("Content-Range: bytes " + currentRange.start - + "-" + currentRange.end + "/" - + currentRange.length); - ostream.println(); - - // Printing content - exception = CopyUtils.copyRange(istream, ostream, currentRange.start, - currentRange.end); - - try { - istream.close(); - } catch (Throwable t) { - ; - } - - } - - ostream.println(); - ostream.print("--" + mimeSeparation + "--"); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The ResourceInfo object - * @param writer The writer to write to - * @param ranges Enumeration of the ranges the client wanted to retrieve - * @param contentType Content type of the resource - * @exception IOException if an input/output error occurs - */ - protected void copyRanges(File cacheEntry, PrintWriter writer, - Iterator ranges, String contentType) - throws IOException { - - IOException exception = null; - - // quite inefficient - why not sort and open once - while ( (exception == null) && (ranges.hasNext()) ) { - - InputStream resourceInputStream = new FileInputStream(cacheEntry); - - Reader reader; - if (fileEncoding == null) { - reader = new InputStreamReader(resourceInputStream); - } else { - reader = new InputStreamReader(resourceInputStream, - fileEncoding); - } - - Range currentRange = (Range) ranges.next(); - - // Writing MIME header. - writer.println(); - writer.println("--" + mimeSeparation); - if (contentType != null) - writer.println("Content-Type: " + contentType); - writer.println("Content-Range: bytes " + currentRange.start - + "-" + currentRange.end + "/" - + currentRange.length); - writer.println(); - - // Printing content - exception = CopyUtils.copyRange(reader, writer, currentRange.start, - currentRange.end); - - try { - reader.close(); - } catch (Throwable t) { - ; - } - - } - writer.println(); - writer.print("--" + mimeSeparation + "--"); - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Dir2Html.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Dir2Html.java deleted file mode 100644 index fa6856cf3..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Dir2Html.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; - -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tomcat.servlets.util.URLEncoder; - -/** - * Handles directory listing - */ -public class Dir2Html { - - /** - * Array containing the safe characters set. - */ - protected static URLEncoder urlEncoder; - - /** - * Allow a readme file to be included. - */ - protected String readmeFile = null; - - // TODO: find a better default - /** - * The input buffer size to use when serving resources. - */ - protected int input = 2048; - - /** - * The output buffer size to use when serving resources. - */ - protected int output = 2048; - - /** - * File encoding to be used when reading static files. If none is specified - * the platform default is used. - */ - protected String fileEncoding = null; - - ThreadLocal formatTL = new ThreadLocal(); - - /** - * Full range marker. - */ - protected static ArrayList FULL = new ArrayList(); - - // Context base dir - protected File basePath; - protected String basePathName; - - public static final String TOMCAT_CSS = - "H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} " + - "H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} " + - "H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} " + - "BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} " + - "B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} " + - "P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}" + - "A {color : black;}" + - "A.name {color : black;}" + - "HR {color : #525D76;}"; - - // ----------------------------------------------------- Static Initializer - - - /** - * GMT timezone - all HTTP dates are on GMT - */ - static { - urlEncoder = new URLEncoder(); - urlEncoder.addSafeCharacter('-'); - urlEncoder.addSafeCharacter('_'); - urlEncoder.addSafeCharacter('.'); - urlEncoder.addSafeCharacter('*'); - urlEncoder.addSafeCharacter('/'); - } - - - /** - * MIME multipart separation string - */ - protected static final String mimeSeparation = "TOMCAT_MIME_BOUNDARY"; - - - // --------------------------------------------------------- Public Methods - - /** - * Serve the specified resource, optionally including the data content. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param content Should the content be included? - * - * @exception IOException if an input/output error occurs - * @exception ServletException if a servlet-specified error occurs - */ - protected void serveResource(HttpServletRequest request, - HttpServletResponse response, - boolean content, - String relativePath) - throws IOException, ServletException { - - // Identify the requested resource path - checks include attributes - String path = DefaultServlet.getRelativePath(request); - - // TODO: Check the file cache to avoid a bunch of FS accesses. - - File resFile = new File(basePath, path); - - if (!resFile.exists()) { - DefaultServlet.send404(request, response); - return; - } - - boolean isDir = resFile.isDirectory(); - - if (isDir) { - renderDir(request, response, resFile,"UTF=8", content, - relativePath); - return; - } - - } - - - - // ----------------- Directory rendering -------------------- - - // Just basic HTML rendering - extend or replace for xslt - - public void renderDir(HttpServletRequest request, - HttpServletResponse response, - File resFile, - String fileEncoding, - boolean content, - String relativePath) throws IOException { - - String contentType = "text/html;charset=" + fileEncoding; - - ServletOutputStream ostream = null; - PrintWriter writer = null; - - if (content) { - // Trying to retrieve the servlet output stream - try { - ostream = response.getOutputStream(); - } catch (IllegalStateException e) { - // If it fails, we try to get a Writer instead if we're - // trying to serve a text file - if ( (contentType == null) - || (contentType.startsWith("text")) ) { - writer = response.getWriter(); - } else { - throw e; - } - } - - } - - // Set the appropriate output headers - response.setContentType(contentType); - - InputStream renderResult = null; - - if (content) { - // Serve the directory browser - renderResult = - render(request.getContextPath(), resFile, relativePath); - } - - - // Copy the input stream to our output stream (if requested) - if (content) { - try { - response.setBufferSize(output); - } catch (IllegalStateException e) { - // Silent catch - } - if (ostream != null) { - CopyUtils.copy(renderResult, ostream); - } else { - CopyUtils.copy(renderResult, writer, fileEncoding); - } - } - - - } - - - /** - * URL rewriter. - * - * @param path Path which has to be rewiten - */ - protected String rewriteUrl(String path) { - return urlEncoder.encode( path ); - } - - - - /** - * Decide which way to render. HTML or XML. - */ - protected InputStream render(String contextPath, File cacheEntry, - String relativePath) { - return renderHtml(contextPath, cacheEntry, relativePath); - } - - - /** - * Return an InputStream to an HTML representation of the contents - * of this directory. - * - * @param contextPath Context path to which our internal paths are - * relative - */ - protected InputStream renderHtml(String contextPath, File cacheEntry, - String relativePath) { - - String dirName = cacheEntry.getName(); - - // Number of characters to trim from the beginnings of filenames -// int trim = relativePath.length(); -// if (!relativePath.endsWith("/")) -// trim += 1; -// if (relativePAth.equals("/")) -// trim = 1; - - // Prepare a writer to a buffered area - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - OutputStreamWriter osWriter = null; - try { - osWriter = new OutputStreamWriter(stream, "UTF8"); - } catch (Exception e) { - // Should never happen - osWriter = new OutputStreamWriter(stream); - } - PrintWriter writer = new PrintWriter(osWriter); - - StringBuilder sb = new StringBuilder(); - - // rewriteUrl(contextPath) is expensive. cache result for later reuse - String rewrittenContextPath = rewriteUrl(contextPath); - - // TODO: use a template for localization / customization - - // Render the page header - sb.append("\r\n"); - sb.append("\r\n"); - sb.append(""); - sb.append(dirName); - sb.append("\r\n"); - sb.append(" "); - sb.append("\r\n"); - sb.append(""); - sb.append("

"); - sb.append(dirName); - sb.append("

"); - - sb.append("
"); - - - sb.append("\r\n"); - - // Render the column headings - sb.append("\r\n"); - sb.append("\r\n"); - sb.append("\r\n"); - sb.append("\r\n"); - sb.append(""); - boolean shade = false; - - // Render the link to our parent (if required) - String parentDirectory = relativePath; - if (parentDirectory.endsWith("/")) { - parentDirectory = - parentDirectory.substring(0, parentDirectory.length() - 1); - } - int slash = parentDirectory.lastIndexOf('/'); - if (slash >= 0) { - String parent = relativePath.substring(0, slash); - sb.append("\r\n"); - shade = true; - } - - - // Render the directory entries within this directory - String[] files = cacheEntry.list(); - for (int i=0; i\r\n"); - shade = !shade; - - sb.append("\r\n"); - - sb.append("\r\n"); - - sb.append("\r\n"); - - sb.append("\r\n"); - } - - - // Render the page footer - sb.append("
"); - sb.append("Name"); - sb.append(""); - sb.append("Size"); - sb.append(""); - sb.append("Last Modified"); - sb.append("
  \r\n"); - //sb.append(""); - sb.append(".."); - //sb.append(""); - sb.append("
  \r\n"); - sb.append(""); - sb.append(trimmed); - if (isDir) - sb.append("/"); - sb.append(""); - if (isDir) - sb.append(" "); - else - displaySize(sb,childCacheEntry.length()); - sb.append(""); - sb.append(DefaultServlet.lastModifiedHttp(childCacheEntry)); - sb.append("
\r\n"); - - sb.append("
"); - - String readme = getReadme(cacheEntry); - if (readme!=null) { - sb.append(readme); - sb.append("
"); - } - - sb.append("\r\n"); - sb.append("\r\n"); - - // Return an input stream to the underlying bytes - writer.write(sb.toString()); - writer.flush(); - return (new ByteArrayInputStream(stream.toByteArray())); - - } - - /** - * Display the size of a file. - */ - protected void displaySize(StringBuilder buf, long filesize) { - - long leftside = filesize / 1024; - long rightside = (filesize % 1024) / 103; // makes 1 digit - if (leftside == 0 && rightside == 0 && filesize != 0) - rightside = 1; - buf.append(leftside).append(".").append(rightside); - buf.append(" KB"); - } - - /** - * Get the readme file as a string. - */ - protected String getReadme(File directory) { - if (readmeFile!=null) { - try { - File rf = new File(directory, readmeFile); - - if (rf.exists()) { - StringWriter buffer = new StringWriter(); - InputStream is = new FileInputStream(rf); - CopyUtils.copyRange(new InputStreamReader(is), - new PrintWriter(buffer)); - - return buffer.toString(); - } - } catch(Throwable e) { - ; /* Should only be IOException or NamingException - * can be ignored - */ - } - } - return null; - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/FileCopyUtils.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/FileCopyUtils.java deleted file mode 100644 index 83e80b3e6..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/FileCopyUtils.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.Reader; - -import javax.servlet.ServletOutputStream; - -import org.apache.tomcat.servlets.util.Range; - - -/** Like CopyUtils, but with File as source. - * - * This has the potential to be optimized with JNI - */ -public class FileCopyUtils { - protected static int input = 2048; - - public static void copy(File f, OutputStream ostream) - throws IOException { - CopyUtils.copy(new FileInputStream(f), ostream); - } - - - public static void copy(File cacheEntry, - PrintWriter writer, - String fileEncoding) - throws IOException { - CopyUtils.copy(new FileInputStream(cacheEntry), writer, fileEncoding); - } - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The ResourceInfo object - * @param ostream The output stream to write to - * @param range Range the client wanted to retrieve - * @exception IOException if an input/output error occurs - */ - public static void copy(File cacheEntry, ServletOutputStream ostream, - Range range) - throws IOException { - - IOException exception = null; - - InputStream resourceInputStream = new FileInputStream(cacheEntry); - InputStream istream = - new BufferedInputStream(resourceInputStream, input); - exception = CopyUtils.copyRange(istream, ostream, range.start, range.end); - - // Clean up the input stream - try { - istream.close(); - } catch (Throwable t) { - ; - } - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } - - /** - * Copy the contents of the specified input stream to the specified - * output stream, and ensure that both streams are closed before returning - * (even in the face of an exception). - * - * @param resourceInfo The ResourceInfo object - * @param writer The writer to write to - * @param range Range the client wanted to retrieve - * @exception IOException if an input/output error occurs - */ - public static void copy(File cacheEntry, PrintWriter writer, - Range range, String fileEncoding) - throws IOException { - - IOException exception = null; - - InputStream resourceInputStream = new FileInputStream(cacheEntry); - - Reader reader; - if (fileEncoding == null) { - reader = new InputStreamReader(resourceInputStream); - } else { - reader = new InputStreamReader(resourceInputStream, - fileEncoding); - } - - exception = CopyUtils.copyRange(reader, writer, range.start, range.end); - - // Clean up the input stream - try { - reader.close(); - } catch (Throwable t) { - ; - } - - // Rethrow any exception that has occurred - if (exception != null) - throw exception; - - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Filesystem.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Filesystem.java deleted file mode 100644 index 8af49f44e..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Filesystem.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.file; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Abstract the filesystem - lighter than the JNDI used in catalina. - * - * This can be used to port the File/Dav servlets to environments that - * don't have a file system access, or in servlet engines with class-based - * sandboxing. - */ -public class Filesystem { - - - public OutputStream getOutputStream(String name) throws IOException { - return null; - } - - public InputStream getInputStream(String name) throws IOException { - return new FileInputStream(name); - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/LocalFilesystem.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/LocalFilesystem.java deleted file mode 100644 index 8c9dbd360..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/LocalFilesystem.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.file; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - - -public class LocalFilesystem extends Filesystem { - - public OutputStream getOutputStream(String name) throws IOException { - return new FileOutputStream(name); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/MD5Encoder.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/MD5Encoder.java deleted file mode 100644 index d44b76b9c..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/MD5Encoder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - - -/** - * Encode an MD5 digest into a String. - *

- * The 128 bit MD5 hash is converted into a 32 character long String. - * Each character of the String is the hexadecimal representation of 4 bits - * of the digest. - * - * @author Remy Maucherat - */ - -public final class MD5Encoder { - - - // ----------------------------------------------------- Instance Variables - - - private static final char[] hexadecimal = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f'}; - - - // --------------------------------------------------------- Public Methods - - - /** - * Encodes the 128 bit (16 bytes) MD5 into a 32 character String. - * - * @param binaryData Array containing the digest - * @return Encoded MD5, or null if encoding failed - */ - public String encode( byte[] binaryData ) { - - if (binaryData.length != 16) - return null; - - char[] buffer = new char[32]; - - for (int i=0; i<16; i++) { - int low = (int) (binaryData[i] & 0x0f); - int high = (int) ((binaryData[i] & 0xf0) >> 4); - buffer[i*2] = hexadecimal[high]; - buffer[i*2 + 1] = hexadecimal[low]; - } - - return new String(buffer); - - } - - -} - diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/URLEncoder.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/URLEncoder.java deleted file mode 100644 index 2f098a7f8..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/URLEncoder.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.BitSet; - -/** - * - * This class is very similar to the java.net.URLEncoder class. - * - * Unfortunately, with java.net.URLEncoder there is no way to specify to the - * java.net.URLEncoder which characters should NOT be encoded. - * - * This code was moved from DefaultServlet.java - * - * @author Craig R. McClanahan - * @author Remy Maucherat - */ -public class URLEncoder { - protected static final char[] hexadecimal = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F'}; - - //Array containing the safe characters set. - protected BitSet safeCharacters = new BitSet(256); - - public URLEncoder() { - for (char i = 'a'; i <= 'z'; i++) { - addSafeCharacter(i); - } - for (char i = 'A'; i <= 'Z'; i++) { - addSafeCharacter(i); - } - for (char i = '0'; i <= '9'; i++) { - addSafeCharacter(i); - } - } - - public void addSafeCharacter( char c ) { - safeCharacters.set( c ); - } - - public String encode( String path ) { - int maxBytesPerChar = 10; - int caseDiff = ('a' - 'A'); - StringBuilder rewrittenPath = new StringBuilder(path.length()); - ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar); - OutputStreamWriter writer = null; - try { - writer = new OutputStreamWriter(buf, "UTF8"); - } catch (Exception e) { - e.printStackTrace(); - writer = new OutputStreamWriter(buf); - } - - for (int i = 0; i < path.length(); i++) { - int c = (int) path.charAt(i); - if (safeCharacters.get(c)) { - rewrittenPath.append((char)c); - } else { - // convert to external encoding before hex conversion - try { - writer.write((char)c); - writer.flush(); - } catch(IOException e) { - buf.reset(); - continue; - } - byte[] ba = buf.toByteArray(); - for (int j = 0; j < ba.length; j++) { - // Converting each byte in the buffer - byte toEncode = ba[j]; - rewrittenPath.append('%'); - int low = (int) (toEncode & 0x0f); - int high = (int) ((toEncode & 0xf0) >> 4); - rewrittenPath.append(hexadecimal[high]); - rewrittenPath.append(hexadecimal[low]); - } - buf.reset(); - } - } - return rewrittenPath.toString(); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/WebdavServlet.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/WebdavServlet.java deleted file mode 100644 index 92c61d66f..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/WebdavServlet.java +++ /dev/null @@ -1,1858 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Writer; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Stack; -import java.util.TimeZone; -import java.util.Vector; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.apache.tomcat.lite.util.CopyUtils; -import org.apache.tomcat.lite.util.FastHttpDateFormat; -import org.apache.tomcat.lite.util.Range; -import org.apache.tomcat.lite.util.URLEncoder; -import org.apache.tomcat.lite.util.UrlUtils; -import org.apache.tomcat.lite.util.XMLWriter; -import org.apache.tomcat.servlets.util.RequestUtil; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - - - -/** - * Servlet which adds support for WebDAV level 1. All the basic HTTP requests - * are handled by the DefaultServlet. - * - * Based on Catalina WebdavServlet, with following changes: - * - removed the JNDI abstraction, use File instead - * - removed WebDAV 2 support ( moved to Webdav2Servlet ) - i.e. no locks - * supported - * - simplified and cleaned up the code - * - * @author Remy Maucherat - * @author Costin Manolache - */ -public class WebdavServlet extends DefaultServlet { - - - // -------------------------------------------------------------- Constants - - protected static final String METHOD_PROPFIND = "PROPFIND"; - protected static final String METHOD_PROPPATCH = "PROPPATCH"; - protected static final String METHOD_MKCOL = "MKCOL"; - protected static final String METHOD_COPY = "COPY"; - protected static final String METHOD_DELETE = "DELETE"; - protected static final String METHOD_MOVE = "MOVE"; - protected static final String METHOD_LOCK = "LOCK"; - protected static final String METHOD_UNLOCK = "UNLOCK"; - - - /** - * Default depth is infite. - */ - protected static final int INFINITY = 3; // To limit tree browsing a bit - - - /** - * PROPFIND - Specify a property mask. - */ - protected static final int FIND_BY_PROPERTY = 0; - - - /** - * PROPFIND - Display all properties. - */ - protected static final int FIND_ALL_PROP = 1; - - - /** - * PROPFIND - Return property names. - */ - protected static final int FIND_PROPERTY_NAMES = 2; - - /** - * Default namespace. - */ - protected static final String DEFAULT_NAMESPACE = "DAV:"; - - - /** - * Simple date format for the creation date ISO representation (partial). - * TODO: ThreadLocal - */ - protected static final SimpleDateFormat creationDateFormat = - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - - - static { - creationDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); - } - - // TODO: replace it with writeRole - who is enabled to write - protected boolean readOnly = true; - - /** - * Repository of the lock-null resources. - *

- * Key : path of the collection containing the lock-null resource
- * Value : Vector of lock-null resource which are members of the - * collection. Each element of the Vector is the path associated with - * the lock-null resource. - */ - protected Hashtable lockNullResources = new Hashtable(); - - - // --------------------------------------------------------- Public Methods - - - /** - * Initialize this servlet. - */ - public void init() - throws ServletException { - - super.init(); - - try { - String value = getServletConfig().getInitParameter("readonly"); - if (value != null) - readOnly = (new Boolean(value)).booleanValue(); - } catch (Throwable t) { - ; - } - log("Starting webdav"); - } - - public void setReadonly(boolean ro) { - readOnly = ro; - } - - public boolean getReadonly() { - return readOnly; - } - // ------------------------------------------------------ Protected Methods - - /** - * Handles the special WebDAV methods. - */ - protected void service(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - String method = req.getMethod(); - - if (method.equals(METHOD_PROPFIND)) { - doPropfind(req, resp); - } else if (method.equals(METHOD_PROPPATCH)) { - doProppatch(req, resp); - } else if (method.equals(METHOD_MKCOL)) { - doMkcol(req, resp); - } else if (method.equals(METHOD_COPY)) { - doCopy(req, resp); - } else if (method.equals(METHOD_MOVE)) { - doMove(req, resp); - } else if (method.equals(METHOD_LOCK)) { - doLock(req, resp); - } else if (method.equals(METHOD_UNLOCK)) { - doUnlock(req, resp); - } else if (method.equals(METHOD_DELETE)) { - doDelete(req, resp); - } else { - // DefaultServlet processing - GET, HEAD, POST - super.service(req, resp); - } - - } - - /** - * Check if the conditions specified in the optional If headers are - * satisfied. - * - * @param request The servlet request we are processing - * @param response The servlet response we are creating - * @param resourceAttributes The resource information - * @return boolean true if the resource meets all the specified conditions, - * and false if any of the conditions is not satisfied, in which case - * request processing is stopped - */ - protected boolean checkIfHeaders(HttpServletRequest request, - HttpServletResponse response, - File resourceAttributes) - throws IOException { - - if (!super.checkIfHeaders(request, response, resourceAttributes)) - return false; - - // TODO : Checking the WebDAV If header - return true; - - } - - - /** - * OPTIONS Method. - * - * @param req The request - * @param resp The response - * @throws ServletException If an error occurs - * @throws IOException If an IO error occurs - */ - protected void doOptions(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.addHeader("DAV", "1"); // And not: ,2"); - - StringBuilder methodsAllowed = determineMethodsAllowed(basePath, - req); - resp.addHeader("Allow", methodsAllowed.toString()); - resp.addHeader("MS-Author-Via", "DAV"); - } - - // ------------------ PROPFIND -------------------- - - /** - * PROPFIND Method. - */ - protected void doPropfind(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - String path = getRelativePath(req); - if (path.endsWith("/")) - path = path.substring(0, path.length() - 1); - - if ((path.toUpperCase().startsWith("/WEB-INF")) || - (path.toUpperCase().startsWith("/META-INF"))) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - // Propfind depth - int depth = getDepth(req); - - File object = new File(basePath, path); - - if (!object.exists()) { - resp.sendError(HttpServletResponse.SC_NOT_FOUND, path); - return; - } - - // Properties which are to be displayed. - Vector properties = new Vector(); - int type = getPropfindType(req, properties); - - resp.setStatus(WebdavStatus.SC_MULTI_STATUS); - resp.setContentType("text/xml; charset=UTF-8"); - - // Create multistatus object - XMLWriter generatedXML = new XMLWriter(resp.getWriter()); - generatedXML.writeXMLHeader(); - - generatedXML.writeElement(null, "multistatus" - + generateNamespaceDeclarations(), - XMLWriter.OPENING); - - if (depth == 0) { - parseProperties(req, generatedXML, path, type, - properties); - } else { - propfindRecurse(req, path, depth, properties, - type, generatedXML); - } - - generatedXML.writeElement(null, "multistatus", - XMLWriter.CLOSING); - generatedXML.sendData(); - } - - - private void propfindRecurse(HttpServletRequest req, String path, int depth, Vector properties, int type, XMLWriter generatedXML) throws IOException { - File object; - // The stack always contains the object of the current level - Stack stack = new Stack(); - stack.push(path); - - // Stack of the objects one level below - Stack stackBelow = new Stack(); - - while ((!stack.isEmpty()) && (depth >= 0)) { - String currentPath = (String) stack.pop(); - parseProperties(req, generatedXML, currentPath, - type, properties); - - object = new File(basePath,currentPath); - if (!object.exists()) { - continue; - } - - if ((object.isDirectory()) && (depth > 0)) { - - File[] files = object.listFiles(); - for (int i=0; i < files.length; i++) { - String newPath = currentPath; - if (!(newPath.endsWith("/"))) - newPath += "/"; - newPath += files[i].getName(); - stackBelow.push(newPath); - } - } - - if (stack.isEmpty()) { - depth--; - stack = stackBelow; - stackBelow = new Stack(); - } - - generatedXML.sendData(); - } - } - - - private int getPropfindType(HttpServletRequest req, Vector properties) throws ServletException { - // Propfind type - int type = FIND_ALL_PROP; - - DocumentBuilder documentBuilder = getDocumentBuilder(); - try { - Document document = documentBuilder.parse - (new InputSource(req.getInputStream())); - // Get the root element of the document - Element rootElement = document.getDocumentElement(); - NodeList childList = rootElement.getChildNodes(); - - for (int i=0; i < childList.getLength(); i++) { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - if (currentNode.getNodeName().endsWith("prop")) { - type = FIND_BY_PROPERTY; - Node propNode = currentNode; - NodeList childListPN = propNode.getChildNodes(); - for (int iPN=0; iPN < childListPN.getLength(); iPN++) { - Node currentNodePN = childListPN.item(iPN); - switch (currentNodePN.getNodeType()) { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - String nodeName = currentNodePN.getNodeName(); - String propertyName = null; - if (nodeName.indexOf(':') != -1) { - propertyName = nodeName.substring - (nodeName.indexOf(':') + 1); - } else { - propertyName = nodeName; - } - // href is a live property which is handled differently - properties.addElement(propertyName); - break; - } - } - } - if (currentNode.getNodeName().endsWith("propname")) { - type = FIND_PROPERTY_NAMES; - } - if (currentNode.getNodeName().endsWith("allprop")) { - type = FIND_ALL_PROP; - } - break; - } - } - } catch(Exception e) { - // Most likely there was no content : we use the defaults. - // TODO : Enhance that ! - } - return type; - } - - - private int getDepth(HttpServletRequest req) { - int depth = INFINITY; - String depthStr = req.getHeader("Depth"); - - if (depthStr == null) { - depth = INFINITY; - } else { - if (depthStr.equals("0")) { - depth = 0; - } else if (depthStr.equals("1")) { - depth = 1; - } else if (depthStr.equals("infinity")) { - depth = INFINITY; - } - } - return depth; - } - - - /** - * URL rewriter. - * - * @param path Path which has to be rewiten - */ - protected String rewriteUrl(String path) { - return urlEncoder.encodeURL( path ); - } - - - /** - * Propfind helper method. - * - * @param req The servlet request - * @param resources Resources object associated with this context - * @param out XML response to the Propfind request - * @param path Path of the current resource - * @param type Propfind type - * @param propertiesVector If the propfind type is find properties by - * name, then this Vector contains those properties - */ - protected void parseProperties(HttpServletRequest req, - XMLWriter out, - String path, int type, - Vector propertiesVector) { - - // Exclude any resource in the /WEB-INF and /META-INF subdirectories - // (the "toUpperCase()" avoids problems on Windows systems) - if (path.toUpperCase().startsWith("/WEB-INF") || - path.toUpperCase().startsWith("/META-INF")) - return; - - File cacheEntry = new File(basePath, path); - - out.writeElement(null, "response", XMLWriter.OPENING); - String status = new String("HTTP/1.1 " + WebdavStatus.SC_OK + " " - + WebdavStatus.getStatusText - (WebdavStatus.SC_OK)); - - // Generating href element - out.writeElement(null, "href", XMLWriter.OPENING); - - String href = req.getContextPath();// + req.getServletPath() + - // req.getPathInfo(); - - // ??? - if ((href.endsWith("/")) && (path.startsWith("/"))) - href += path.substring(1); - else - href += path; - if ((cacheEntry.isDirectory()) && (!href.endsWith("/"))) - href += "/"; - - out.writeText(rewriteUrl(href)); - - out.writeElement(null, "href", XMLWriter.CLOSING); - - String resourceName = path; - int lastSlash = path.lastIndexOf('/'); - if (lastSlash != -1) - resourceName = resourceName.substring(lastSlash + 1); - - switch (type) { - - case FIND_ALL_PROP : - - out.writeElement(null, "propstat", XMLWriter.OPENING); - out.writeElement(null, "prop", XMLWriter.OPENING); - - out.writeProperty - (null, "creationdate", - getISOCreationDate(cacheEntry.lastModified())); - out.writeElement(null, "displayname", XMLWriter.OPENING); - out.writeData(resourceName); - out.writeElement(null, "displayname", XMLWriter.CLOSING); - if (!cacheEntry.isDirectory()) { - out.writeProperty(null, "getlastmodified", - FastHttpDateFormat.formatDate(cacheEntry.lastModified(), - null)); - out.writeProperty(null, "getcontentlength", - String.valueOf(cacheEntry.length())); - String contentType = - getServletContext().getMimeType(cacheEntry.getName()); - if (contentType != null) { - out.writeProperty(null, "getcontenttype", contentType); - } - out.writeProperty(null, "getetag", getETag(cacheEntry)); - out.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT); - } else { - out.writeElement(null, "resourcetype", XMLWriter.OPENING); - out.writeElement(null, "collection", XMLWriter.NO_CONTENT); - out.writeElement(null, "resourcetype", XMLWriter.CLOSING); - } - - out.writeProperty(null, "source", ""); - out.writeElement(null, "prop", XMLWriter.CLOSING); - out.writeElement(null, "status", XMLWriter.OPENING); - out.writeText(status); - out.writeElement(null, "status", XMLWriter.CLOSING); - out.writeElement(null, "propstat", XMLWriter.CLOSING); - break; - - case FIND_PROPERTY_NAMES : - out.writeElement(null, "propstat", XMLWriter.OPENING); - out.writeElement(null, "prop", XMLWriter.OPENING); - out.writeElement(null, "creationdate", XMLWriter.NO_CONTENT); - out.writeElement(null, "displayname", XMLWriter.NO_CONTENT); - if (! cacheEntry.isDirectory()) { - out.writeElement(null, "getcontentlanguage", - XMLWriter.NO_CONTENT); - out.writeElement(null, "getcontentlength", - XMLWriter.NO_CONTENT); - out.writeElement(null, "getcontenttype", - XMLWriter.NO_CONTENT); - out.writeElement(null, "getetag", - XMLWriter.NO_CONTENT); - out.writeElement(null, "getlastmodified", - XMLWriter.NO_CONTENT); - } - out.writeElement(null, "resourcetype", XMLWriter.NO_CONTENT); - out.writeElement(null, "source", XMLWriter.NO_CONTENT); - out.writeElement(null, "lockdiscovery", XMLWriter.NO_CONTENT); - - out.writeElement(null, "prop", XMLWriter.CLOSING); - out.writeElement(null, "status", XMLWriter.OPENING); - out.writeText(status); - out.writeElement(null, "status", XMLWriter.CLOSING); - out.writeElement(null, "propstat", XMLWriter.CLOSING); - - break; - - case FIND_BY_PROPERTY : - - Vector propertiesNotFound = new Vector(); - - // Parse the list of properties - out.writeElement(null, "propstat", XMLWriter.OPENING); - out.writeElement(null, "prop", XMLWriter.OPENING); - - genPropertiesFound(out, propertiesVector, cacheEntry, - resourceName, propertiesNotFound); - - out.writeElement(null, "prop", XMLWriter.CLOSING); - out.writeElement(null, "status", XMLWriter.OPENING); - out.writeText(status); - out.writeElement(null, "status", XMLWriter.CLOSING); - out.writeElement(null, "propstat", XMLWriter.CLOSING); - - Enumeration propertiesNotFoundList = propertiesNotFound.elements(); - - if (propertiesNotFoundList.hasMoreElements()) { - status = new String("HTTP/1.1 " + WebdavStatus.SC_NOT_FOUND - + " " + WebdavStatus.getStatusText - (WebdavStatus.SC_NOT_FOUND)); - - out.writeElement(null, "propstat", XMLWriter.OPENING); - out.writeElement(null, "prop", XMLWriter.OPENING); - while (propertiesNotFoundList.hasMoreElements()) { - out.writeElement - (null, (String) propertiesNotFoundList.nextElement(), - XMLWriter.NO_CONTENT); - } - out.writeElement(null, "prop", XMLWriter.CLOSING); - out.writeElement(null, "status", XMLWriter.OPENING); - out.writeText(status); - out.writeElement(null, "status", XMLWriter.CLOSING); - out.writeElement(null, "propstat", XMLWriter.CLOSING); - } - break; - - } - - out.writeElement(null, "response", XMLWriter.CLOSING); - } - - - private void genPropertiesFound(XMLWriter out, Vector propertiesVector, - File cacheEntry, String resourceName, - Vector propertiesNotFound) { - Enumeration properties = propertiesVector.elements(); - - while (properties.hasMoreElements()) { - String property = (String) properties.nextElement(); - if (property.equals("creationdate")) { - out.writeProperty(null, "creationdate", - getISOCreationDate(cacheEntry.lastModified())); - } else if (property.equals("displayname")) { - out.writeElement(null, "displayname", XMLWriter.OPENING); - out.writeData(resourceName); - out.writeElement(null, "displayname", XMLWriter.CLOSING); - } else if (property.equals("getcontentlanguage")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - out.writeElement(null, "getcontentlanguage", - XMLWriter.NO_CONTENT); - } - } else if (property.equals("getcontentlength")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - out.writeProperty(null, "getcontentlength", - (String.valueOf(cacheEntry.length()))); - } - } else if (property.equals("getcontenttype")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - out.writeProperty(null, "getcontenttype", - getServletContext().getMimeType(cacheEntry.getName())); - } - } else if (property.equals("getetag")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - out.writeProperty(null, "getetag", getETag(cacheEntry)); - } - } else if (property.equals("getlastmodified")) { - if (cacheEntry.isDirectory()) { - propertiesNotFound.addElement(property); - } else { - out.writeProperty(null, "getlastmodified", - FastHttpDateFormat - .formatDate(cacheEntry.lastModified(), null)); - } - } else if (property.equals("resourcetype")) { - if (cacheEntry.isDirectory()) { - out.writeElement(null, "resourcetype", - XMLWriter.OPENING); - out.writeElement(null, "collection", - XMLWriter.NO_CONTENT); - out.writeElement(null, "resourcetype", - XMLWriter.CLOSING); - } else { - out.writeElement(null, "resourcetype", - XMLWriter.NO_CONTENT); - } - } else if (property.equals("source")) { - out.writeProperty(null, "source", ""); - } else if (property.equals("supportedlock")) { - // TODO: hook for Webdav2 - propertiesNotFound.addElement(property); - } else if (property.equals("lockdiscovery")) { - propertiesNotFound.addElement(property); - } else { - propertiesNotFound.addElement(property); - } - - } - } - - // ------------------ PROPPATCH -------------------- - - /** - * PROPPATCH Method. - */ - protected void doProppatch(HttpServletRequest req, - HttpServletResponse resp) - throws ServletException, IOException { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - } - - // ------------------ MKCOL -------------------- - - /** - * MKCOL Method. - */ - protected void doMkcol(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (readOnly) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavStatus.SC_LOCKED); - return; - } - - String path = getRelativePath(req); - - if ((path.toUpperCase().startsWith("/WEB-INF")) || - (path.toUpperCase().startsWith("/META-INF"))) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - File object = new File(basePath,path); - - // Can't create a collection if a resource already exists at the given - // path - if (object.exists()) { - // Get allowed methods - StringBuilder methodsAllowed = determineMethodsAllowed(basePath, - req); - - resp.addHeader("Allow", methodsAllowed.toString()); - - resp.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED); - return; - } - - if (req.getInputStream().available() > 0) { - DocumentBuilder documentBuilder = getDocumentBuilder(); - try { - Document document = documentBuilder.parse - (new InputSource(req.getInputStream())); - // TODO : Process this request body - resp.sendError(WebdavStatus.SC_NOT_IMPLEMENTED); - return; - - } catch(SAXException saxe) { - // Parse error - assume invalid content - resp.sendError(WebdavStatus.SC_BAD_REQUEST); - return; - } - } - - boolean result = true; - - File newDir = new File(basePath, path); - result = newDir.mkdir(); - - if (!result) { - resp.sendError(WebdavStatus.SC_CONFLICT, - WebdavStatus.getStatusText - (WebdavStatus.SC_CONFLICT)); - } else { - resp.setStatus(WebdavStatus.SC_CREATED); - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - } - - } - - /** - * DELETE Method. - */ - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (readOnly) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavStatus.SC_LOCKED); - return; - } - - deleteResource(req, resp); - - } - - - /** - * This is not part of DefaultServlet - all PUT and write operations - * should be handled by webdav servlet, which allows more control - */ - protected void doPut(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - if (isLocked(req)) { - resp.sendError(WebdavStatus.SC_LOCKED); - return; - } - - if (readOnly) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - String path = getRelativePath(req); - - if (path.indexOf("..") >= 0) { - // not supported, too dangerous - // what else to escape ? - resp.setStatus(404); - return; - } - - File resFile = new File(basePath, path); - boolean exists = resFile.exists(); - - // extra check - if (!resFile.getCanonicalPath().startsWith(basePathName)) { - //log.info("File outside basedir " + basePathS + " " + f); - resp.setStatus(404); - return; - } - - - boolean result = true; - - // Temp. content file used to support partial PUT - //File contentFile = null; - - String rangeHeader = req.getHeader("Content-Range"); - Range range = null; - if ( rangeHeader != null ) { - // we have a header, but has bad value. - // original catalina code has a bug I think - range = Range.parseContentRange(rangeHeader); - if (range == null) { // can't parse - resp.sendError(HttpServletResponse.SC_BAD_REQUEST); - return; - } - } - - InputStream resourceInputStream = null; - - // Append data specified in ranges to existing content for this - // resource - create a temp. file on the local filesystem to - // perform this operation - // Assume just one range is specified for now - if (range != null) { - //contentFile = executePartialPut(req, range, path); - //resourceInputStream = new FileInputStream(contentFile); - resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); - return; - } else { - resourceInputStream = req.getInputStream(); - } - - try { - // will override - OutputStream fos = getOut(resFile.getPath()); - CopyUtils.copy(resourceInputStream, fos); - } catch(IOException e) { - result = false; - } - - if (result) { - if (exists) { - resp.setStatus(HttpServletResponse.SC_NO_CONTENT); - } else { - resp.setStatus(HttpServletResponse.SC_CREATED); - } - } else { - resp.sendError(HttpServletResponse.SC_CONFLICT); - } - - // Removing any lock-null resource which would be present - lockNullResources.remove(path); - } - - - /** - * Handle a partial PUT. New content specified in request is appended to - * existing content in oldRevisionContent (if present). This code does - * not support simultaneous partial updates to the same resource. - * @throws FileNotFoundException - */ -// protected File executePartialPut(HttpServletRequest req, Range range, -// String path) -// throws IOException { -// -// // Append data specified in ranges to existing content for this -// // resource - create a temp. file on the local filesystem to -// // perform this operation -// File tempDir = (File) getServletContext().getAttribute -// ("javax.servlet.context.tempdir"); -// // Convert all '/' characters to '.' in resourcePath -// String convertedResourcePath = path.replace('/', '.'); -// File contentFile = new File(tempDir, convertedResourcePath); -// if (contentFile.createNewFile()) { -// // Clean up contentFile when Tomcat is terminated -// contentFile.deleteOnExit(); -// } -// -// RandomAccessFile randAccessContentFile = -// new RandomAccessFile(contentFile, "rw"); -// -// Resource oldResource = null; -// try { -// Object obj = resources.lookup(path); -// if (obj instanceof Resource) -// oldResource = (Resource) obj; -// } catch (NamingException e) { -// } -// -// // Copy data in oldRevisionContent to contentFile -// if (oldResource != null) { -// BufferedInputStream bufOldRevStream = -// new BufferedInputStream(oldResource.streamContent(), -// BUFFER_SIZE); -// -// int numBytesRead; -// byte[] copyBuffer = new byte[BUFFER_SIZE]; -// while ((numBytesRead = bufOldRevStream.read(copyBuffer)) != -1) { -// randAccessContentFile.write(copyBuffer, 0, numBytesRead); -// } -// -// bufOldRevStream.close(); -// } -// -// randAccessContentFile.setLength(range.length); -// -// // Append data in request input stream to contentFile -// randAccessContentFile.seek(range.start); -// int numBytesRead; -// byte[] transferBuffer = new byte[BUFFER_SIZE]; -// BufferedInputStream requestBufInStream = -// new BufferedInputStream(req.getInputStream(), BUFFER_SIZE); -// while ((numBytesRead = requestBufInStream.read(transferBuffer)) != -1) { -// randAccessContentFile.write(transferBuffer, 0, numBytesRead); -// } -// randAccessContentFile.close(); -// requestBufInStream.close(); -// -// return contentFile; -// -// } - - - private OutputStream getOut(String path) throws FileNotFoundException { - return new FileOutputStream(path); - } - - /** - * COPY Method. - */ - protected void doCopy(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (readOnly) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - copyResource(req, resp); - } - - - /** - * MOVE Method. - */ - protected void doMove(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (readOnly) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return; - } - - if (isLocked(req)) { - resp.sendError(WebdavStatus.SC_LOCKED); - return; - } - - String path = getRelativePath(req); - - if (copyResource(req, resp)) { - deleteResource(path, req, resp, false); - } - - } - - - /** - * LOCK Method. - */ - protected void doLock(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.sendError(WebdavStatus.SC_NOT_IMPLEMENTED); - } - - /** - * UNLOCK Method. - */ - protected void doUnlock(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - resp.sendError(WebdavStatus.SC_NOT_IMPLEMENTED); - } - - // -------------------------------------------------------- protected Methods - - /** - * Generate the namespace declarations. - */ - protected String generateNamespaceDeclarations() { - return " xmlns=\"" + DEFAULT_NAMESPACE + "\""; - } - - - /** - * Check to see if a resource is currently write locked. The method - * will look at the "If" header to make sure the client - * has give the appropriate lock tokens. - * - * @param req Servlet request - * @return boolean true if the resource is locked (and no appropriate - * lock token has been found for at least one of the non-shared locks which - * are present on the resource). - */ - protected boolean isLocked(HttpServletRequest req) { - return false; - } - - /** - * Check to see if a resource is currently write locked. - * - * @param path Path of the resource - * @param ifHeader "If" HTTP header which was included in the request - * @return boolean true if the resource is locked (and no appropriate - * lock token has been found for at least one of the non-shared locks which - * are present on the resource). - */ - protected boolean isLocked(String path, String ifHeader) { - return false; - } - - - /** - * Copy a resource. - * - * @param req Servlet request - * @param resp Servlet response - * @return boolean true if the copy is successful - */ - protected boolean copyResource(HttpServletRequest req, - HttpServletResponse resp) - throws ServletException, IOException { - - // Parsing destination header - - String destinationPath = req.getHeader("Destination"); - - if (destinationPath == null) { - resp.sendError(WebdavStatus.SC_BAD_REQUEST); - return false; - } - - // Remove url encoding from destination - destinationPath = URLEncoder.URLDecode(destinationPath, "UTF8"); - - destinationPath = removeDestinationPrefix(req, destinationPath); - - // Normalise destination path (remove '.' and '..') - destinationPath = UrlUtils.normalize(destinationPath); - - String contextPath = req.getContextPath(); - if ((contextPath != null) && - (destinationPath.startsWith(contextPath))) { - destinationPath = destinationPath.substring(contextPath.length()); - } - - String pathInfo = req.getPathInfo(); - if (pathInfo != null) { - String servletPath = req.getServletPath(); - if ((servletPath != null) && - (destinationPath.startsWith(servletPath))) { - destinationPath = destinationPath.substring(servletPath.length()); - } - } - - - if ((destinationPath.toUpperCase().startsWith("/WEB-INF")) || - (destinationPath.toUpperCase().startsWith("/META-INF"))) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return false; - } - - String path = getRelativePath(req); - - if ((path.toUpperCase().startsWith("/WEB-INF")) || - (path.toUpperCase().startsWith("/META-INF"))) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return false; - } - - if (destinationPath.equals(path)) { - resp.sendError(WebdavStatus.SC_FORBIDDEN); - return false; - } - - // Parsing overwrite header - - boolean overwrite = true; - String overwriteHeader = req.getHeader("Overwrite"); - - if (overwriteHeader != null) { - if (overwriteHeader.equalsIgnoreCase("T")) { - overwrite = true; - } else { - overwrite = false; - } - } - - // Overwriting the destination - - boolean exists = true; - File f1 = new File(basePath, destinationPath); - if (!f1.exists()) { - exists = false; - } - - if (overwrite) { - // Delete destination resource, if it exists - if (exists) { - if (!deleteResource(destinationPath, req, resp, true)) { - return false; - } - } else { - resp.setStatus(WebdavStatus.SC_CREATED); - } - } else { - // If the destination exists, then it's a conflict - if (exists) { - resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED); - return false; - } - } - - // Copying source to destination - - Hashtable errorList = new Hashtable(); - - boolean result = copyResource(basePath, errorList, - path, destinationPath); - - if ((!result) || (!errorList.isEmpty())) { - sendReport(req, resp, errorList); - return false; - } - - // Removing any lock-null resource which would be present at - // the destination path - lockNullResources.remove(destinationPath); - return true; - - } - - - private String removeDestinationPrefix(HttpServletRequest req, - String destinationPath) { - int protocolIndex = destinationPath.indexOf("://"); - if (protocolIndex >= 0) { - // if the Destination URL contains the protocol, we can safely - // trim everything upto the first "/" character after "://" - int firstSeparator = - destinationPath.indexOf("/", protocolIndex + 4); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = destinationPath.substring(firstSeparator); - } - } else { - String hostName = req.getServerName(); - if ((hostName != null) && (destinationPath.startsWith(hostName))) { - destinationPath = destinationPath.substring(hostName.length()); - } - - int portIndex = destinationPath.indexOf(":"); - if (portIndex >= 0) { - destinationPath = destinationPath.substring(portIndex); - } - - if (destinationPath.startsWith(":")) { - int firstSeparator = destinationPath.indexOf("/"); - if (firstSeparator < 0) { - destinationPath = "/"; - } else { - destinationPath = - destinationPath.substring(firstSeparator); - } - } - } - return destinationPath; - } - - - /** - * Copy a collection. - * - * @param resources Resources implementation to be used - * @param errorList Hashtable containing the list of errors which occurred - * during the copy operation - * @param source Path of the resource to be copied - * @param dest Destination path - */ - protected boolean copyResource(File resources, Hashtable errorList, - String source, String dest) { - - File object = new File(basePath, source); - File destF = new File(basePath, dest); - - if (object.isDirectory()) { - - boolean done = destF.mkdirs(); - if (!done) { - errorList.put - (dest, new Integer(WebdavStatus.SC_CONFLICT)); - return false; - } - - File[] enumeration = object.listFiles(); - for (int i=0; i 0) { - creationDateValue.append("+"); - } - if (offset != 0) { - if (offset < 10) - creationDateValue.append("0"); - creationDateValue.append(offset + ":00"); - } else { - creationDateValue.append("Z"); - } - */ - return creationDateValue.toString(); - } - - /** - * Determines the methods normally allowed for the resource. - * - */ - protected StringBuilder determineMethodsAllowed(File basePath, - HttpServletRequest req) { - - StringBuilder methodsAllowed = new StringBuilder(); - String path = getRelativePath(req); - File object = new File(basePath, path); - if (!object.exists()) { - methodsAllowed.append("OPTIONS, MKCOL, PUT"); - return methodsAllowed; - } - methodsAllowed.append("OPTIONS, GET, HEAD, POST, DELETE, TRACE"); - methodsAllowed.append(", PROPPATCH, COPY, MOVE, PROPFIND"); - - if (object.isDirectory()) { - methodsAllowed.append(", PUT"); - } - - return methodsAllowed; - } -} - - -// -------------------------------------------------------- WebdavStatus Class - - -/** - * Wraps the HttpServletResponse class to abstract the - * specific protocol used. To support other protocols - * we would only need to modify this class and the - * WebDavRetCode classes. - * - * @author Marc Eaddy - * @version 1.0, 16 Nov 1997 - */ -class WebdavStatus { - - - // ----------------------------------------------------- Instance Variables - - - /** - * This Hashtable contains the mapping of HTTP and WebDAV - * status codes to descriptive text. This is a static - * variable. - */ - protected static Hashtable mapStatusCodes = new Hashtable(); - - - // ------------------------------------------------------ HTTP Status Codes - - - /** - * Status code (200) indicating the request succeeded normally. - */ - public static final int SC_OK = HttpServletResponse.SC_OK; - - - /** - * Status code (201) indicating the request succeeded and created - * a new resource on the server. - */ - public static final int SC_CREATED = HttpServletResponse.SC_CREATED; - - - /** - * Status code (202) indicating that a request was accepted for - * processing, but was not completed. - */ - public static final int SC_ACCEPTED = HttpServletResponse.SC_ACCEPTED; - - - /** - * Status code (204) indicating that the request succeeded but that - * there was no new information to return. - */ - public static final int SC_NO_CONTENT = HttpServletResponse.SC_NO_CONTENT; - - - /** - * Status code (301) indicating that the resource has permanently - * moved to a new location, and that future references should use a - * new URI with their requests. - */ - public static final int SC_MOVED_PERMANENTLY = - HttpServletResponse.SC_MOVED_PERMANENTLY; - - - /** - * Status code (302) indicating that the resource has temporarily - * moved to another location, but that future references should - * still use the original URI to access the resource. - */ - public static final int SC_MOVED_TEMPORARILY = - HttpServletResponse.SC_MOVED_TEMPORARILY; - - - /** - * Status code (304) indicating that a conditional GET operation - * found that the resource was available and not modified. - */ - public static final int SC_NOT_MODIFIED = - HttpServletResponse.SC_NOT_MODIFIED; - - - /** - * Status code (400) indicating the request sent by the client was - * syntactically incorrect. - */ - public static final int SC_BAD_REQUEST = - HttpServletResponse.SC_BAD_REQUEST; - - - /** - * Status code (401) indicating that the request requires HTTP - * authentication. - */ - public static final int SC_UNAUTHORIZED = - HttpServletResponse.SC_UNAUTHORIZED; - - - /** - * Status code (403) indicating the server understood the request - * but refused to fulfill it. - */ - public static final int SC_FORBIDDEN = HttpServletResponse.SC_FORBIDDEN; - - - /** - * Status code (404) indicating that the requested resource is not - * available. - */ - public static final int SC_NOT_FOUND = HttpServletResponse.SC_NOT_FOUND; - - - /** - * Status code (500) indicating an error inside the HTTP service - * which prevented it from fulfilling the request. - */ - public static final int SC_INTERNAL_SERVER_ERROR = - HttpServletResponse.SC_INTERNAL_SERVER_ERROR; - - - /** - * Status code (501) indicating the HTTP service does not support - * the functionality needed to fulfill the request. - */ - public static final int SC_NOT_IMPLEMENTED = - HttpServletResponse.SC_NOT_IMPLEMENTED; - - - /** - * Status code (502) indicating that the HTTP server received an - * invalid response from a server it consulted when acting as a - * proxy or gateway. - */ - public static final int SC_BAD_GATEWAY = - HttpServletResponse.SC_BAD_GATEWAY; - - - /** - * Status code (503) indicating that the HTTP service is - * temporarily overloaded, and unable to handle the request. - */ - public static final int SC_SERVICE_UNAVAILABLE = - HttpServletResponse.SC_SERVICE_UNAVAILABLE; - - - /** - * Status code (100) indicating the client may continue with - * its request. This interim response is used to inform the - * client that the initial part of the request has been - * received and has not yet been rejected by the server. - */ - public static final int SC_CONTINUE = 100; - - - /** - * Status code (405) indicating the method specified is not - * allowed for the resource. - */ - public static final int SC_METHOD_NOT_ALLOWED = 405; - - - /** - * Status code (409) indicating that the request could not be - * completed due to a conflict with the current state of the - * resource. - */ - public static final int SC_CONFLICT = 409; - - - /** - * Status code (412) indicating the precondition given in one - * or more of the request-header fields evaluated to false - * when it was tested on the server. - */ - public static final int SC_PRECONDITION_FAILED = 412; - - - /** - * Status code (413) indicating the server is refusing to - * process a request because the request entity is larger - * than the server is willing or able to process. - */ - public static final int SC_REQUEST_TOO_LONG = 413; - - - /** - * Status code (415) indicating the server is refusing to service - * the request because the entity of the request is in a format - * not supported by the requested resource for the requested - * method. - */ - public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; - - - // -------------------------------------------- Extended WebDav status code - - - /** - * Status code (207) indicating that the response requires - * providing status for multiple independent operations. - */ - public static final int SC_MULTI_STATUS = 207; - // This one colides with HTTP 1.1 - // "207 Parital Update OK" - - - /** - * Status code (418) indicating the entity body submitted with - * the PATCH method was not understood by the resource. - */ - public static final int SC_UNPROCESSABLE_ENTITY = 418; - // This one colides with HTTP 1.1 - // "418 Reauthentication Required" - - - /** - * Status code (419) indicating that the resource does not have - * sufficient space to record the state of the resource after the - * execution of this method. - */ - public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; - // This one colides with HTTP 1.1 - // "419 Proxy Reauthentication Required" - - - /** - * Status code (420) indicating the method was not executed on - * a particular resource within its scope because some part of - * the method's execution failed causing the entire method to be - * aborted. - */ - public static final int SC_METHOD_FAILURE = 420; - - - /** - * Status code (423) indicating the destination resource of a - * method is locked, and either the request did not contain a - * valid Lock-Info header, or the Lock-Info header identifies - * a lock held by another principal. - */ - public static final int SC_LOCKED = 423; - - - // ------------------------------------------------------------ Initializer - - - static { - // HTTP 1.0 tatus Code - addStatusCodeMap(SC_OK, "OK"); - addStatusCodeMap(SC_CREATED, "Created"); - addStatusCodeMap(SC_ACCEPTED, "Accepted"); - addStatusCodeMap(SC_NO_CONTENT, "No Content"); - addStatusCodeMap(SC_MOVED_PERMANENTLY, "Moved Permanently"); - addStatusCodeMap(SC_MOVED_TEMPORARILY, "Moved Temporarily"); - addStatusCodeMap(SC_NOT_MODIFIED, "Not Modified"); - addStatusCodeMap(SC_BAD_REQUEST, "Bad Request"); - addStatusCodeMap(SC_UNAUTHORIZED, "Unauthorized"); - addStatusCodeMap(SC_FORBIDDEN, "Forbidden"); - addStatusCodeMap(SC_NOT_FOUND, "Not Found"); - addStatusCodeMap(SC_INTERNAL_SERVER_ERROR, "Internal Server Error"); - addStatusCodeMap(SC_NOT_IMPLEMENTED, "Not Implemented"); - addStatusCodeMap(SC_BAD_GATEWAY, "Bad Gateway"); - addStatusCodeMap(SC_SERVICE_UNAVAILABLE, "Service Unavailable"); - addStatusCodeMap(SC_CONTINUE, "Continue"); - addStatusCodeMap(SC_METHOD_NOT_ALLOWED, "Method Not Allowed"); - addStatusCodeMap(SC_CONFLICT, "Conflict"); - addStatusCodeMap(SC_PRECONDITION_FAILED, "Precondition Failed"); - addStatusCodeMap(SC_REQUEST_TOO_LONG, "Request Too Long"); - addStatusCodeMap(SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); - // WebDav Status Codes - addStatusCodeMap(SC_MULTI_STATUS, "Multi-Status"); - addStatusCodeMap(SC_UNPROCESSABLE_ENTITY, "Unprocessable Entity"); - addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE, - "Insufficient Space On Resource"); - addStatusCodeMap(SC_METHOD_FAILURE, "Method Failure"); - addStatusCodeMap(SC_LOCKED, "Locked"); - } - - - // --------------------------------------------------------- Public Methods - - - /** - * Returns the HTTP status text for the HTTP or WebDav status code - * specified by looking it up in the static mapping. This is a - * static function. - * - * @param nHttpStatusCode [IN] HTTP or WebDAV status code - * @return A string with a short descriptive phrase for the - * HTTP status code (e.g., "OK"). - */ - public static String getStatusText(int nHttpStatusCode) { - Integer intKey = new Integer(nHttpStatusCode); - - if (!mapStatusCodes.containsKey(intKey)) { - return ""; - } else { - return (String) mapStatusCodes.get(intKey); - } - } - - - // -------------------------------------------------------- protected Methods - - - /** - * Adds a new status code -> status text mapping. This is a static - * method because the mapping is a static variable. - * - * @param nKey [IN] HTTP or WebDAV status code - * @param strVal [IN] HTTP status text - */ - protected static void addStatusCodeMap(int nKey, String strVal) { - mapStatusCodes.put(new Integer(nKey), strVal); - } - -}; - diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/XMLWriter.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/XMLWriter.java deleted file mode 100644 index 769407cb2..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/XMLWriter.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.file; - -import java.io.IOException; -import java.io.Writer; - -/** - * XMLWriter helper class. - * - * @author Remy Maucherat - */ -public class XMLWriter { - - - // -------------------------------------------------------------- Constants - - - /** - * Opening tag. - */ - public static final int OPENING = 0; - - - /** - * Closing tag. - */ - public static final int CLOSING = 1; - - - /** - * Element with no content. - */ - public static final int NO_CONTENT = 2; - - - // ----------------------------------------------------- Instance Variables - - - /** - * Buffer. - */ - protected StringBuilder buffer = new StringBuilder(); - - - /** - * Writer. - */ - protected Writer writer = null; - - - // ----------------------------------------------------------- Constructors - - - /** - * Constructor. - */ - public XMLWriter() { - } - - - /** - * Constructor. - */ - public XMLWriter(Writer writer) { - this.writer = writer; - } - - - // --------------------------------------------------------- Public Methods - - - /** - * Retrieve generated XML. - * - * @return String containing the generated XML - */ - public String toString() { - return buffer.toString(); - } - - - /** - * Write property to the XML. - * - * @param namespace Namespace - * @param namespaceInfo Namespace info - * @param name Property name - * @param value Property value - */ - public void writeProperty(String namespace, String namespaceInfo, - String name, String value) { - writeElement(namespace, namespaceInfo, name, OPENING); - buffer.append(value); - writeElement(namespace, namespaceInfo, name, CLOSING); - - } - - - /** - * Write property to the XML. - * - * @param namespace Namespace - * @param name Property name - * @param value Property value - */ - public void writeProperty(String namespace, String name, String value) { - writeElement(namespace, name, OPENING); - buffer.append(value); - writeElement(namespace, name, CLOSING); - } - - - /** - * Write property to the XML. - * - * @param namespace Namespace - * @param name Property name - */ - public void writeProperty(String namespace, String name) { - writeElement(namespace, name, NO_CONTENT); - } - - - /** - * Write an element. - * - * @param name Element name - * @param namespace Namespace abbreviation - * @param type Element type - */ - public void writeElement(String namespace, String name, int type) { - writeElement(namespace, null, name, type); - } - - - /** - * Write an element. - * - * @param namespace Namespace abbreviation - * @param namespaceInfo Namespace info - * @param name Element name - * @param type Element type - */ - public void writeElement(String namespace, String namespaceInfo, - String name, int type) { - if ((namespace != null) && (namespace.length() > 0)) { - switch (type) { - case OPENING: - if (namespaceInfo != null) { - buffer.append("<" + namespace + ":" + name + " xmlns:" - + namespace + "=\"" - + namespaceInfo + "\">"); - } else { - buffer.append("<" + namespace + ":" + name + ">"); - } - break; - case CLOSING: - buffer.append("\n"); - break; - case NO_CONTENT: - default: - if (namespaceInfo != null) { - buffer.append("<" + namespace + ":" + name + " xmlns:" - + namespace + "=\"" - + namespaceInfo + "\"/>"); - } else { - buffer.append("<" + namespace + ":" + name + "/>"); - } - break; - } - } else { - switch (type) { - case OPENING: - buffer.append("<" + name + ">"); - break; - case CLOSING: - buffer.append("\n"); - break; - case NO_CONTENT: - default: - buffer.append("<" + name + "/>"); - break; - } - } - } - - - /** - * Write text. - * - * @param text Text to append - */ - public void writeText(String text) { - buffer.append(text); - } - - - /** - * Write data. - * - * @param data Data to append - */ - public void writeData(String data) { - buffer.append(""); - } - - - /** - * Write XML Header. - */ - public void writeXMLHeader() { - buffer.append("\n"); - } - - - /** - * Send data and reinitializes buffer. - */ - public void sendData() - throws IOException { - if (writer != null) { - writer.write(buffer.toString()); - buffer = new StringBuilder(); - } - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/BaseJspLoader.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/BaseJspLoader.java deleted file mode 100644 index 87dc0a845..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/BaseJspLoader.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.jsp; - -import java.io.IOException; -import java.util.Vector; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; - - -/** - * Load a JSP generated by jasper. - * - * Requires a 'jspc' servlet. - * - * This class has no dependencies on Jasper, it uses 2 servlets to integrate. - */ -public abstract class BaseJspLoader { - boolean usePrecompiled = false; - - public static interface JspRuntime { - public void init(ServletContext ctx); - } - - public static interface JspCompiler { - public void compileAndInit(ServletContext ctx, String jspUri, - ServletConfig cfg, - String classPath, String pkg); - } - - /** - * Load the proxied jsp, if any. - * @param config - * @throws ServletException - * @throws IOException - */ - public Servlet loadProxy(String jspFile, - ServletContext ctx, - ServletConfig config) throws ServletException, IOException { - synchronized(this.getClass()) { - // So we don't have a direct dep on jasper... - Object attribute = ctx.getAttribute("jasper.jspRuntimeContext"); - if (attribute == null) { - try { - Class jsprt = Class.forName("org.apache.tomcat.servlets.jspc.JasperRuntime"); - JspRuntime rt = (JspRuntime)jsprt.newInstance(); - rt.init(ctx); - } catch (Throwable t) { - t.printStackTrace(); - return null; - } - } - } - String mangledClass = getClassName(ctx, jspFile ); - - // TODO: reloading filter: get the class file, - // compare with jsp file, use dependants - - - HttpServlet jsp = null; - Class jspC = null; - - String cp = getClassPath(ctx); - ClassLoader cl = getClassLoader(ctx); - - // Already created - if (usePrecompiled) { - try { - jspC = cl.loadClass(mangledClass); - } catch( Throwable t ) { - //t.printStackTrace(); - // Not found - first try - } - } - - if (jspC == null) { - System.err.println("Recompile " + jspFile); - // Class not found - needs to be compiled - compileAndInitPage(ctx, jspFile, config, cp); - } else { - System.err.println("Pre-compiled " + jspFile); - } - - if( jspC == null ) { - try { - jspC = cl.loadClass(mangledClass); - } catch( Throwable t ) { - //t.printStackTrace(); - } - } - if (jspC == null) { - throw new ServletException("Class not found " + mangledClass); - } - - try { - jsp=(HttpServlet)jspC.newInstance(); - } catch( Throwable t ) { - t.printStackTrace(); - } - jsp.init(config); - return jsp; - } - - public ClassLoader getClassLoader(ServletContext ctx) { - return null; - } - - public String getClassPath(ServletContext ctx) { - return null; - } - - protected void compileAndInitPage(ServletContext ctx, - String jspUri, - ServletConfig cfg, - String classPath) - throws ServletException, IOException { - try { - Class jsprt = Class.forName("org.apache.tomcat.servlets.jspc.JspcServlet"); - JspCompiler rt = (JspCompiler) jsprt.newInstance(); - rt.compileAndInit(ctx, jspUri, cfg, classPath, getPackage(ctx, jspUri)); - } catch (Throwable t) { - t.printStackTrace(); - } - } - - public boolean needsReload(String jspFile, Servlet s) { - return false; - } - - public String getPackage(ServletContext ctx, String jspUri) { - String ver = "v" + ctx.getMajorVersion() + - ctx.getMinorVersion(); - - int iSep = jspUri.lastIndexOf('/') + 1; - String className = makeJavaIdentifier(jspUri.substring(iSep)); - String basePackageName = JSP_PACKAGE_NAME; - - iSep--; - String derivedPackageName = (iSep > 0) ? - makeJavaPackage(jspUri.substring(1,iSep)) : ""; - - return ver + "." + basePackageName; - - } - - /** Convert an identifier to a class name, using jasper conventions - * @param ctx - * - * @param jspUri a relative JSP file - * @return class name that would be generated by jasper - */ - public String getClassName( ServletContext ctx, String jspUri ) { - // Generated code is different for different servlet API versions - // We could have a context running in both 2.5 and 3.0 with precompiled - // jsps - String ver = "v" + ctx.getMajorVersion() + - ctx.getMinorVersion(); - - int iSep = jspUri.lastIndexOf('/') + 1; - String className = makeJavaIdentifier(jspUri.substring(iSep)); - String basePackageName = JSP_PACKAGE_NAME; - - iSep--; - String derivedPackageName = (iSep > 0) ? - makeJavaPackage(jspUri.substring(1,iSep)) : ""; - if (derivedPackageName.length() == 0) { - return basePackageName + "." + className; - } - - return ver + "." + basePackageName + '.' + derivedPackageName + "." + - className; - } - - // ------------- Copied from jasper --------------------------- - - private static final String JSP_PACKAGE_NAME = "org.apache.jsp"; - - private static final String makeJavaIdentifier(String identifier) { - StringBuffer modifiedIdentifier = - new StringBuffer(identifier.length()); - if (!Character.isJavaIdentifierStart(identifier.charAt(0))) { - modifiedIdentifier.append('_'); - } - for (int i = 0; i < identifier.length(); i++) { - char ch = identifier.charAt(i); - if (Character.isJavaIdentifierPart(ch) && ch != '_') { - modifiedIdentifier.append(ch); - } else if (ch == '.') { - modifiedIdentifier.append('_'); - } else { - modifiedIdentifier.append(mangleChar(ch)); - } - } - if (isJavaKeyword(modifiedIdentifier.toString())) { - modifiedIdentifier.append('_'); - } - return modifiedIdentifier.toString(); - } - - private static final String javaKeywords[] = { - "abstract", "assert", "boolean", "break", "byte", "case", - "catch", "char", "class", "const", "continue", - "default", "do", "double", "else", "enum", "extends", - "final", "finally", "float", "for", "goto", - "if", "implements", "import", "instanceof", "int", - "interface", "long", "native", "new", "package", - "private", "protected", "public", "return", "short", - "static", "strictfp", "super", "switch", "synchronized", - "this", "throws", "transient", "try", "void", - "volatile", "while" }; - - private static final String makeJavaPackage(String path) { - String classNameComponents[] = split(path,"/"); - StringBuffer legalClassNames = new StringBuffer(); - for (int i = 0; i < classNameComponents.length; i++) { - legalClassNames.append(makeJavaIdentifier(classNameComponents[i])); - if (i < classNameComponents.length - 1) { - legalClassNames.append('.'); - } - } - return legalClassNames.toString(); - } - - private static final String [] split(String path, String pat) { - Vector comps = new Vector(); - int pos = path.indexOf(pat); - int start = 0; - while( pos >= 0 ) { - if(pos > start ) { - String comp = path.substring(start,pos); - comps.add(comp); - } - start = pos + pat.length(); - pos = path.indexOf(pat,start); - } - if( start < path.length()) { - comps.add(path.substring(start)); - } - String [] result = new String[comps.size()]; - for(int i=0; i < comps.size(); i++) { - result[i] = (String)comps.elementAt(i); - } - return result; - } - - - /** - * Test whether the argument is a Java keyword - */ - private static boolean isJavaKeyword(String key) { - int i = 0; - int j = javaKeywords.length; - while (i < j) { - int k = (i+j)/2; - int result = javaKeywords[k].compareTo(key); - if (result == 0) { - return true; - } - if (result < 0) { - i = k+1; - } else { - j = k; - } - } - return false; - } - - /** - * Mangle the specified character to create a legal Java class name. - */ - private static final String mangleChar(char ch) { - char[] result = new char[5]; - result[0] = '_'; - result[1] = Character.forDigit((ch >> 12) & 0xf, 16); - result[2] = Character.forDigit((ch >> 8) & 0xf, 16); - result[3] = Character.forDigit((ch >> 4) & 0xf, 16); - result[4] = Character.forDigit(ch & 0xf, 16); - return new String(result); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/PreCompileFilter.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/PreCompileFilter.java deleted file mode 100644 index eb3be81cf..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/PreCompileFilter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.jsp; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; - -/** - * Filter for JSPs to support 'preCompile' support. - * This is a silly feature, can and should be left out in prod. - * It needs to be used in the default config to pass the tests. - * - * @author Costin Manolache - */ -public class PreCompileFilter extends HttpServlet { - // Copied from jasper.Constants to avoid compile dep - /** - * The query parameter that causes the JSP engine to just - * pregenerated the servlet but not invoke it. - */ - public static final String PRECOMPILE = - System.getProperty("org.apache.jasper.Constants.PRECOMPILE", "jsp_precompile"); - - /** - * If called from a servlet, compile the servlet and init it. - */ - public void init(ServletConfig arg0) throws ServletException { - super.init(arg0); - } - - boolean preCompile(HttpServletRequest request) throws ServletException { - String queryString = request.getQueryString(); - if (queryString == null) { - return (false); - } - int start = queryString.indexOf(PRECOMPILE); - if (start < 0) { - return (false); - } - queryString = - queryString.substring(start + PRECOMPILE.length()); - if (queryString.length() == 0) { - return (true); // ?jsp_precompile - } - if (queryString.startsWith("&")) { - return (true); // ?jsp_precompile&foo=bar... - } - if (!queryString.startsWith("=")) { - return (false); // part of some other name or value - } - int limit = queryString.length(); - int ampersand = queryString.indexOf("&"); - if (ampersand > 0) { - limit = ampersand; - } - String value = queryString.substring(1, limit); - if (value.equals("true")) { - return (true); // ?jsp_precompile=true - } else if (value.equals("false")) { - // Spec says if jsp_precompile=false, the request should not - // be delivered to the JSP page; the easiest way to implement - // this is to set the flag to true, and precompile the page anyway. - // This still conforms to the spec, since it says the - // precompilation request can be ignored. - return (true); // ?jsp_precompile=false - } else { - throw new ServletException("Cannot have request parameter " + - PRECOMPILE + " set to " + value); - } - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/SingleThreadedProxyServlet.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/SingleThreadedProxyServlet.java deleted file mode 100644 index 83f325720..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/SingleThreadedProxyServlet.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.jsp; - -import java.util.Stack; - -import javax.servlet.Servlet; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** For SingleThreadedServlet support. - * - * This is container independent. - * - * Will maintain a pool of servlets, etc - * - * @author Costin Manolache - */ -public class SingleThreadedProxyServlet extends HttpServlet { - - private Class classClass = null; - private transient boolean singleThreadModel = false; - /** - * Stack containing the STM instances. - */ - private transient Stack instancePool = null; - - /** - * Extra params: - * - servlet-class - the class of the single-threaded servlet - * - - * - */ - public void init() { - - } - - public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException { - synchronized (instancePool) { - if (instancePool.isEmpty()) { - try { - Servlet newServlet = null; // loadServlet(); - - // todo: should we init each of them ? - - newServlet.service(req, res); - - - } catch (Throwable e) { - throw new ServletException("allocate ", - e); - } - } - Servlet s = (Servlet) instancePool.pop(); - } - - - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/WildcardTemplateServlet.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/WildcardTemplateServlet.java deleted file mode 100644 index 41a98e515..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/WildcardTemplateServlet.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.jsp; - -import java.io.IOException; -import java.util.HashMap; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -/** - * - * @author Costin Manolache - */ -public class WildcardTemplateServlet extends HttpServlet { - - // for the '*.jsp' case - need to keep track of the jsps - HashMap jsps=new HashMap(); - - BaseJspLoader mapper; - - /** - * If called from a servlet, compile the servlet and init it. - */ - public void init(ServletConfig config) throws ServletException { - super.init(config); - String mapperCN = config.getInitParameter("mapper"); - if (mapperCN == null) { - throw new UnavailableException("can't create mapper"); - } - try { - Class c = Class.forName(mapperCN); - mapper = (BaseJspLoader) c.newInstance(); - } catch (Throwable t) { - throw new UnavailableException("can't create mapper"); - } - } - - // TODO: use context extensions to register the servlet as if it would be - // loaded from web.xml - - protected void service(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException - { - // This is a *.jsp mapping. - String jspPath = null; - - /** - * Magic to get the jsp file from the mappings or container - */ - if (jspPath == null) { - jspPath = (String)req.getAttribute("org.apache.catalina.jsp_file"); - } - if (jspPath == null) { - // RequestDispatcher.include() - jspPath = (String)req.getAttribute("javax.servlet.include.servlet_path"); - if (jspPath != null) { - String pathInfo = (String)req.getAttribute("javax.servlet.include.path_info"); - if (pathInfo != null) { - jspPath += pathInfo; - } - } else { - jspPath = req.getServletPath(); - String pathInfo = req.getPathInfo(); - if (pathInfo != null) { - jspPath += pathInfo; - } - } - } - - // now we should have jspUri == the path to the jsp. - Servlet realJspServlet = jsps.get(jspPath); - - // TODO: support reload - - if (realJspServlet == null) { - realJspServlet = mapper.loadProxy(jspPath, - getServletContext(), getServletConfig()); - if (realJspServlet != null) { - jsps.put(jspPath, realJspServlet); - } else { - throw new ServletException(jspPath + " not found"); - } - } - - realJspServlet.service(req, res); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JasperRuntime.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JasperRuntime.java deleted file mode 100644 index df8e8028f..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JasperRuntime.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.jspc; - -import java.io.File; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.jasper.Options; -import org.apache.jasper.compiler.JspConfig; -import org.apache.jasper.compiler.JspRuntimeContext; -import org.apache.jasper.compiler.TagPluginManager; -import org.apache.jasper.compiler.TldLocationsCache; -import org.apache.tomcat.servlets.jsp.BaseJspLoader; - -public class JasperRuntime extends HttpServlet implements BaseJspLoader.JspRuntime { - - // TODO: add DefaultAnnotationProcessor - // TODO: implement the options - private JspRuntimeContext jspRuntimeContext; - - public void init(ServletConfig cfg) throws ServletException { - super.init(cfg); - ServletContext ctx = cfg.getServletContext(); - init(ctx); - } - - public void doGet(HttpServletRequest req, HttpServletResponse res) { - - } - - @Override - public void init(ServletContext ctx) { - jspRuntimeContext = new JspRuntimeContext(ctx, new Options() { - @Override - public boolean genStringAsCharArray() { - return false; - } - - @Override - public Map getCache() { - return null; - } - - @Override - public int getCheckInterval() { - return 0; - } - - @Override - public boolean getClassDebugInfo() { - return false; - } - - @Override - public String getClassPath() { - return null; - } - - @Override - public String getCompiler() { - return null; - } - - @Override - public String getCompilerClassName() { - return null; - } - - @Override - public String getCompilerSourceVM() { - return null; - } - - @Override - public String getCompilerTargetVM() { - return null; - } - - @Override - public boolean getDevelopment() { - return false; - } - - @Override - public boolean getDisplaySourceFragment() { - return false; - } - - @Override - public boolean getErrorOnUseBeanInvalidClassAttribute() { - return false; - } - - @Override - public boolean getFork() { - return false; - } - - @Override - public String getIeClassId() { - return null; - } - - @Override - public String getJavaEncoding() { - return null; - } - - @Override - public JspConfig getJspConfig() { - return null; - } - - @Override - public boolean getKeepGenerated() { - return false; - } - - @Override - public boolean getMappedFile() { - return false; - } - - @Override - public int getModificationTestInterval() { - return 0; - } - - @Override - public File getScratchDir() { - return null; - } - - public boolean getSendErrorToClient() { - return false; - } - - @Override - public TagPluginManager getTagPluginManager() { - return null; - } - - @Override - public TldLocationsCache getTldLocationsCache() { - return null; - } - - @Override - public boolean getTrimSpaces() { - return false; - } - - @Override - public boolean isCaching() { - return false; - } - - @Override - public boolean isPoolingEnabled() { - return false; - } - - @Override - public boolean isSmapDumped() { - return false; - } - - @Override - public boolean isSmapSuppressed() { - return false; - } - - @Override - public boolean isXpoweredBy() { - return false; - } - }); - - ctx.setAttribute("jasper.jspRuntimeContext", jspRuntimeContext); - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JspcServlet.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JspcServlet.java deleted file mode 100644 index f2b710568..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/jspc/JspcServlet.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.jspc; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.jasper.JasperException; -import org.apache.jasper.JspC; -import org.apache.tomcat.servlets.jsp.BaseJspLoader; - -/** - * The actual compiler. Maps and compile a jsp-file to a class. - */ -public class JspcServlet extends HttpServlet implements BaseJspLoader.JspCompiler { - - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException { - - // TODO: allow only local calls ? - - // relative to context - String jspFiles = req.getParameter("jspFiles"); - String classPath = req.getParameter("classPath"); - String pkg = req.getParameter("pkg"); - - compileAndInit(getServletContext(), - jspFiles, getServletConfig(), classPath, pkg); - } - - @Override - public void compileAndInit(ServletContext ctx, String jspFiles, - ServletConfig cfg, String classPath, String pkg) { - - if (jspFiles.startsWith("/")) { - jspFiles = jspFiles.substring(1); - } - String baseDir = ctx.getRealPath("/"); - - JspC jspc = new JspC(); - - jspc.setUriroot(baseDir); - jspc.setTrimSpaces(false); - jspc.setPoolingEnabled(true); - jspc.setErrorOnUseBeanInvalidClassAttribute(false); - jspc.setClassDebugInfo(true); - jspc.setCaching(true); - jspc.setSmapDumped(true); - jspc.setGenStringAsCharArray(true); - - jspc.setJspFiles(jspFiles); - - jspc.setVerbose(10); - - jspc.setPackage(pkg); - - jspc.setOutputDir(baseDir + "WEB-INF/tmp"); - jspc.setCompile(true); - //jspc.setCompiler("jdt"); - jspc.setClassPath(classPath); - - try { - jspc.execute(); - } catch (JasperException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/AccessFilter.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/AccessFilter.java deleted file mode 100644 index a49d6870f..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/AccessFilter.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - - -import java.io.IOException; -import java.security.Principal; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - - -/** - * Access control. - * - * In Catalina, the AuthenticatorBase.invoke() will apply the security - * filters based on LoginConfig. All constraints are applied in the - * valve. For sessions - the Principal will be cached. The TTL needs to be - * indicated by the authenticator. - * - * This works differently - it's a regular filter, could be modified and - * set in web.xml explicitely, or set by the container when reading web.xml - * - * - * Mappings: - * - * /[FORM]/j_security_check ( with j_password, j_username params ) - * -> authentication servlet - * Assert: no other j_security_check mapping - * - * - * For each security rule we define one AccessFilter, configured with the - * right init-params. - * - * 1. For each security_constraint, create a (base) filter named: _access_nnn, - * and add init-params for roles - * - * 1.1 For each web-resource-collection, take the method set, sort it. Create - * one filter for each set of methods, named _access_nnn_methodlist - * - * 2.For each pattern in each web-resource-collection, add a mapping to - * the appropriate filter, at the end of web.xml ( after normal filters - * and servlets ). - * - * - * @author Costin Manolache - */ -public class AccessFilter implements Filter { - - // web-resource-collection: name -> url+method rules - // Since filters don't match method, for each method subset we need a new - // filter instance - private String[] methods; - - // Wildcard on roles - anyone authenticated can access the resource - private boolean allRoles = false; - - // if false - no access control needed. - // if true - must check roles - either allRoles or specific list - private boolean authConstraint = false; - - // roles to check - private String authRoles[] = new String[0]; - - /** - * The user data constraint for this security constraint. Must be NONE, - * INTEGRAL, or CONFIDENTIAL. - */ - private String userConstraint = "NONE"; - - - public void destroy() { - } - - public static class AuthToken { - public String headerValue; // key - public long expiry; - public Principal principal; - } - - Map cachedTokens = new HashMap(); - - UserAuthentication auth; - String method; - - public void doFilter(ServletRequest request, - ServletResponse servletResponse, - FilterChain chain) - throws IOException, ServletException { - - HttpServletResponse res = (HttpServletResponse)servletResponse; - HttpServletRequest req = (HttpServletRequest)request; - - String method = req.getMethod(); - // exclude the context path - String uri = req.getServletPath() + req.getPathInfo(); - - // no authorization or principal not found. - // Call the auth servlet. - // TODO: use URL or RD.include. - - Principal p = auth.authenticate(req, res, method); - // set the principal on req! - if (p == null) { - // couldn't authenticate - response is set. - return; - } else { - // we are ok - cache the response, forward - - chain.doFilter(req, res); - } - - } - - - - public void init(FilterConfig filterConfig) throws ServletException { - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/BasicAuthentication.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/BasicAuthentication.java deleted file mode 100644 index cfcb212cf..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/BasicAuthentication.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - - -/** - * Implements Basic authentication. - */ -public class BasicAuthentication implements UserAuthentication { - - String realm; - - @Override - public Principal authenticate(HttpServletRequest request, - HttpServletResponse response, - String requestedMethod) throws IOException { - - if (realm == null) - realm = request.getServerName() + ":" + request.getServerPort(); - - // Validate any credentials already included with this request - String authorization = request.getHeader("authorization"); - if (authorization != null) { - Principal principal = null; // processDigestHeader(request, authorization); - if (principal != null) { - return principal; - } - } - - String domain = request.getContextPath(); - String authHeader = getAuthenticateHeader(domain, false); - - response.setHeader("WWW-Authenticate", authHeader); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return null; - } - - - /** Generate the auth header - */ - protected String getAuthenticateHeader(String domain, - boolean stale) { - - long currentTime = System.currentTimeMillis(); - return ""; - } - - // ------------------------------------------------------ Protected Methods - - - public Principal authenticate(final String username, String clientDigest, - String nOnce, String nc, String cnonce, - String qop, String realm, - String md5a2) { - - - String serverDigest = null; - - return null; - } - - - @Override - public boolean isUserInRole(HttpServletRequest req, Principal p, String role) { - return false; - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/FormAuthentication.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/FormAuthentication.java deleted file mode 100644 index f17c6a07b..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/FormAuthentication.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - - -/** - * Implements Form authentication. - */ -public class FormAuthentication implements UserAuthentication { - - String realm; - String url; - - @Override - public Principal authenticate(HttpServletRequest request, - HttpServletResponse response, - String requestedMethod) throws IOException { - - if (realm == null) - realm = request.getServerName() + ":" + request.getServerPort(); - - // Validate any credentials already included with this request - String authorization = request.getHeader("authorization"); - if (authorization != null) { - Principal principal = null; // processDigestHeader(request, authorization); - if (principal != null) { - return principal; - } - } - - String domain = request.getContextPath(); - String authHeader = getAuthenticateHeader(domain, false); - - response.setHeader("WWW-Authenticate", authHeader); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return null; - } - - - /** Generate the auth header - */ - protected String getAuthenticateHeader(String domain, - boolean stale) { - - long currentTime = System.currentTimeMillis(); - return ""; - } - - // ------------------------------------------------------ Protected Methods - - - public Principal authenticate(final String username, String clientDigest, - String nOnce, String nc, String cnonce, - String qop, String realm, - String md5a2) { - - - String serverDigest = null; - - return null; - } - - - @Override - public boolean isUserInRole(HttpServletRequest req, Principal p, String role) { - return false; - } - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/IPFilter.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/IPFilter.java deleted file mode 100644 index 8e7634ff0..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/IPFilter.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - - -import java.io.IOException; -import java.util.ArrayList; -import java.util.regex.Pattern; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; - - -/** - * Reimplementation of catalina IP valve. - * - */ -public class IPFilter implements Filter { - /** - * The set of allow regular expressions we will evaluate. - */ - protected Pattern allows[] = new Pattern[0]; - - - /** - * The set of deny regular expressions we will evaluate. - */ - protected Pattern denies[] = new Pattern[0]; - - // --------------------------------------------------------- Public Methods - - public void setAllows(String pattern) { - allows = getPatterns(pattern); - } - - public void setDenies(String pattern) { - denies = getPatterns(pattern); - } - - private Pattern[] getPatterns(String pattern) { - String[] patSplit = pattern.split(","); - ArrayList allowsAL = new ArrayList(); - for( int i=0; i 0) && (allows.length == 0)) { - chain.doFilter(request, response); - return; - } - - // Deny this request - response.sendError(HttpServletResponse.SC_FORBIDDEN); - } - - - public void init(FilterConfig filterConfig) throws ServletException { - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/SimpleUserAuthDB.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/SimpleUserAuthDB.java deleted file mode 100644 index 0a56c95e7..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/SimpleUserAuthDB.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - - -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Properties; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; - -/** - * Load user/passwords from a file. - * - * @author Costin Manolache - */ -public class SimpleUserAuthDB implements UserDB { - - private static final String USER_PREFIX = "u."; - private static final String ROLE_PREFIX = "r."; - - HashMap users = new HashMap(); - HashMap roles = new HashMap(); - - boolean hasMessageDigest = false; - String realm = null; - - public void addUser(String name, String pass) { - users.put(name, pass); - } - - public void addRole(String user, String value) { - String[] userRoles = value.split(","); - roles.put(user, userRoles); - } - - public void setFilename(String fileName) { - - } - - public void init(Properties p) throws ServletException { - } - - public void init(ServletConfig servletConfig) throws ServletException { - Enumeration names = servletConfig.getInitParameterNames(); - while (names.hasMoreElements()) { - String name = (String)names.nextElement(); - String value = servletConfig.getInitParameter(name); - if (name.startsWith(USER_PREFIX)) { - addUser(name.substring(USER_PREFIX.length()), value); - } - if (name.startsWith(ROLE_PREFIX)) { - addRole(name.substring(ROLE_PREFIX.length()), value); - } - } - } - - public void checkAuth(String method, String cookie) { - - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserAuthentication.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserAuthentication.java deleted file mode 100644 index 62b4b9799..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserAuthentication.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - */ -package org.apache.tomcat.servlets.sec; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Plugin for user auth. - * - * This interface should support all common forms of auth, - * including Basic, Digest, Form and various other auth - * standards - the plugin has full control over request and - * response. - * - * Container will verify the security constraints on URLs and - * call this for all URLs that have constraints. The plugin can - * either authenticate and return the principal, or change - * the response - redirect, add headers, send content. - * - * Alternative: a simple Filter can do the same, with some conventions - * to support it ( attributes ). - * - * @author Costin Manolache - */ -public interface UserAuthentication { - - /** - * If req has all the info - return the principal. - * Otherwise set the challenge in response. - * - * @param requestedMethod auth method from web.xml. Spec - * complain plugins must support it. - * @throws IOException - */ - public Principal authenticate(HttpServletRequest req, - HttpServletResponse res, - String requestedMethod) throws IOException; - - - public boolean isUserInRole(HttpServletRequest req, - Principal p, - String role); -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserDB.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserDB.java deleted file mode 100644 index df79e8d71..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserDB.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.sec; - -/** - * Interface to a password/role storage, used by the classes in - * this directory. - * - * @author Costin Manolache - */ -public interface UserDB { - - //public void auth(String user, String md5); -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/HttpSessionImpl.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/HttpSessionImpl.java deleted file mode 100644 index d8fdeb241..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/HttpSessionImpl.java +++ /dev/null @@ -1,786 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.session; - - -import java.io.Serializable; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionAttributeListener; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import javax.servlet.http.HttpSessionContext; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -import org.apache.tomcat.servlets.util.Enumerator; - -/** - * Standard implementation of the Session interface. - * - * This is a minimal, non-serializable HttpSession. You can use a different - * session manager, but you should keep in mind that persistent or distributed - * sessions are a bad thing. - * - * The session is best for caching data across requests, and tracking the - * user flow. For any data you don't want to lose or is worth preserving - - * use a transaction manager, or any form of storage that provides the - * set of ACID characteristics you need. - * - * Even the most sophisticated sessions managers can't guarantee data integrity - * in 100% of cases, and can't notify you of the cases where a replication - * failed. Using such a manager might fool users into making incorrect - * assumptions. Computers and networks do crash at random points, and all - * the theory on transactions exists for a good reason. - * - * Note: this is a user-space implementation, i.e. this can be used in any - * container by using the WebappSessionManager class. - * - * @author Costin Manolache - removed most of the code - * @author Craig R. McClanahan - * @author Sean Legassick - * @author Jon S. Stevens - */ -public class HttpSessionImpl implements HttpSession, Serializable { - - /** - * Type array, used as param to toArray() - */ - protected static final String EMPTY_ARRAY[] = new String[0]; - - /** - * The HTTP session context associated with this session. - */ - protected HttpSessionContext sessionContext = null; - - - /** - * The Manager with which this Session is associated. - */ - protected transient SimpleSessionManager manager = null; - - /** - * The session identifier of this Session. - */ - protected String id = null; - - /** - * The collection of user data attributes associated with this Session. - */ - protected Map attributes = new HashMap(); - - /** - * The time this session was created, in milliseconds since midnight, - * January 1, 1970 GMT. - */ - protected long creationTime = 0L; - - /** - * The last accessed time for this Session. - */ - protected long lastAccessedTime = creationTime; - - /** - * The current accessed time for this session. - */ - protected long thisAccessedTime = creationTime; - - /** - * The maximum time interval, in seconds, between client requests before - * the servlet container may invalidate this session. A negative time - * indicates that the session should never time out. - */ - protected int maxInactiveInterval = -1; - - /** - * The access count for this session - how many requests are using this - * session ( so we can prevent expiry ) - */ - protected transient int accessCount = 0; - - /** - * We are currently processing a session expiration, so bypass - * certain IllegalStateException tests. - */ - protected transient boolean expiring = false; - - - /** - * Flag indicating whether this session is new or not. - */ - protected boolean isNew = false; - - - /** - * Flag indicating whether this session is valid or not. - */ - protected boolean isValid = false; - - - /** Only the manager can create sessions, so it knows about them. - */ - HttpSessionImpl(SimpleSessionManager manager) { - this.manager = manager; - } - - // ---------- API methods --------- - - /** - * Return the session identifier for this session. - */ - public String getId() { - return this.id; - } - - /** - * Return the last time the client sent a request associated with this - * session, as the number of milliseconds since midnight, January 1, 1970 - * GMT. Actions that your application takes, such as getting or setting - * a value associated with the session, do not affect the access time. - */ - public long getLastAccessedTime() { - checkValid(); - return this.lastAccessedTime; - - } - - /** - * Return the maximum time interval, in seconds, between client requests - * before the servlet container will invalidate the session. A negative - * time indicates that the session should never time out. - */ - public int getMaxInactiveInterval() { - return this.maxInactiveInterval; - } - - - /** - * Set the maximum time interval, in seconds, between client requests - * before the servlet container will invalidate the session. A negative - * time indicates that the session should never time out. - * - * @param interval The new maximum interval - */ - public void setMaxInactiveInterval(int interval) { - this.maxInactiveInterval = interval; - if (isValid && interval == 0) { - expire(); - } - } - - /** - * Return the time when this session was created, in milliseconds since - * midnight, January 1, 1970 GMT. - * - * @exception IllegalStateException if this method is called on an - * invalidated session - */ - public long getCreationTime() { - checkValid(); - return this.creationTime; - - } - - public ServletContext getServletContext() { - if (manager == null) - return null; // Should never happen - ServletContext context = (ServletContext)manager.getContext(); - return context; - } - - - public HttpSessionContext getSessionContext() { - if (sessionContext == null) - sessionContext = new StandardSessionContext(); - return (sessionContext); - } - - /** - * Return the object bound with the specified name in this session, or - * null if no object is bound with that name. - * - * @param name Name of the attribute to be returned - * - * @exception IllegalStateException if this method is called on an - * invalidated session - */ - public Object getAttribute(String name) { - checkValid(); - return attributes.get(name); - } - - - /** - * Return an Enumeration of String objects - * containing the names of the objects bound to this session. - * - * @exception IllegalStateException if this method is called on an - * invalidated session - */ - public Enumeration getAttributeNames() { - checkValid(); - return new Enumerator(attributes.keySet(), true); - } - - - /** - * Return the object bound with the specified name in this session, or - * null if no object is bound with that name. - * - * @param name Name of the value to be returned - * - * @exception IllegalStateException if this method is called on an - * invalidated session - * - * @deprecated As of Version 2.2, this method is replaced by - * getAttribute() - */ - public Object getValue(String name) { - return (getAttribute(name)); - } - - - /** - * Return the set of names of objects bound to this session. If there - * are no such objects, a zero-length array is returned. - * - * @exception IllegalStateException if this method is called on an - * invalidated session - * - * @deprecated As of Version 2.2, this method is replaced by - * getAttributeNames() - */ - public String[] getValueNames() { - checkValid(); - return keys(); // same, but no check for validity - } - - - /** - * Invalidates this session and unbinds any objects bound to it. - * - * @exception IllegalStateException if this method is called on - * an invalidated session - */ - public void invalidate() { - checkValid(); - expire(); - } - - - /** - * Return true if the client does not yet know about the - * session, or if the client chooses not to join the session. For - * example, if the server used only cookie-based sessions, and the client - * has disabled the use of cookies, then a session would be new on each - * request. - * - * @exception IllegalStateException if this method is called on an - * invalidated session - */ - public boolean isNew() { - checkValid(); - return (this.isNew); - } - - public void putValue(String name, Object value) { - setAttribute(name, value); - } - - public void removeAttribute(String name) { - checkValid(); - removeAttributeInternal(name, true); - } - - public void removeValue(String name) { - removeAttribute(name); - } - - - /** - * Bind an object to this session, using the specified name. If an object - * of the same name is already bound to this session, the object is - * replaced. - *

- * After this method executes, and if the object implements - * HttpSessionBindingListener, the container calls - * valueBound() on the object. - * - * @param name Name to which the object is bound, cannot be null - * @param value Object to be bound, cannot be null - * - * @exception IllegalArgumentException if an attempt is made to add a - * non-serializable object in an environment marked distributable. - * @exception IllegalStateException if this method is called on an - * invalidated session - */ - public void setAttribute(String name, Object value) { - // Name cannot be null - if (name == null) return; - - // Null value is the same as removeAttribute() - if (value == null) { - removeAttribute(name); - return; - } - - checkValid(); - - if ((manager != null) && manager.getDistributable() && - !(value instanceof Serializable)) - throw new IllegalArgumentException("setAttribute() not serializable"); - - // Construct an event with the new value - HttpSessionBindingEvent event = null; - - // Call the valueBound() method if necessary - if (value instanceof HttpSessionBindingListener) { - // Don't call any notification if replacing with the same value - Object oldValue = attributes.get(name); - if (value != oldValue) { - event = new HttpSessionBindingEvent(getSession(), name, value); - try { - ((HttpSessionBindingListener) value).valueBound(event); - } catch (Throwable t){ - manager.log.log(Level.SEVERE, "Listener valueBound() error", t); - } - } - } - - // Replace or add this attribute - Object unbound = attributes.put(name, value); - - // Call the valueUnbound() method if necessary - if ((unbound != null) && (unbound != value) && - (unbound instanceof HttpSessionBindingListener)) { - try { - ((HttpSessionBindingListener) unbound).valueUnbound - (new HttpSessionBindingEvent(getSession(), name)); - } catch (Throwable t) { - manager.log.log(Level.SEVERE, "Listener valueUnbound()", t); - } - } - - // Notify interested application event listeners - ServletContext context = manager.getContext(); - List listeners = manager.getEventListeners(); - if (listeners.size() == 0) - return; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof HttpSessionAttributeListener)) - continue; - HttpSessionAttributeListener listener = - (HttpSessionAttributeListener) listeners.get(i); - try { - if (unbound != null) { - if (event == null) { - event = new HttpSessionBindingEvent - (getSession(), name, unbound); - } - listener.attributeReplaced(event); - } else { - if (event == null) { - event = new HttpSessionBindingEvent - (getSession(), name, value); - } - listener.attributeAdded(event); - } - } catch (Throwable t) { - manager.log.log(Level.SEVERE, "Listener attibuteAdded/Replaced()", t); - } - } - - } - - // -------- Implementation - interactions with SessionManager ----- - - /** - * Set the creation time for this session. This method is called by the - * Manager when an existing Session instance is reused. - */ - public void setCreationTime(long time) { - this.creationTime = time; - this.lastAccessedTime = time; - this.thisAccessedTime = time; - } - - /** - * Set the session identifier for this session and notify listeners about - * new session - * - * @param id The new session identifier - */ - public void setId(String id) { - - if ((this.id != null) && (manager != null)) - manager.remove(this); - - this.id = id; - - if (manager != null) - manager.add(this); - tellNew(); - } - - - /** - * Inform the listeners about the new session. - */ - public void tellNew() { - // Notify interested application event listeners - ServletContext context = manager.getContext(); - List listeners = manager.getEventListeners(); - if (listeners.size() > 0) { - HttpSessionEvent event = - new HttpSessionEvent(getSession()); - for (int i = 0; i < listeners.size(); i++) { - Object listenerObj = listeners.get(i); - if (!(listenerObj instanceof HttpSessionListener)) - continue; - HttpSessionListener listener = - (HttpSessionListener) listenerObj; - try { - listener.sessionCreated(event); - } catch (Throwable t) { - manager.log.log(Level.SEVERE, "listener.sessionCreated()", t); - } - } - } - - } - - /** - * Return the Manager within which this Session is valid. - */ - public SimpleSessionManager getManager() { - return (this.manager); - } - - - - /** - * Set the isNew flag for this session. - * - * @param isNew The new value for the isNew flag - */ - public void setNew(boolean isNew) { - this.isNew = isNew; - } - - public HttpSession getSession() { - return this; - } - - private void checkValid() { - if ( !isValid() ) { - throw new IllegalStateException("checkValid"); - } - } - - /** - * Return the isValid flag for this session. - */ - public boolean isValid() { - if (this.expiring) { - return true; - } - if (!this.isValid ) { - return false; - } - if (accessCount > 0) { - return true; - } - if (maxInactiveInterval >= 0) { - long timeNow = System.currentTimeMillis(); - int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L); - if (timeIdle >= maxInactiveInterval) { - expire(true); - } - } - return this.isValid; - } - - public void setValid(boolean isValid) { - this.isValid = isValid; - } - - /** - * Update the accessed time information for this session. This method - * should be called by the context when a request comes in for a particular - * session, even if the application does not reference it. - */ - public void access() { - this.lastAccessedTime = this.thisAccessedTime; - this.thisAccessedTime = System.currentTimeMillis(); - - evaluateIfValid(); - accessCount++; - } - - - /** - * End the access. - */ - public void endAccess() { - isNew = false; - accessCount--; - } - - /** - * Perform the internal processing required to invalidate this session, - * without triggering an exception if the session has already expired. - */ - public void expire() { - expire(true); - } - - - /** - * Perform the internal processing required to invalidate this session, - * without triggering an exception if the session has already expired. - * - * @param notify Should we notify listeners about the demise of - * this session? - */ - public void expire(boolean notify) { - - // Mark this session as "being expired" if needed - if (expiring) - return; - - synchronized (this) { - - if (manager == null) - return; - - expiring = true; - - // Notify interested application event listeners - // FIXME - Assumes we call listeners in reverse order - ServletContext context = manager.getContext(); - List listeners = manager.getEventListeners(); - if (notify && (listeners.size() > 0)) { - HttpSessionEvent event = - new HttpSessionEvent(getSession()); - for (int i = 0; i < listeners.size(); i++) { - Object listenerObj = listeners.get(i); - int j = (listeners.size() - 1) - i; - if (!(listenerObj instanceof HttpSessionListener)) - continue; - HttpSessionListener listener = - (HttpSessionListener) listenerObj; - try { - listener.sessionDestroyed(event); - } catch (Throwable t) { - manager.log.log(Level.SEVERE, "listener.sessionDestroyed", t); - } - } - } - accessCount = 0; - isValid = false; - - /* - * Compute how long this session has been alive, and update - * session manager's related properties accordingly - */ - long timeNow = System.currentTimeMillis(); - int timeAlive = (int) ((timeNow - creationTime)/1000); - manager.addExpiredSession(timeAlive); - - // Remove this session from our manager's active sessions - manager.remove(this); - - expiring = false; - - // Unbind any objects associated with this session - String keys[] = keys(); - for (int i = 0; i < keys.length; i++) - removeAttributeInternal(keys[i], notify); - } - } - - - /** - * Release all object references, and initialize instance variables, in - * preparation for reuse of this object. - */ - public void recycle() { - - // Reset the instance variables associated with this Session - attributes.clear(); - creationTime = 0L; - expiring = false; - id = null; - lastAccessedTime = 0L; - maxInactiveInterval = -1; - accessCount = 0; - isNew = false; - isValid = false; - manager = null; - - } - - /** - * Return a string representation of this object. - */ - public String toString() { - - StringBuilder sb = new StringBuilder(); - sb.append("StandardSession["); - sb.append(id); - sb.append("]"); - return (sb.toString()); - } - - protected void evaluateIfValid() { - /* - * If this session has expired or is in the process of expiring or - * will never expire, return - */ - if (!this.isValid || expiring || maxInactiveInterval < 0) - return; - - isValid(); - - } - - /** - * Return the names of all currently defined session attributes - * as an array of Strings. If there are no defined attributes, a - * zero-length array is returned. - */ - protected String[] keys() { - return ((String[]) attributes.keySet().toArray(EMPTY_ARRAY)); - } - - - /** - * Remove the object bound with the specified name from this session. If - * the session does not have an object bound with this name, this method - * does nothing. - *

- * After this method executes, and if the object implements - * HttpSessionBindingListener, the container calls - * valueUnbound() on the object. - * - * @param name Name of the object to remove from this session. - * @param notify Should we notify interested listeners that this - * attribute is being removed? - */ - protected void removeAttributeInternal(String name, boolean notify) { - // Remove this attribute from our collection - Object value = attributes.remove(name); - - // Do we need to do valueUnbound() and attributeRemoved() notification? - if (!notify || (value == null)) { - return; - } - - // Call the valueUnbound() method if necessary - HttpSessionBindingEvent event = null; - if (value instanceof HttpSessionBindingListener) { - event = new HttpSessionBindingEvent(getSession(), name, value); - ((HttpSessionBindingListener) value).valueUnbound(event); - } - - // Notify interested application event listeners - ServletContext context = manager.getContext(); - List listeners = manager.getEventListeners(); - if (listeners.size() == 0) - return; - for (int i = 0; i < listeners.size(); i++) { - if (!(listeners.get(i) instanceof HttpSessionAttributeListener)) - continue; - HttpSessionAttributeListener listener = - (HttpSessionAttributeListener) listeners.get(i); - try { - if (event == null) { - event = new HttpSessionBindingEvent - (getSession(), name, value); - } - listener.attributeRemoved(event); - } catch (Throwable t) { - manager.log.log(Level.SEVERE, "listener.attributeRemoved", t); - } - } - - } - -} - - -// ------------------------------------------------------------ Protected Class - - -/** - * This class is a dummy implementation of the HttpSessionContext - * interface, to conform to the requirement that such an object be returned - * when HttpSession.getSessionContext() is called. - * - * @author Craig R. McClanahan - * - * @deprecated As of Java Servlet API 2.1 with no replacement. The - * interface will be removed in a future version of this API. - */ - -final class StandardSessionContext implements HttpSessionContext { - - - protected HashMap dummy = new HashMap(); - - /** - * Return the session identifiers of all sessions defined - * within this context. - * - * @deprecated As of Java Servlet API 2.1 with no replacement. - * This method must return an empty Enumeration - * and will be removed in a future version of the API. - */ - public Enumeration getIds() { - - return (new Enumerator(dummy)); - - } - - - /** - * Return the HttpSession associated with the - * specified session identifier. - * - * @param id Session identifier for which to look up a session - * - * @deprecated As of Java Servlet API 2.1 with no replacement. - * This method must return null and will be removed in a - * future version of the API. - */ - public HttpSession getSession(String id) { - - return (null); - - } - - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/RandomGenerator.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/RandomGenerator.java deleted file mode 100644 index 6bd1a338e..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/RandomGenerator.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.session; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Random; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Generates random IDs, useable as cookies. - * - * Based on code from tomcat session manager - but general purpose. - * Can use /dev/urandom or similar file. - * - * - */ -public class RandomGenerator { - protected DataInputStream randomIS=null; - protected String devRandomSource="/dev/urandom"; - - private static final Logger log = Logger.getLogger(RandomGenerator.class.getName()); - - /** - * The message digest algorithm to be used when generating session - * identifiers. This must be an algorithm supported by the - * java.security.MessageDigest class on your platform. - */ - protected String algorithm = "MD5"; - - /** - * The session id length of Sessions created by this Manager. - */ - protected int sessionIdLength = 16; - - - /** - * Return the MessageDigest implementation to be used when - * creating session identifiers. - */ - protected MessageDigest digest = null; - - public String jvmRoute; - - /** - * A String initialization parameter used to increase the entropy of - * the initialization of our random number generator. - */ - protected String entropy = null; - - /** - * A random number generator to use when generating session identifiers. - */ - protected Random random = null; - - /** - * Return the message digest algorithm for this Manager. - */ - public String getAlgorithm() { - return (this.algorithm); - } - - public void init() { - // Initialize random number generation - getRandomBytes(new byte[16]); - } - - - /** - * Set the message digest algorithm for this Manager. - * - * @param algorithm The new message digest algorithm - */ - public void setAlgorithm(String algorithm) { - this.algorithm = algorithm; - } - - /** - * Return the MessageDigest object to be used for calculating - * session identifiers. If none has been created yet, initialize - * one the first time this method is called. - */ - public synchronized MessageDigest getDigest() { - - if (this.digest == null) { - long t1=System.currentTimeMillis(); - try { - this.digest = MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - log.log(Level.SEVERE, "Algorithm not found", e); - try { - this.digest = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException f) { - log.log(Level.SEVERE, "No message digest available", f); - this.digest = null; - } - } - long t2=System.currentTimeMillis(); - if( log.isLoggable(Level.FINEST) ) - log.finest("getDigest() " + (t2-t1)); - } - - return (this.digest); - - } - - /** - * Generate and return a new session identifier. - */ - public synchronized String generateSessionId() { - - byte random[] = new byte[16]; - String result = null; - - // Render the result as a String of hexadecimal digits - StringBuilder buffer = new StringBuilder(); - int resultLenBytes = 0; - - while (resultLenBytes < this.sessionIdLength) { - getRandomBytes(random); - random = getDigest().digest(random); - for (int j = 0; - j < random.length && resultLenBytes < this.sessionIdLength; - j++) { - byte b1 = (byte) ((random[j] & 0xf0) >> 4); - byte b2 = (byte) (random[j] & 0x0f); - if (b1 < 10) - buffer.append((char) ('0' + b1)); - else - buffer.append((char) ('A' + (b1 - 10))); - if (b2 < 10) - buffer.append((char) ('0' + b2)); - else - buffer.append((char) ('A' + (b2 - 10))); - resultLenBytes++; - } - } - if (jvmRoute != null) { - buffer.append('.').append(jvmRoute); - } - result = buffer.toString(); - return (result); - - } - - protected void getRandomBytes(byte bytes[]) { - // Generate a byte array containing a session identifier - if (devRandomSource != null && randomIS == null) { - setRandomFile(devRandomSource); - } - if (randomIS != null) { - try { - int len = randomIS.read(bytes); - if (len == bytes.length) { - return; - } - } catch (Exception ex) { - // Ignore - } - devRandomSource = null; - - try { - randomIS.close(); - } catch (Exception e) { - log.warning("Failed to close randomIS."); - } - - randomIS = null; - } - getRandom().nextBytes(bytes); - } - - /** - * Return the random number generator instance we should use for - * generating session identifiers. If there is no such generator - * currently defined, construct and seed a new one. - */ - public Random getRandom() { - if (this.random == null) { - // Calculate the new random number generator seed - long seed = System.currentTimeMillis(); - long t1 = seed; - char entropy[] = getEntropy().toCharArray(); - for (int i = 0; i < entropy.length; i++) { - long update = ((byte) entropy[i]) << ((i % 8) * 8); - seed ^= update; - } - try { - // Construct and seed a new random number generator - Class clazz = Class.forName(randomClass); - this.random = (Random) clazz.newInstance(); - this.random.setSeed(seed); - } catch (Exception e) { - // Fall back to the simple case - log.log(Level.SEVERE, "Failed to create random " + randomClass, e); - this.random = new java.util.Random(); - this.random.setSeed(seed); - } - if(log.isLoggable(Level.FINEST)) { - long t2=System.currentTimeMillis(); - if( (t2-t1) > 100 ) - log.finest("Init random: " + " " + (t2-t1)); - } - } - - return (this.random); - - } - - /** - * Return the entropy increaser value, or compute a semi-useful value - * if this String has not yet been set. - */ - public String getEntropy() { - - // Calculate a semi-useful value if this has not been set - if (this.entropy == null) { - // Use APR to get a crypto secure entropy value - byte[] result = new byte[32]; - boolean apr = false; - try { - String methodName = "random"; - Class paramTypes[] = new Class[2]; - paramTypes[0] = result.getClass(); - paramTypes[1] = int.class; - Object paramValues[] = new Object[2]; - paramValues[0] = result; - paramValues[1] = new Integer(32); - Method method = Class.forName("org.apache.tomcat.jni.OS") - .getMethod(methodName, paramTypes); - method.invoke(null, paramValues); - apr = true; - } catch (Throwable t) { - // Ignore - } - if (apr) { - setEntropy(new String(result)); - } else { - setEntropy(this.toString()); - } - } - - return (this.entropy); - - } - - - /** - * Set the entropy increaser value. - * - * @param entropy The new entropy increaser value - */ - public void setEntropy(String entropy) { - this.entropy = entropy; - } - - - /** - * Return the random number generator class name. - */ - public String getRandomClass() { - - return (this.randomClass); - - } - - - /** - * Set the random number generator class name. - * - * @param randomClass The new random number generator class name - */ - public void setRandomClass(String randomClass) { - this.randomClass = randomClass; - } - - /** - * The Java class name of the random number generator class to be used - * when generating session identifiers. - */ - protected String randomClass = "java.security.SecureRandom"; - /** - * Use /dev/random-type special device. This is new code, but may reduce - * the big delay in generating the random. - * - * You must specify a path to a random generator file. Use /dev/urandom - * for linux ( or similar ) systems. Use /dev/random for maximum security - * ( it may block if not enough "random" exist ). You can also use - * a pipe that generates random. - * - * The code will check if the file exists, and default to java Random - * if not found. There is a significant performance difference, very - * visible on the first call to getSession ( like in the first JSP ) - * - so use it if available. - */ - public void setRandomFile( String s ) { - // as a hack, you can use a static file - and genarate the same - // session ids ( good for strange debugging ) - try{ - devRandomSource=s; - File f=new File( devRandomSource ); - if( ! f.exists() ) return; - randomIS= new DataInputStream( new FileInputStream(f)); - randomIS.readLong(); -// if( log.isDebugEnabled() ) -// log.debug( "Opening " + devRandomSource ); - } catch( IOException ex ) { - try { - randomIS.close(); - } catch (Exception e) { - log.warning("Failed to close randomIS."); - } - - randomIS=null; - } - } - - public String getRandomFile() { - return devRandomSource; - } - - - /** - * Gets the session id length (in bytes) of Sessions created by - * this Manager. - * - * @return The session id length - */ - public int getSessionIdLength() { - - return (this.sessionIdLength); - - } - - - /** - * Sets the session id length (in bytes) for Sessions created by this - * Manager. - * - * @param idLength The session id length - */ - public void setSessionIdLength(int idLength) { - this.sessionIdLength = idLength; - } -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/SimpleSessionManager.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/SimpleSessionManager.java deleted file mode 100644 index e071c719d..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/SimpleSessionManager.java +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.session; - - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - - -// TODO: move 'expiring objects' to a separate utility class -// TODO: hook the background thread - -/** - * Minimal implementation of the Manager interface that supports - * no session persistence or distributable capabilities. This class may - * be subclassed to create more sophisticated Manager implementations. - * - * @author Costin Manolache - * @author Craig R. McClanahan - */ -public class SimpleSessionManager implements UserSessionManager { - static final Logger log = Logger.getLogger(SimpleSessionManager.class.getName()); - - protected RandomGenerator randomG = new RandomGenerator(); - - protected ServletContext context; - - - /** - * The distributable flag for Sessions created by this Manager. If this - * flag is set to true, any user attributes added to a - * session controlled by this Manager must be Serializable. - * - * This is for compliance with the spec - tomcat-lite is not intended for - * session replication ( use a full version for that ) - */ - protected boolean distributable; - - /** - * The default maximum inactive interval for Sessions created by - * this Manager. - */ - protected int maxInactiveInterval = 60; - - /** - * The longest time (in seconds) that an expired session had been alive. - */ - protected int sessionMaxAliveTime; - - - /** - * Average time (in seconds) that expired sessions had been alive. - */ - protected int sessionAverageAliveTime; - - - /** - * Number of sessions that have expired. - */ - protected int expiredSessions = 0; - - static class SessionLRU extends LinkedHashMap { -// protected boolean removeEldestEntry(Map.Entry eldest) { -// HttpSessionImpl s = (HttpSessionImpl)eldest.getValue(); -// int size = this.size(); -// -// // TODO: check if eldest is expired or if we're above the limit. -// // if eldest is expired, turn a flag to check for more. -// -// // Note: this doesn't work well for sessions that set shorter -// // expiry time, or longer expiry times. -// return false; -// } - - } - - /** - * The set of currently active Sessions for this Manager, keyed by - * session identifier. - */ - protected LinkedHashMap sessions = new SessionLRU(); - - // Number of sessions created by this manager - protected int sessionCounter=0; - - protected int maxActive=0; - - // number of duplicated session ids - anything >0 means we have problems - protected int duplicates=0; - - protected boolean initialized=false; - - /** - * Processing time during session expiration. - */ - protected long processingTime = 0; - - static List EMPTY_LIST = new ArrayList(); - - // One per machine - it has an internal pool, can schedule - // tasks for multiple webapps. - static Timer timer = new Timer(); - boolean active = false; - - TimerTask task = new TimerTask() { - public void run() { - processExpires(); - synchronized (sessions) { - // We don't want a timer thread running around if - // there is no activity - if (sessions.size() == 0) { - active = false; - this.cancel(); - } - } - } - }; - - public List getEventListeners() { - List l = - (List) context.getAttribute("context-listeners"); - if (l == null) return EMPTY_LIST; - return l; - } - - /** - * Total sessions created by this manager. - */ - public int getSessionCounter() { - return sessionCounter; - } - - - /** - * Number of duplicated session IDs generated by the random source. - * Anything bigger than 0 means problems. - * - * @return The count of duplicates - */ - public int getDuplicates() { - return duplicates; - } - - - /** - * Returns the number of active sessions - * - * @return number of sessions active - */ - public int getActiveSessions() { - return sessions.size(); - } - - - /** - * Max number of concurrent active sessions - * - * @return The highest number of concurrent active sessions - */ - public int getMaxActive() { - return maxActive; - } - - - public void setMaxActive(int maxActive) { - this.maxActive = maxActive; - } - - - /** - * Gets the longest time (in seconds) that an expired session had been - * alive. - * - * @return Longest time (in seconds) that an expired session had been - * alive. - */ - public int getSessionMaxAliveTime() { - return sessionMaxAliveTime; - } - - /** - * Gets the average time (in seconds) that expired sessions had been - * alive. - * - * @return Average time (in seconds) that expired sessions had been - * alive. - */ - public int getSessionAverageAliveTime() { - return sessionAverageAliveTime; - } - - /** - * Return the Container with which this Manager is associated. - */ - public ServletContext getContext() { - return (this.context); - } - - - /** - * Set the Container with which this Manager is associated. - * - * @param container The newly associated Container - */ - public void setContext(ServletContext container) { - this.context = container; - } - - /** - * Return the distributable flag for the sessions supported by - * this Manager. - */ - public boolean getDistributable() { - return (this.distributable); - } - - /** - * Set the distributable flag for the sessions supported by this - * Manager. If this flag is set, all user data objects added to - * sessions associated with this manager must implement Serializable. - * - * @param distributable The new distributable flag - */ - public void setDistributable(boolean distributable) { - this.distributable = distributable; - } - - /** - * Return the default maximum inactive interval (in seconds) - * for Sessions created by this Manager. - */ - public int getSessionTimeout() { - return (this.maxInactiveInterval); - } - - public void setSessionTimeout(int stout) { - maxInactiveInterval = stout; - } - - /** - * Gets the number of sessions that have expired. - * - * @return Number of sessions that have expired - */ - public int getExpiredSessions() { - return expiredSessions; - } - - /** - * Called when a session is expired, add the time to statistics - */ - public void addExpiredSession(int timeAlive) { - synchronized (this) { - this.expiredSessions++; // should be atomic - // not sure it's the best solution - sessionAverageAliveTime = - ((sessionAverageAliveTime * (expiredSessions-1)) + - timeAlive)/expiredSessions; - if (timeAlive > sessionMaxAliveTime) { - sessionMaxAliveTime = timeAlive; - } - } - } - - public long getProcessingTime() { - return processingTime; - } - - private void enableTimer() { - if (active) { - return; - } - active = true; - timer.scheduleAtFixedRate(task, getSessionTimeout(), getSessionTimeout()); - } - - - - /** - * Invalidate all sessions that have expired. - */ - public void processExpires() { - - long timeNow = System.currentTimeMillis(); - HttpSessionImpl sessions[] = findSessions(); - int expireHere = 0 ; - - if(log.isLoggable(Level.FINE)) - log.fine("Start expire sessions " + " at " + timeNow + " sessioncount " + sessions.length); - - for (int i = 0; i < sessions.length; i++) { - if (!sessions[i].isValid()) { - expiredSessions++; - expireHere++; - } - } - - long timeEnd = System.currentTimeMillis(); - if(log.isLoggable(Level.FINE)) - log.fine("End expire sessions " + " processingTime " + - (timeEnd - timeNow) + " expired sessions: " + expireHere); - - processingTime += ( timeEnd - timeNow ); - - } - - public SimpleSessionManager() { - randomG.init(); - } - - public void destroy() { - initialized=false; - } - - /** - * Add this Session to the set of active Sessions for this Manager. - * - * @param session Session to be added - */ - public void add(HttpSessionImpl session) { - synchronized (sessions) { - sessions.put(session.getId(), session); - if( sessions.size() > maxActive ) { - maxActive=sessions.size(); - } - - // Make sure the timer is set. - enableTimer(); - } - } - - - /** - * Construct and return a new session object, based on the default - * settings specified by this Manager's properties. The session - * id specified will be used as the session id. - * If a new session cannot be created for any reason, return - * null. - * - * @param sessionId The session id which should be used to create the - * new session; if null, a new session id will be - * generated - * @exception IllegalStateException if a new session cannot be - * instantiated for any reason - */ - public HttpSessionImpl createSession(String sessionId) { - - // Recycle or create a Session instance - HttpSessionImpl session = createEmptySession(); - - // Initialize the properties of the new session and return it - session.setNew(true); - session.setValid(true); - session.setCreationTime(System.currentTimeMillis()); - session.setMaxInactiveInterval(this.maxInactiveInterval); - if (sessionId == null ) { - while (sessionId == null) { - sessionId = randomG.generateSessionId(); - if (sessions.get(sessionId) != null) { - duplicates++; - sessionId = null; - } - } - } -/* } else { - // FIXME: Code to be used in case route replacement is needed - String jvmRoute = randomG.jvmRoute; - if (jvmRoute != null) { - String requestJvmRoute = null; - int index = sessionId.indexOf("."); - if (index > 0) { - requestJvmRoute = sessionId - .substring(index + 1, sessionId.length()); - } - if (requestJvmRoute != null && !requestJvmRoute.equals(jvmRoute)) { - sessionId = sessionId.substring(0, index) + "." + jvmRoute; - } - } -*/ - session.setId(sessionId); - sessionCounter++; - return (session); - } - - - /** - * Get a session from the recycled ones or create a new empty one. - * The PersistentManager manager does not need to create session data - * because it reads it from the Store. - */ - public HttpSessionImpl createEmptySession() { - return new HttpSessionImpl(this); - } - - - /** - * Return the active Session, associated with this Manager, with the - * specified session id (if any); otherwise return null. - * - * @param id The session id for the session to be returned - * - * @exception IllegalStateException if a new session cannot be - * instantiated for any reason - * @exception IOException if an input/output error occurs while - * processing this request - */ - public HttpSessionImpl findSession(String id) throws IOException { - - if (id == null) - return (null); - synchronized (sessions) { - HttpSessionImpl session = (HttpSessionImpl) sessions.get(id); - return (session); - } - - } - - - /** - * Return the set of active Sessions associated with this Manager. - * If this Manager has no active Sessions, a zero-length array is returned. - */ - public HttpSessionImpl[] findSessions() { - - HttpSessionImpl results[] = null; - synchronized (sessions) { - results = new HttpSessionImpl[sessions.size()]; - results = (HttpSessionImpl[]) sessions.values().toArray(results); - } - return (results); - - } - - - /** - * Remove this Session from the active Sessions for this Manager. - * - * @param session Session to be removed - */ - public void remove(HttpSessionImpl session) { - - synchronized (sessions) { - sessions.remove(session.getId()); - } - - } - - // ------------------------------------------------------ Protected Methods - - /** JMX and debugging - */ - public void expireSession( String sessionId ) { - HttpSessionImpl s=(HttpSessionImpl)sessions.get(sessionId); - if( s==null ) { - return; - } - s.expire(); - } - - - /** JMX method or debugging - */ - public String getLastAccessedTime( String sessionId ) { - HttpSessionImpl s=(HttpSessionImpl)sessions.get(sessionId); - if( s==null ) { - return ""; - } - return new Date(s.getLastAccessedTime()).toString(); - } - - ThreadLocal httpSession; - - public String getSessionCookieName() { - return "JSESSIONID"; - } - - - /** Parse the cookies. Since multiple session cookies could be set ( - * different paths for example ), we need to lookup and find a valid one - * for our context. - * - * If none is found - the last (bad) session id is returned. - * - * As side effect, an attribute is set on the req with the session ( we - * already looked it up while searching ). - */ - public HttpSession getRequestedSessionId(HttpServletRequest req) { - Cookie[] cookies = req.getCookies(); - String cn = getSessionCookieName(); - for (int i=0; i from web.xml - * - * Implementation of this class must provide HttpSession object - * and implement the spec. - * - */ -public interface UserSessionManager { - - - - HttpSession findSession(String requestedSessionId) throws IOException; - - HttpSession createSession(String requestedSessionId); - - boolean isValid(HttpSession session); - - void access(HttpSession session); - - void endAccess(HttpSession session); - - - void setSessionTimeout(int to); - - void setContext(ServletContext ctx); - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Enumerator.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Enumerator.java deleted file mode 100644 index e262547bd..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Enumerator.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.util; - - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; - - -/** - * Adapter class that wraps an Enumeration around a Java2 - * collection classes object Iterator so that existing APIs - * returning Enumerations can easily run on top of the new collections. - * Constructors are provided to easliy create such wrappers. - * - * @author Craig R. McClanahan - */ -public final class Enumerator implements Enumeration { - - - // ----------------------------------------------------------- Constructors - - - /** - * Return an Enumeration over the values of the specified Collection. - * - * @param collection Collection whose values should be enumerated - */ - public Enumerator(Collection collection) { - - this(collection.iterator()); - - } - - - /** - * Return an Enumeration over the values of the specified Collection. - * - * @param collection Collection whose values should be enumerated - * @param clone true to clone iterator - */ - public Enumerator(Collection collection, boolean clone) { - - this(collection.iterator(), clone); - - } - - - /** - * Return an Enumeration over the values returned by the - * specified Iterator. - * - * @param iterator Iterator to be wrapped - */ - public Enumerator(Iterator iterator) { - - super(); - this.iterator = iterator; - - } - - - /** - * Return an Enumeration over the values returned by the - * specified Iterator. - * - * @param iterator Iterator to be wrapped - * @param clone true to clone iterator - */ - public Enumerator(Iterator iterator, boolean clone) { - - super(); - if (!clone) { - this.iterator = iterator; - } else { - List list = new ArrayList(); - while (iterator.hasNext()) { - list.add(iterator.next()); - } - this.iterator = list.iterator(); - } - - } - - - /** - * Return an Enumeration over the values of the specified Map. - * - * @param map Map whose values should be enumerated - */ - public Enumerator(Map map) { - - this(map.values().iterator()); - - } - - - /** - * Return an Enumeration over the values of the specified Map. - * - * @param map Map whose values should be enumerated - * @param clone true to clone iterator - */ - public Enumerator(Map map, boolean clone) { - - this(map.values().iterator(), clone); - - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * The Iterator over which the Enumeration - * represented by this class actually operates. - */ - private Iterator iterator = null; - - - // --------------------------------------------------------- Public Methods - - - /** - * Tests if this enumeration contains more elements. - * - * @return true if and only if this enumeration object - * contains at least one more element to provide, false - * otherwise - */ - public boolean hasMoreElements() { - - return (iterator.hasNext()); - - } - - - /** - * Returns the next element of this enumeration if this enumeration - * has at least one more element to provide. - * - * @return the next element of this enumeration - * - * @exception NoSuchElementException if no more elements exist - */ - public Object nextElement() throws NoSuchElementException { - - return (iterator.next()); - - } - - -} diff --git a/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/RequestUtil.java b/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/RequestUtil.java deleted file mode 100644 index 31a157d56..000000000 --- a/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/RequestUtil.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.servlets.util; - -import java.io.UnsupportedEncodingException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Map; -import java.util.TimeZone; - -import javax.servlet.http.Cookie; - - -/** - * General purpose request parsing and encoding utility methods. - * - * @author Craig R. McClanahan - * @author Tim Tye - * @version $Id$ - */ - -public final class RequestUtil { - - - /** - * The DateFormat to use for generating readable dates in cookies. - */ - private static SimpleDateFormat format = - new SimpleDateFormat(" EEEE, dd-MMM-yy kk:mm:ss zz"); - - static { - format.setTimeZone(TimeZone.getTimeZone("GMT")); - } - - - /** - * Encode a cookie as per RFC 2109. The resulting string can be used - * as the value for a Set-Cookie header. - * - * @param cookie The cookie to encode. - * @return A string following RFC 2109. - */ - public static String encodeCookie(Cookie cookie) { - - StringBuffer buf = new StringBuffer( cookie.getName() ); - buf.append("="); - buf.append(cookie.getValue()); - - if (cookie.getComment() != null) { - buf.append("; Comment=\""); - buf.append(cookie.getComment()); - buf.append("\""); - } - - if (cookie.getDomain() != null) { - buf.append("; Domain=\""); - buf.append(cookie.getDomain()); - buf.append("\""); - } - - long age = cookie.getMaxAge(); - if (cookie.getMaxAge() >= 0) { - buf.append("; Max-Age=\""); - buf.append(cookie.getMaxAge()); - buf.append("\""); - } - - if (cookie.getPath() != null) { - buf.append("; Path=\""); - buf.append(cookie.getPath()); - buf.append("\""); - } - - if (cookie.getSecure()) { - buf.append("; Secure"); - } - - if (cookie.getVersion() > 0) { - buf.append("; Version=\""); - buf.append(cookie.getVersion()); - buf.append("\""); - } - - return (buf.toString()); - } - - - /** - * Filter the specified message string for characters that are sensitive - * in HTML. This avoids potential attacks caused by including JavaScript - * codes in the request URL that is often reported in error messages. - * - * @param message The message string to be filtered - */ - public static String filter(String message) { - - if (message == null) - return (null); - - char content[] = new char[message.length()]; - message.getChars(0, message.length(), content, 0); - StringBuilder result = new StringBuilder(content.length + 50); - for (int i = 0; i < content.length; i++) { - switch (content[i]) { - case '<': - result.append("<"); - break; - case '>': - result.append(">"); - break; - case '&': - result.append("&"); - break; - case '"': - result.append("""); - break; - default: - result.append(content[i]); - } - } - return (result.toString()); - - } - - - /** - * Normalize a relative URI path that may have relative values ("/./", - * "/../", and so on ) it it. WARNING - This method is - * useful only for normalizing application-generated paths. It does not - * try to perform security checks for malicious input. - * - * @param path Relative path to be normalized - */ - public static String normalize(String path) { - - if (path == null) - return null; - - // Create a place for the normalized path - String normalized = path; - - if (normalized.equals("/.")) - return "/"; - - // Add a leading "/" if necessary - if (!normalized.startsWith("/")) - normalized = "/" + normalized; - - // Resolve occurrences of "//" in the normalized path - while (true) { - int index = normalized.indexOf("//"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 1); - } - - // Resolve occurrences of "/./" in the normalized path - while (true) { - int index = normalized.indexOf("/./"); - if (index < 0) - break; - normalized = normalized.substring(0, index) + - normalized.substring(index + 2); - } - - // Resolve occurrences of "/../" in the normalized path - while (true) { - int index = normalized.indexOf("/../"); - if (index < 0) - break; - if (index == 0) - return (null); // Trying to go outside our context - int index2 = normalized.lastIndexOf('/', index - 1); - normalized = normalized.substring(0, index2) + - normalized.substring(index + 3); - } - - // Return the normalized path that we have completed - return (normalized); - - } - - - /** - * Parse the character encoding from the specified content type header. - * If the content type is null, or there is no explicit character encoding, - * null is returned. - * - * @param contentType a content type header - */ - public static String parseCharacterEncoding(String contentType) { - - if (contentType == null) - return (null); - int start = contentType.indexOf("charset="); - if (start < 0) - return (null); - String encoding = contentType.substring(start + 8); - int end = encoding.indexOf(';'); - if (end >= 0) - encoding = encoding.substring(0, end); - encoding = encoding.trim(); - if ((encoding.length() > 2) && (encoding.startsWith("\"")) - && (encoding.endsWith("\""))) - encoding = encoding.substring(1, encoding.length() - 1); - return (encoding.trim()); - - } - - - /** - * Parse a cookie header into an array of cookies according to RFC 2109. - * - * @param header Value of an HTTP "Cookie" header - */ - public static Cookie[] parseCookieHeader(String header) { - - if ((header == null) || (header.length() < 1)) - return (new Cookie[0]); - - ArrayList cookies = new ArrayList(); - while (header.length() > 0) { - int semicolon = header.indexOf(';'); - if (semicolon < 0) - semicolon = header.length(); - if (semicolon == 0) - break; - String token = header.substring(0, semicolon); - if (semicolon < header.length()) - header = header.substring(semicolon + 1); - else - header = ""; - try { - int equals = token.indexOf('='); - if (equals > 0) { - String name = token.substring(0, equals).trim(); - String value = token.substring(equals+1).trim(); - cookies.add(new Cookie(name, value)); - } - } catch (Throwable e) { - ; - } - } - - return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()])); - - } - - - /** - * Append request parameters from the specified String to the specified - * Map. It is presumed that the specified Map is not accessed from any - * other thread, so no synchronization is performed. - *

- * IMPLEMENTATION NOTE: URL decoding is performed - * individually on the parsed name and value elements, rather than on - * the entire query string ahead of time, to properly deal with the case - * where the name or value includes an encoded "=" or "&" character - * that would otherwise be interpreted as a delimiter. - * - * @param map Map that accumulates the resulting parameters - * @param data Input string containing request parameters - * - * @exception IllegalArgumentException if the data is malformed - */ - public static void parseParameters(Map map, String data, String encoding) - throws UnsupportedEncodingException { - - if ((data != null) && (data.length() > 0)) { - - // use the specified encoding to extract bytes out of the - // given string so that the encoding is not lost. If an - // encoding is not specified, let it use platform default - byte[] bytes = null; - try { - if (encoding == null) { - bytes = data.getBytes(); - } else { - bytes = data.getBytes(encoding); - } - } catch (UnsupportedEncodingException uee) { - } - - parseParameters(map, bytes, encoding); - } - - } - - - - - - - /** - * Decode and return the specified URL-encoded byte array. - * - * @param bytes The url-encoded byte array - * @exception IllegalArgumentException if a '%' character is not followed - * by a valid 2-digit hexadecimal number - */ -// public static String URLDecode(byte[] bytes) { -// return URLDecode(bytes, null); -// } - - - - - /** - * Convert a byte character value to hexidecimal digit value. - * - * @param b the character value byte - */ - private static byte convertHexDigit( byte b ) { - if ((b >= '0') && (b <= '9')) return (byte)(b - '0'); - if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10); - if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10); - return 0; - } - - - /** - * Put name and value pair in map. When name already exist, add value - * to array of values. - * - * @param map The map to populate - * @param name The parameter name - * @param value The parameter value - */ - private static void putMapEntry( Map map, String name, String value) { - String[] newValues = null; - String[] oldValues = (String[]) map.get(name); - if (oldValues == null) { - newValues = new String[1]; - newValues[0] = value; - } else { - newValues = new String[oldValues.length + 1]; - System.arraycopy(oldValues, 0, newValues, 0, oldValues.length); - newValues[oldValues.length] = value; - } - map.put(name, newValues); - } - - - /** - * Append request parameters from the specified String to the specified - * Map. It is presumed that the specified Map is not accessed from any - * other thread, so no synchronization is performed. - *

- * IMPLEMENTATION NOTE: URL decoding is performed - * individually on the parsed name and value elements, rather than on - * the entire query string ahead of time, to properly deal with the case - * where the name or value includes an encoded "=" or "&" character - * that would otherwise be interpreted as a delimiter. - * - * NOTE: byte array data is modified by this method. Caller beware. - * - * @param map Map that accumulates the resulting parameters - * @param data Input string containing request parameters - * @param encoding Encoding to use for converting hex - * - * @exception UnsupportedEncodingException if the data is malformed - */ - public static void parseParameters(Map map, byte[] data, String encoding) - throws UnsupportedEncodingException { - - if (data != null && data.length > 0) { - int pos = 0; - int ix = 0; - int ox = 0; - String key = null; - String value = null; - while (ix < data.length) { - byte c = data[ix++]; - switch ((char) c) { - case '&': - value = new String(data, 0, ox, encoding); - if (key != null) { - putMapEntry(map, key, value); - key = null; - } - ox = 0; - break; - case '=': - if (key == null) { - key = new String(data, 0, ox, encoding); - ox = 0; - } else { - data[ox++] = c; - } - break; - case '+': - data[ox++] = (byte)' '; - break; - case '%': - data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4) - + convertHexDigit(data[ix++])); - break; - default: - data[ox++] = c; - } - } - //The last value does not end in '&'. So save it now. - if (key != null) { - value = new String(data, 0, ox, encoding); - putMapEntry(map, key, value); - } - } - - } - - - -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/SimpleServlet.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/SimpleServlet.java deleted file mode 100644 index 0221b4859..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/SimpleServlet.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite; - -import java.io.IOException; - -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class SimpleServlet extends HttpServlet { - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws IOException { - res.setHeader("Foo", "Bar"); - res.getWriter().write("Hello world"); - } - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws IOException { - res.setHeader("Foo", "Post"); - res.getWriter().write("Hello post world"); - } -} \ No newline at end of file diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/AnnotationTest.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/AnnotationTest.java deleted file mode 100644 index cd3f64d98..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/AnnotationTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import java.io.FileInputStream; -import java.io.IOException; - -import junit.framework.TestCase; - -import org.apache.tomcat.servlets.config.ServletContextConfig; -import org.apache.tomcat.servlets.config.deploy.AnnotationsProcessor; - -public class AnnotationTest extends TestCase { - - // TODO: fix the build file to find the target dir - // you can run this manually until this happens - String eclipseBase = "test-webapp/WEB-INF/classes"; - - public void testScanClasses() throws IOException { - ServletContextConfig cfg = new ServletContextConfig(); - AnnotationsProcessor scanner = new AnnotationsProcessor(cfg); -// scanner.processDir(eclipseBase); -// -// dump(cfg); - - } - - public void testScanClass() throws IOException { - ServletContextConfig cfg = new ServletContextConfig(); - AnnotationsProcessor scanner = new AnnotationsProcessor(cfg); - - String path = eclipseBase + "/org/apache/tomcat/lite/Annotated2Servlet.class"; -// scanner.processClass(new FileInputStream(path), eclipseBase, path); -// -// dump(cfg); - - } - - private void dump(ServletContextConfig cfg) { -// ObjectMapper jackson = new ObjectMapper(); -// try { -// jackson.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); -// jackson.configure(SerializationConfig.Feature.WRITE_NULL_PROPERTIES, -// false); -// -// ByteArrayOutputStream out = new ByteArrayOutputStream(); -// jackson.writeValue(out, cfg); -// System.err.println(out.toString()); -// } catch (Throwable t) { -// t.printStackTrace(); -// } - } - -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/JspWatchdogTests.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/JspWatchdogTests.java deleted file mode 100644 index ac7e9a31f..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/JspWatchdogTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - -import org.apache.tomcat.lite.servlet.TomcatLite; - -import junit.framework.Test; - -public class JspWatchdogTests extends TomcatLiteWatchdog { - - public JspWatchdogTests() { - super(); - testMatch = - //"precompileNegativeTest"; - null; - // Test we know are failing - need to fix at some point. - exclude = new String[] { - "negativeDuplicateExtendsFatalTranslationErrorTest", - "negativeDuplicateErrorPageFatalTranslationErrorTest", - "negativeDuplicateInfoFatalTranslationErrorTest", - "negativeDuplicateLanguageFatalTranslationErrorTest", - "negativeDuplicateSessionFatalTranslationErrorTest", - "positiveIncludeCtxRelativeHtmlTest", - "precompileNegativeTest" - }; - file = getWatchdogdir() + "/src/conf/jsp-gtest.xml"; - goldenDir = - getWatchdogdir() + "/src/clients/org/apache/jcheck/jsp/client/"; - targetMatch = "jsp-test"; - - } - - protected void addConnector(TomcatLite lite) { - lite.setPort(8019); - } - - public static Test suite() { - return new JspWatchdogTests().getSuite(8019); - } - -} - diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/LiteTestHelper.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/LiteTestHelper.java deleted file mode 100644 index 2df27f7ac..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/LiteTestHelper.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tomcat.lite.io.BBuffer; -import org.apache.tomcat.lite.servlet.ServletContextImpl; -import org.apache.tomcat.lite.servlet.TomcatLite; - -public class LiteTestHelper { - static TomcatLite lite; - - public static ServletContextImpl addContext(TomcatLite lite) throws ServletException { - ServletContextImpl ctx = - (ServletContextImpl) lite.addServletContext(null, null, "/test1"); - - - ctx.add("testException", new HttpServlet() { - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws IOException { - throw new NullPointerException(); - } - }); - ctx.addMapping("/testException", "testException"); - - - ctx.add("test", new HttpServlet() { - public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { - res.addHeader("Foo", "Bar"); - res.getWriter().write("Hello world"); - } - }); - - ctx.addMapping("/1stTest", "test"); - - - return ctx; - } - - public static void startLite() throws IOException, ServletException { - if (lite == null) { - lite = new TomcatLite(); - - LiteTestHelper.addContext(lite); - lite.start(); - - lite.startConnector(); - } - } - - public static void initServletsAndRun(TomcatLite lite, int port) throws ServletException, IOException { - addContext(lite); - lite.init(); - lite.start(); - - - if (port > 0) { - // This should be added after all local initialization to avoid - // the server from responding. - // Alternatively, you can load this early but set it to return - // 'unavailable' if load balancers depend on this. - addConnector(lite, port, true); - - // At this point we can add contexts and inject requests, if we want to - // do it over HTTP need to start the connector as well. - lite.startConnector(); - } - } - - public static void addConnector(TomcatLite lite, - int port, boolean daemon) { - lite.setPort(port); - } - - /** - * Get url using URLConnection. - */ - public static BBuffer getUrl(String path) throws IOException { - - BBuffer out = BBuffer.allocate(4096); - - URL url = new URL(path); - URLConnection connection = url.openConnection(); - connection.setReadTimeout(5000); - connection.connect(); - InputStream is = connection.getInputStream(); - out.readAll(is); - return out; - } - -// static class ByteChunkOutputBuffer implements OutputBuffer { -// -// protected ByteChunk output = null; -// -// public ByteChunkOutputBuffer(ByteChunk output) { -// this.output = output; -// } -// -// public int doWrite(ByteChunk chunk, Response response) -// throws IOException { -// output.append(chunk); -// return chunk.getLength(); -// } -// } - - -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/PropertiesSpiTest.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/PropertiesSpiTest.java deleted file mode 100644 index a331dfb33..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/PropertiesSpiTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import java.io.IOException; -import java.util.Properties; - -import junit.framework.TestCase; - -import org.apache.tomcat.integration.simple.SimpleObjectManager; - - -public class PropertiesSpiTest extends TestCase { - - SimpleObjectManager spi; - - public void setUp() { - spi = new SimpleObjectManager(); - - spi.getProperties().put("obj1.name", "foo"); - spi.getProperties().put("obj1.(class)", BoundObj.class.getName()); - - } - - public void testArgs() throws IOException { - spi = new SimpleObjectManager(new String[] { - "-a=1", "-b", "2"}); - Properties res = spi.getProperties(); - - assertEquals("1", res.get("a")); - assertEquals("2", res.get("b")); - - - } - - public static class BoundObj { - String name; - - public void setName(String n) { - this.name = n; - } - } - - public void testBind() throws Exception { - BoundObj bo = new BoundObj(); - spi.bind("obj1", bo); - assertEquals(bo.name, "foo"); - } - - public void testCreate() throws Exception { - BoundObj bo = (BoundObj) spi.get("obj1"); - assertEquals(bo.name, "foo"); - } -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/ServletTests.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/ServletTests.java deleted file mode 100644 index 03d717c2b..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/ServletTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - */ -package org.apache.tomcat.lite.servlet; - -import org.apache.tomcat.lite.servlet.TomcatLite; - -import junit.framework.Test; - -public class ServletTests extends TomcatLiteWatchdog { - - public ServletTests() { - super(); - exclude = new String[] { - "ServletToJSPErrorPageTest", - "ServletToJSPError502PageTest", - }; - } - - protected void addConnector(TomcatLite connector) { - connector.setPort(7074); - } - - /** - * Magic JUnit method - */ - public static Test suite() { - return new ServletTests().getSuite(7074); - } -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteNoConnectorTest.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteNoConnectorTest.java deleted file mode 100644 index 88f0ecd6a..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteNoConnectorTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - - - -import junit.framework.TestCase; - -import org.apache.tomcat.lite.http.HttpChannel; -import org.apache.tomcat.lite.http.HttpConnector; -import org.apache.tomcat.lite.http.HttpRequest; -import org.apache.tomcat.lite.http.HttpResponse; -import org.apache.tomcat.lite.io.BBuffer; - -/** - * Example of testing servlets without using sockets. - * - * @author Costin Manolache - */ -public class TomcatLiteNoConnectorTest extends TestCase { - - TomcatLite lite; - HttpConnector con; - - public void setUp() throws Exception { - con = new HttpConnector(null); - - lite = new TomcatLite(); - lite.setHttpConnector(con); - - // Load all servlets we need to test - LiteTestHelper.initServletsAndRun(lite, 0); - } - - public void tearDown() throws Exception { - lite.stop(); - } - - public void testSimpleRequest() throws Exception { - HttpChannel httpCh = con.getServer(); - - HttpRequest req = httpCh.getRequest(); - req.setURI("/test1/1stTest"); - - HttpResponse res = httpCh.getResponse(); - - lite.getHttpConnector().getDispatcher().service(req, res, true, false); - - BBuffer resBody = res.getBody().readAll(null); - assertEquals("Hello world", resBody.toString()); - - assertEquals(res.getHeader("Foo"), "Bar"); - assertEquals(res.getStatus(), 200); - } - -// -// public void testPostRequest() throws Exception { -// ByteChunk out = new ByteChunk(); -// ServletRequestImpl req = -// LiteTestHelper.createMessage(lite, "/test1/1stTest", out); -// req.setMethod("POST"); -// -// ServletResponseImpl res = lite.service(req); -// -// assertEquals("Hello post world", out.toString()); -// // Headers are still in the response -// assertEquals(res.getHeader("Foo"), "Post"); -// assertEquals(res.getStatus(), 200); -// } -// -// public void testException() throws IOException, Exception { -// ByteChunk out = new ByteChunk(); -// ServletRequestImpl req = -// LiteTestHelper.createMessage(lite, "/test1/testException", out); -// ServletResponseImpl res = lite.service(req); -// assertEquals(res.getStatus(), 500); -// } - -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteSimpleTest.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteSimpleTest.java deleted file mode 100644 index 8f4d8b5c1..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteSimpleTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; - -import junit.framework.TestCase; - -import org.apache.tomcat.lite.io.IOBuffer; - -/** - * TODO: convert to new API - * - */ -public class TomcatLiteSimpleTest extends TestCase { - - protected TomcatLite lite = new TomcatLite(); - - public void setUp() throws Exception { - LiteTestHelper.addContext(lite); - - lite.init(); - - lite.setPort(8884); - lite.start(); - lite.startConnector(); - } - - public void testSimpleRequest() throws Exception { - URL url = new URL("http://localhost:8884/test1/1stTest"); - URLConnection connection = url.openConnection(); - InputStream is = connection.getInputStream(); - String res = new IOBuffer().append(is).readAll(null).toString(); - assertEquals("Hello world", res); - } -} diff --git a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java b/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java deleted file mode 100644 index a306b3c51..000000000 --- a/modules/tomcat-lite/test/org/apache/tomcat/lite/servlet/TomcatLiteWatchdog.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tomcat.lite.servlet; - -import java.io.File; -import java.io.IOException; - -import javax.servlet.ServletException; - -import junit.framework.TestResult; - -import org.apache.tomcat.lite.servlet.TomcatLite; -import org.apache.tomcat.test.watchdog.WatchdogClient; - - -public abstract class TomcatLiteWatchdog extends WatchdogClient { - - public TomcatLiteWatchdog() { - super(); - goldenDir = getWatchdogdir() + "/src/clients/org/apache/jcheck/servlet/client/"; - testMatch = - //"HttpServletResponseWrapperSetStatusMsgTest"; - //"ServletContextAttributeAddedEventTest"; - null; - // ex: "ServletToJSP"; - file = getWatchdogdir() + "/src/conf/servlet-gtest.xml"; - targetMatch = "gtestservlet-test"; - } - - public TomcatLiteWatchdog(String s) { - this(); - super.single = s; - } - - protected void beforeSuite() { - // required for the tests - System.setProperty("org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER", - "true"); - - try { - initServerWithWatchdog(getWatchdogdir()); - } catch (ServletException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - protected abstract void addConnector(TomcatLite liteServer); - - public void initServerWithWatchdog(String wdDir) throws ServletException, - IOException { - TomcatLite tomcatForWatchdog; - - File f = new File(wdDir + "/build/webapps"); - - tomcatForWatchdog = new TomcatLite(); - - addConnector(tomcatForWatchdog); -// tomcatForWatchdog.getHttpConnector().setDebug(true); -// tomcatForWatchdog.getHttpConnector().setDebugHttp(true); - - tomcatForWatchdog.addServletContext(null, "webapps/ROOT", "/").loadConfig(); - - for (String s : new String[] { - "servlet-compat", - "servlet-tests", - "jsp-tests"} ) { - tomcatForWatchdog.addServletContext(null, f.getCanonicalPath() + "/" + s, - "/" + s).loadConfig(); - } - - tomcatForWatchdog.init(); - tomcatForWatchdog.start(); - - tomcatForWatchdog.startConnector(); - } - - - - protected void afterSuite(TestResult res) { - // no need to stop it - using daemon threads. - } -}