+++ /dev/null
-/*
- * 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<FilterConfigImpl> filters = new ArrayList<FilterConfigImpl>();
-
- /**
- * 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 <code>service()</code> 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;
- }
-}
+++ /dev/null
-/*
- * 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<String, String> initParams;
-
- private Class<? extends Filter> filterClass;
-
- private boolean initDone = false;
-
- public void setData(String filterName, String filterClass,
- Map<String, String> 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<? extends Filter> filterClass2) {
- this.filterClass = filterClass2;
- }
-
-
- public String getInitParameter(String name) {
- if (initParams == null) return null;
- return initParams.get(name);
- }
-
- /**
- * Return an <code>Enumeration</code> 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<? extends Filter>) 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<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
- initParameters);
- }
-}
+++ /dev/null
-/*
- */
-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());
- }
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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
- * <code><jsp-file></code> 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<MappingData> localMappingData =
- new ThreadLocal<MappingData>();
-
- /*
- 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.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong>: 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);
-
- }
-
-
-}
+++ /dev/null
-/*
- */
-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
+++ /dev/null
-/*
- */
-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) {
-
- };
- }
-}
+++ /dev/null
-/*
- */
-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<Part> 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<? extends Filter> 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<? extends Servlet> servletClass) {
- return null;
- }
-
- public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
- return null;
- }
-
- public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
- return null;
- }
-
- public FilterRegistration getFilterRegistration(String filterName) {
- return null;
- }
-
- public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
- return null;
- }
-
- public JspConfigDescriptor getJspConfigDescriptor() {
- return null;
- }
-
- public ServletRegistration getServletRegistration(String servletName) {
- return null;
- }
-
- public Map<String, ? extends ServletRegistration> getServletRegistrations() {
- return null;
- }
-
- public SessionCookieConfig getSessionCookieConfig() {
- return null;
- }
-
- public int getMajorVersion() {
- return 3;
- }
-
- public int getMinorVersion() {
- return 0;
- }
-
- public void setSessionTrackingModes(
- Set<SessionTrackingMode> 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<DispatcherType> 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<String> dispatchers = new ArrayList<String>();
- 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<DispatcherType> 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<String> dispatchers = new ArrayList<String>();
- 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<String> setInitParameters(Map<String, String> 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<String> getServletNameMappings() {
- return null;
- }
-
- @Override
- public Collection<String> getUrlPatternMappings() {
- return null;
- }
-
- @Override
- public String getClassName() {
- return null;
- }
-
- @Override
- public String getInitParameter(String name) {
- return null;
- }
-
- @Override
- public Map<String, String> 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<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return setInitParameters(initParameters);
- }
-
- @Override
- public void addMappingForServletNames(
- EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
- String... servletNames) {
- }
-
- @Override
- public void addMappingForUrlPatterns(
- EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
- String... urlPatterns) {
- }
-
- @Override
- public Collection<String> getServletNameMappings() {
- return null;
- }
-
- @Override
- public Collection<String> getUrlPatternMappings() {
- return null;
- }
-
- @Override
- public String getClassName() {
- return null;
- }
-
- @Override
- public String getInitParameter(String name) {
- return null;
- }
-
- @Override
- public Map<String, String> getInitParameters() {
- return null;
- }
-
- @Override
- public String getName() {
- return null;
- }
-
- }
-
-}
+++ /dev/null
-/*
- * 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 <b>Wrapper</b> 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<String, String> initParams = new HashMap<String, String>();
- 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 <code>SingleThreadModel</code>.
- */
- 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 && i<methods.length; i++) {
- Method m = methods[i];
-
- if (m.getName().equals("doGet")) {
- allow.add("GET");
- allow.add("HEAD");
- } else if (m.getName().equals("doPost")) {
- allow.add("POST");
- } else if (m.getName().equals("doPut")) {
- allow.add("PUT");
- } else if (m.getName().equals("doDelete")) {
- allow.add("DELETE");
- }
- }
-
- String[] methodNames = new String[allow.size()];
- return (String[]) allow.toArray(methodNames);
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * MUST be called before service()
- * This method should be called to get the servlet. After
- * service(), dealocate should be called. This deals with STM and
- * update use counters.
- *
- * Normally called from RequestDispatcher and TomcatLite.
- */
- public Servlet allocate() throws ServletException {
- // If we are currently unloading this servlet, throw an exception
- if (unloading)
- throw new ServletException
- ("allocate() while unloading " + getServletName());
-
- Servlet servlet = null;
- // never loaded.
- synchronized (this) {
- if (instance == null && !singleThreadModel) {
- try {
- servlet = loadServlet();
- } catch (ServletException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("loadServlet()", e);
- }
-
- if (servlet != null && !singleThreadModel) {
- setServlet(servlet);
- }
- }
- }
-
-
- // If not SingleThreadedModel, return the same instance every time
- if (instance != null) {
- countAllocated++;
- return (instance);
- }
-
- // Simpler policy for ST: unbound number of servlets ( can grow to
- // one per thread )
-
- synchronized (instancePool) {
- if (instancePool.isEmpty()) {
- try {
- if (servlet != null) {
- // this is the first invocation
- countAllocated++;
- return servlet;
- }
- countAllocated++;
- Servlet newServlet = loadServlet();
- log.fine("New STM servet " + newServlet + " " +
- countAllocated);
- return newServlet;
- } catch (ServletException e) {
- throw e;
- } catch (Throwable e) {
- throw new ServletException("allocate " + getServletName(),
- e);
- }
- }
- log.fine("Get from pool " + instancePool.size() + " " +
- countAllocated);
- Servlet s = (Servlet) instancePool.pop();
- countAllocated++;
- log.fine("After get " + instancePool.size() + " " + s +
- " " + countAllocated);
- return s;
- }
- }
-
-
- /**
- * MUST be called after service().
- */
- public void deallocate(Servlet servlet) {
- // If not SingleThreadModel, no action is required
- if (!singleThreadModel) {
- countAllocated--;
- return;
- }
-
- // Unlock and free this instance
- synchronized (instancePool) {
- countAllocated--;
- if (instancePool.contains(servlet)) {
- System.err.println("Aleady in pool " + servlet + " "
- + instancePool.size()+ " " + countAllocated);
- return;
- }
- System.err.println("return pool " + servlet + " " +
- instancePool.size() + " " + countAllocated);
- instancePool.push(servlet);
- }
- }
-
- public Servlet newInstance() throws ServletException, IOException {
- String actualClass = servletClassName;
-
- if (instance != null) {
- return instance;
- }
- if (actualClass == null) {
- // No explicit name. Try to use the framework
- if (jspFile != null) {
- BaseJspLoader mapper = new JspLoader();
- return mapper.loadProxy(jspFile, ctx, this);
- }
- if (actualClass == null) {
- // Object manager can manage servlets.
- Servlet res = (Servlet) ctx.getObjectManager().get( servletName +
- "-servlet");
- if (res != null) {
- servletClass = res.getClass();
- actualClass = servletClass.getName();
- return res;
- }
- }
-
- //ctx.getObjectManager().getObject(c);
- //ctx.getObjectManager().getObject(servletName);
- }
-
-
- if (servletClass == null) {
- // set classClass
- loadClass(actualClass);
- }
-
-
- // jsp-file case. Load the JspProxyServlet instead, with the
- // right params. Note the JspProxyServlet is _not_ jasper,
- // nor 'jsp' servlet - it is just a proxy with no special
- // params. It calls the jsp servlet and jasper to generate the
- // real class.
-
- // this is quite different from catalina, where an ugly kludge was
- // used to use the same jsp servlet in 2 roles
-
- // the jsp proxy is replaced by the web.xml processor
-
- if (servletClass == null) {
- unavailable(null);
- throw new UnavailableException("ClassNotFound: " + actualClass);
- }
-
- // Instantiate and initialize an instance of the servlet class itself
- try {
- return (Servlet) servletClass.newInstance();
- } catch (ClassCastException e) {
- unavailable(null);
- throw new UnavailableException("ClassCast: (Servlet)" +
- actualClass);
- } catch (Throwable e) {
- unavailable(null);
-
- // Added extra log statement for Bugzilla 36630:
- // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
- if(log.isLoggable(Level.FINE)) {
- log.log(Level.FINE, "newInstance() error: servlet-name: " +
- getServletName() +
- " servlet-class: " + actualClass, e);
- }
-
- // Restore the context ClassLoader
- throw new ServletException("newInstance() error " + getServletName() +
- " " + actualClass, e);
- }
- }
-
- /**
- * Load and initialize an instance of this servlet, if there is not already
- * at least one initialized instance. This can be used, for example, to
- * load servlets that are marked in the deployment descriptor to be loaded
- * at server startup time.
- * @throws IOException
- */
- public synchronized Servlet loadServlet() throws ServletException, IOException {
- // Nothing to do if we already have an instance or an instance pool
- if (!singleThreadModel && (instance != null))
- return instance;
-
- long t1=System.currentTimeMillis();
-
- Servlet servlet = newInstance();
-
- classLoadTime=(int) (System.currentTimeMillis() -t1);
-
- // Call the initialization method of this servlet
- try {
- servlet.init(this);
- } catch (UnavailableException f) {
- unavailable(f);
- throw f;
- } catch (ServletException f) {
- throw f;
- } catch (Throwable f) {
- getServletContext().log("StandardWrapper.Throwable", f );
- throw new ServletException("Servlet.init()", f);
- }
-
- // Register our newly initialized instance
- singleThreadModel = servlet instanceof SingleThreadModel;
- if (singleThreadModel) {
- if (instancePool == null)
- instancePool = new Stack();
- }
- loadTime=System.currentTimeMillis() -t1;
-
- return servlet;
- }
-
-
- private void loadClass(String actualClass) throws ServletException {
- // Complain if no servlet class has been specified
- if (actualClass == null) {
- unavailable(null);
- throw new ServletException("servlet-class missing " +
- getServletName());
- }
-
- ClassLoader classLoader = ctx.getClassLoader();
- if (classLoader == null )
- classLoader = this.getClass().getClassLoader();
-
- // Load the specified servlet class from the appropriate class loader
- try {
- servletClass = classLoader.loadClass(actualClass);
- } catch (ClassNotFoundException e) {
- servletClass = null;
- }
- }
-
- /**
- * Return a String representation of this component.
- */
- public String toString() {
- StringBuffer sb = new StringBuffer();
- if (ctx != null) {
- sb.append(ctx.toString());
- sb.append(".");
- }
- sb.append("Servlet[");
- sb.append(getServletName()).append(" ");
- sb.append(servletClassName);
- if (jspFile != null) {
- sb.append(" jsp=").append(jspFile);
- }
- sb.append("]");
- return (sb.toString());
- }
-
-
- /**
- * Process an UnavailableException, marking this servlet as unavailable
- * for the specified amount of time.
- *
- * @param unavailable The exception that occurred, or <code>null</code>
- * 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
- * <code>destroy()</code> 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 <code>null</code>.
- *
- * @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<String> 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<String> failed = new HashSet<String>();
- 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<String> setInitParameters(Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
- initParameters);
- }
-
- public void setServletClass(Class<? extends Servlet> 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");
- }
-
-
-}
+++ /dev/null
-/*
- * 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<String, Object> attributes = new HashMap<String, Object>();
-
- protected transient ArrayList<EventListener> lifecycleListeners =
- new ArrayList<EventListener>();
-
- protected UserSessionManager manager;
-
- HashMap<String, FilterConfigImpl> filters = new HashMap<String, FilterConfigImpl>();
-
- HashMap<String, ServletConfigImpl> servlets = new HashMap<String, ServletConfigImpl>();
-
- /** 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<EventListener> getListeners() {
- return lifecycleListeners;
- }
-
- public <T extends EventListener> void addListener(T listener) {
- lifecycleListeners.add(listener);
- }
-
- public void removeListener(EventListener listener) {
- lifecycleListeners.remove(listener);
- }
-
- public void addListener(Class<? extends EventListener> listenerClass) {
- }
-
- public void addListener(String className) {
- }
-
- public <T extends EventListener> T createListener(Class<T> 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 <code>null</code>.
- *
- * @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 <code>ServletContext</code> 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 <code>RequestDispatcher</code> 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
- * <code>null</code> 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 <code>null</code> 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 <code>null</code>.
- *
- * @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 <code>RequestDispatcher</code> 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 <code>RequestDispatcher</code> 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/*<RequestDispatcherImpl>*/ 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 <code>InputStream</code>. The
- * path must be specified according to the rules described under
- * <code>getResource</code>. If no such resource can be identified,
- * return <code>null</code>.
- *
- * @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
- * <code>log(String, Throwable)</code> 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/*<Integer, List<ServletConfigImpl>>*/ onStartup =
- new TreeMap/*<Integer, List<ServletConfigImpl>>*/();
- while (fI.hasNext()) {
- ServletConfigImpl fc = (ServletConfigImpl)fI.next();
- if (fc.getLoadOnStartup() > 0 ) {
- Integer i = new Integer(fc.getLoadOnStartup());
- List/*<ServletConfigImpl>*/ old = (List)onStartup.get(i);
- if (old == null) {
- old = new ArrayList/*<ServletConfigImpl>*/();
- onStartup.put(i, old);
- }
- old.add(fc);
- }
- }
- Iterator keys = onStartup.keySet().iterator();
- while (keys.hasNext()) {
- Integer key = (Integer)keys.next();
- List/*<ServletConfigImpl>*/ 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 extends Filter> T createFilter(Class<T> 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 extends Servlet> T createServlet(Class<T> 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<String, String> params = contextConfig.contextParam;
- return setInitParameter(this, params, name, value);
- }
-
- static Set<String> setInitParameters(ServletContextImpl ctx,
- Map<String, String> params,
- Map<String, String> initParameters)
- throws IllegalArgumentException, IllegalStateException {
- if (ctx.startDone) {
- throw new IllegalStateException();
- }
- Set<String> result = new HashSet<String>();
- 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<String, String> 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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * 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();
- }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-}
-
+++ /dev/null
-/*
- * 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();
-
- }
-}
+++ /dev/null
-/*
- * 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
- * <code><jsp-file></code> 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
- * <code>null</code>.
- *
- * @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 <code>Enumeration</code> 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 <code>null</code> 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<ServerCookie> 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 <code>null</code>
- *
- * @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
- * <code>createInputStream()</code>.
- *
- * @exception IllegalStateException if <code>getReader()</code> 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 <code>Accept-Language</code> 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 <code>Accept-Language</code>
- * 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 <code>null</code>. 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 <code>Map</code> 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 <code>Map</code> containing parameter names as keys
- * and parameter values as map values.
- */
- public Map<String, String[]> 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 <code>null</code>.
- *
- * @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 <code>BufferedReader</code> around the
- * servlet input stream returned by <code>createInputStream()</code>.
- *
- * @exception IllegalStateException if <code>getInputStream()</code>
- * 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
- * <code>ServletContext.getRealPath()</code>.
- */
- 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 <code>ServletRequest</code> 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.
- * <p>
- * Because this method returns a <code>StringBuffer</code>,
- * not a <code>String</code>, you can modify the URL easily,
- * for example, to append query parameters.
- * <p>
- * This method is useful for creating redirect messages and
- * for reporting errors.
- *
- * @return A <code>StringBuffer</code> 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 <code>true</code> if the session identifier included in this
- * request came from a cookie.
- */
- public boolean isRequestedSessionIdFromCookie() {
-
- if (requestedSessionId != null)
- return (requestedSessionCookie);
- else
- return (false);
-
- }
-
-
- /**
- * Return <code>true</code> 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
- * <code>isRequestedSessionIdFromURL()</code> instead.
- */
- public boolean isRequestedSessionIdFromUrl() {
- return (isRequestedSessionIdFromURL());
- }
-
-
- /**
- * Return <code>true</code> 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 <code>true</code> 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 <code>true</code> 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 <security-role-ref> 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 <security-role>
- 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 <code>null</code>. 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 <code>getReader()</code>.
- *
- * @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 <code>getContextPath()</code>,
- * 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
- * <code>getRemoteUser()</code> 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;
- }
-
-}
+++ /dev/null
-/*
- * 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 <code>javax.servlet.http.HttpServletRequest</code>
- * that transforms an application request object (which might be the original
- * one passed to a servlet, or might be based on the 2.3
- * <code>javax.servlet.http.HttpServletRequestWrapper</code> class)
- * back into an internal <code>org.apache.catalina.HttpRequest</code>.
- * <p>
- * <strong>WARNING</strong>: Due to Java's lack of support for multiple
- * inheritance, all of the logic in <code>ApplicationRequest</code> is
- * duplicated in <code>ApplicationHttpRequest</code>. 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 <code>getAttribute()</code> 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 <code>getAttributeNames()</code> method of the wrapped
- * request.
- */
- public Enumeration getAttributeNames() {
- return (new AttributeNamesEnumerator());
- }
-
-
- /**
- * Override the <code>removeAttribute()</code> 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 <code>setAttribute()</code> 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 <code>getContextPath()</code> method of the wrapped
- * request.
- */
- public String getContextPath() {
-
- return (this.contextPath);
-
- }
-
-
- /**
- * Override the <code>getParameter()</code> 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 <code>getParameterMap()</code> method of the
- * wrapped request.
- */
- public Map getParameterMap() {
-
- parseParameters();
- return (parameters);
-
- }
-
-
- /**
- * Override the <code>getParameterNames()</code> method of the
- * wrapped request.
- */
- public Enumeration getParameterNames() {
-
- parseParameters();
- return (new Enumerator(parameters.keySet()));
-
- }
-
-
- /**
- * Override the <code>getParameterValues()</code> 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 <code>getPathInfo()</code> method of the wrapped request.
- */
- public String getPathInfo() {
-
- return (this.pathInfo);
-
- }
-
-
- /**
- * Override the <code>getQueryString()</code> method of the wrapped
- * request.
- */
- public String getQueryString() {
-
- return (this.queryString);
-
- }
-
-
- /**
- * Override the <code>getRequestURI()</code> method of the wrapped
- * request.
- */
- public String getRequestURI() {
-
- return (this.requestURI);
-
- }
-
-
- /**
- * Override the <code>getRequestURL()</code> 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 <code>getServletPath()</code> 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;
- }
-
- }
-
-
-}
+++ /dev/null
-/*
- * 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<Cookie> cookies = new ArrayList<Cookie>();
-
-
- /**
- * 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 <code>true</code> if we are currently inside a
- * RequestDispatcher.include(), else <code>false</code>
- */
- 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 <code>null</code> 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 <code>getWriter</code> 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 <code>getOutputStream</code> 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 <code>getCharacterEncoding</code> (i.e., the method
- * just returns the default value <code>ISO-8859-1</code>),
- * <code>getWriter</code> updates it to <code>ISO-8859-1</code>
- * (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 <code>null</code> 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<String> getHeaderNames() {
- return getHttpResponse().getHeaderNames();
- }
-
- public Collection<String> 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 <code>sendError()</code>
- * 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
- * <code>encodeRedirectURL()</code> 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
- * <code>encodeURL()</code> 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("<html><body><h1>Status: " +
- status + "</h1><h1>Message: " + message +
- "</h1></body></html>");
- 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 <code>true</code> if the specified URL should be encoded with
- * a session identifier. This will be true if all of the following
- * conditions are met:
- * <ul>
- * <li>The request we are responding to asked for a valid session
- * <li>The requested session ID was not received via a cookie
- * <li>The specified URL points back to somewhere within the web
- * application that is responding to this request
- * </ul>
- *
- * @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());
- }
-
-
-
-}
-
+++ /dev/null
-/*
- * 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) {
- }
-}
+++ /dev/null
-/*
- * 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();
- }
-
-
-}
+++ /dev/null
-/*
- * 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<ServletContextImpl> 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<String,String> preloadServlets = new HashMap();
- Map<String,String> preloadMappings = new HashMap();
-
- Map<String,String> 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/*<ServletContextImpl>*/ 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<ServletContext> 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;
- }
-}
+++ /dev/null
-/*
- * 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<FilterMap> 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 <code>null</code>.
- *
- * @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 <code>true</code> if the context-relative request path
- * matches the requirements of the specified filter mapping;
- * otherwise, return <code>null</code>.
- *
- * @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 <code>true</code> if the specified servlet name matches
- * the requirements of the specified filter mapping; otherwise
- * return <code>false</code>.
- *
- * @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() {
- }
-
-}
+++ /dev/null
-/*
- */
-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;
- }
-
-}
+++ /dev/null
-/**
- *
- */
-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<String> fileName = new ArrayList<String>();
- public long timestamp;
-
- public boolean full;
-
- public String displayName;
-
- public HashMap<String, String> contextParam = new HashMap<String, String>();
-
- public HashMap<String, String> mimeMapping = new HashMap<String, String>(); // extension -> mime-type
-
- public ArrayList<String> listenerClass = new ArrayList<String>();
-
- public ArrayList<String> welcomeFileList = new ArrayList<String>();
-
- // code -> location
- public HashMap<String, String> errorPageCode= new HashMap<String, String>();
-
- // exception -> location
- public HashMap<String, String> errorPageException= new HashMap<String, String>();
-
- public HashMap<String, String> localeEncodingMapping= new HashMap<String, String>(); // locale -> encoding
-
- // public HashMap tagLibs; // uri->location
- // jsp-property-group
-
- // securityConstraint
- public ArrayList<SecurityConstraintData> securityConstraint = new ArrayList<SecurityConstraintData>();
-
- // loginConfig
- public String authMethod;
- public String realmName;
- public String formLoginPage;
- public String formErrorPage;
-
- public ArrayList<String> securityRole = new ArrayList<String>();
-
- // envEntry
- public ArrayList<EnvEntryData> envEntry = new ArrayList<EnvEntryData>();
-
- // ejbRef
- // ejbLocalRef
- // serviceRef
- // resourceRef
- // resourceEnvRef
- // message-destination
- // message-destinationRef
- public HashMap<String, FilterData> filters = new HashMap<String, FilterData>();
- public HashMap<String, ServletData> servlets = new HashMap<String, ServletData>();
-
- public int sessionTimeout;
- public boolean distributable;
-
- public HashMap<String, String> servletMapping = new HashMap<String, String>(); // url -> servlet
- public ArrayList<FilterMappingData> filterMappings = new ArrayList<FilterMappingData>();
- 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<String> dispatcher = new ArrayList<String>();
- }
-
- 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<String, String> initParams = new HashMap<String, String>();
-
- 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<String, String> securityRoleRef = new HashMap<String, String>(); // roleName -> [roleLink]
- public boolean multipartConfig = false;
-
- public List<String> declaresRoles = new ArrayList<String>();
-
- }
-
- public static class WebResourceCollectionData implements Serializable {
- public String webResourceName;
- public ArrayList<String> urlPattern = new ArrayList<String>();
- public ArrayList<String> httpMethod = new ArrayList<String>();
- }
-
- public static class SecurityConstraintData implements Serializable {
- private static final long serialVersionUID = -4780214921810871769L;
-
- public ArrayList<String> roleName = new ArrayList<String>(); // auth-constraint/role
-
- public ArrayList<WebResourceCollectionData> webResourceCollection =
- new ArrayList<WebResourceCollectionData>();
- public String transportGuarantee;
-
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- */
-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<JarEntry> 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<String, Object> asmList2Map(List list) {
- Map<String, Object> 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<String, AnnotationNode> annotationMap(List annL) {
- Map<String, AnnotationNode> 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<String, AnnotationNode> 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<String, Object> 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<String, AnnotationNode> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, AnnotationNode> annotations) {
- AnnotationNode webFilterA = annotations.get("javax.servlet.annotation.WebServlet");
- if (webFilterA != null) {
- // TODO: validity checks (implements servlet, etc)
-
- FilterData sd = new FilterData();
- Map<String, Object> 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<String, Object> 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<String, Object> 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;
- }
-
-
-}
+++ /dev/null
-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<attrs.getLength(); i++ ) {
-// Node n=attrs.item(i);
-// String name=n.getNodeName();
-// String value=n.getNodeValue();
-//
-//// if( log.isTraceEnabled() )
-//// log.trace("Attribute " + parent.getNodeName() + " " +
-//// name + "=" + value);
-// try {
-// IntrospectionUtils.setProperty(o, name, value);
-// } catch( Exception ex ) {
-// ex.printStackTrace();
-// }
-// }
-// }
-
- /** Read XML as DOM.
- */
- public static Document readXml(InputStream is)
- throws SAXException, IOException, ParserConfigurationException
- {
- DocumentBuilderFactory dbf =
- DocumentBuilderFactory.newInstance();
-
- dbf.setValidating(false);
- dbf.setIgnoringComments(false);
- dbf.setIgnoringElementContentWhitespace(true);
- //dbf.setCoalescing(true);
- //dbf.setExpandEntityReferences(true);
-
- DocumentBuilder db = null;
- db = dbf.newDocumentBuilder();
- db.setEntityResolver( new NullResolver() );
-
- // db.setErrorHandler( new MyErrorHandler());
-
- Document doc = db.parse(is);
- return doc;
- }
-
-}
+++ /dev/null
-/*
- */
-package org.apache.tomcat.servlets.config.deploy;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
-import org.apache.tomcat.servlets.config.ConfigLoader;
-import org.apache.tomcat.servlets.config.ServletContextConfig;
-
-/**
- * Independent of tomcat-lite - will read the current context config,
- * parse classes/jars for annotations - and generate a .ser file
- * containing all info.
- *
- * This can be used to display informations about the config ( in a
- * container-independent servlet ), or by the container for faster
- * load times.
- *
- * @author Costin Manolache
- */
-public class WarDeploy extends ConfigLoader implements Runnable {
-
- public ServletContextConfig loadConfig(String basePath) {
- ServletContextConfig contextConfig = super.loadConfig(basePath);
-
- boolean needsDeploy = contextConfig == null;
-
- if (contextConfig != null) {
- if (contextConfig.version != ServletContextConfig.CURRENT_VERSION) {
- needsDeploy = true;
- } else {
- // Check web.xml and other dep file timestamp(s)
- for (String fn : contextConfig.fileName) {
- File f = new File(fn);
- if (f.lastModified() > contextConfig.timestamp) {
- needsDeploy = true;
- break;
- }
- }
- }
- }
-
- if (needsDeploy) {
- setBase(basePath);
- run();
- contextConfig = super.loadConfig(basePath);
- }
-
- return contextConfig;
- }
-
- @Override
- public void run() {
- if (base == null) {
- return; // nothing we can do
- }
-
- ServletContextConfig contextConfig = new ServletContextConfig();
- contextConfig.timestamp = System.currentTimeMillis();
-
- File webXmlF = new File(base + "/WEB-INF/web.xml");
- boolean needsAnnotations = true;
-
- if (webXmlF.exists()) {
- WebXml webXml = new WebXml(contextConfig);
- try {
- webXml.readWebXml(base + "/WEB-INF/web.xml");
- if (contextConfig.metadataComplete) {
- needsAnnotations = false;
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- try {
- if (needsAnnotations) {
- AnnotationsProcessor ap = new AnnotationsProcessor(contextConfig);
- ap.processWebapp(base);
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
-
-
- // Save
- try {
- ObjectOutputStream ois =
- new ObjectOutputStream(new FileOutputStream(base +
- ServletContextConfig.SERIALIZED_PATH));
- ois.writeObject(contextConfig);
- ois.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- }
-
- String base;
-
-
- public static void main(String[] args) {
- String base = args[0];
- WarDeploy wd = new WarDeploy();
- wd.setBase(base);
- wd.run();
- }
-
- private void setBase(String base) {
- this.base = base;
- }
-
-}
+++ /dev/null
-/*
- */
-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.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-import javax.servlet.ServletException;
-
-import org.apache.tomcat.servlets.config.ServletContextConfig;
-import org.apache.tomcat.servlets.config.ServletContextConfig.EnvEntryData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.FilterData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.FilterMappingData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.SecurityConstraintData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.ServletData;
-import org.apache.tomcat.servlets.config.ServletContextConfig.WebResourceCollectionData;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-/**
- * General-purpose utility to process an web.xml file. Result
- * is a tree of objects starting with WebAppData.
- *
- * TODO: allow writting of web.xml, allow modification ( preserving
- * comments )
- *
- * @author costin
- */
-public class WebXml {
- ServletContextConfig d;
-
- public WebXml(ServletContextConfig cfg) {
- d = cfg;
- }
-
- public void processJar(String path) throws IOException {
- JarFile jar = new JarFile(path);
- Enumeration<JarEntry> 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);
- }
-
-}
+++ /dev/null
-/*
- * 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;
-
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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("<html>\r\n");
- sb.append("<head>\r\n");
- sb.append("<title>");
- sb.append(dirName);
- sb.append("</title>\r\n");
- sb.append("<STYLE><!--");
- sb.append(TOMCAT_CSS);
- sb.append("--></STYLE> ");
- sb.append("</head>\r\n");
- sb.append("<body>");
- sb.append("<h1>");
- sb.append(dirName);
- sb.append("</h1>");
-
- sb.append("<HR size=\"1\" noshade=\"noshade\">");
-
-
- sb.append("<table width=\"100%\" cellspacing=\"0\"" +
- " cellpadding=\"5\" align=\"center\">\r\n");
-
- // Render the column headings
- sb.append("<tr>\r\n");
- sb.append("<td align=\"left\"><font size=\"+1\"><strong>");
- sb.append("Name");
- sb.append("</strong></font></td>\r\n");
- sb.append("<td align=\"center\"><font size=\"+1\"><strong>");
- sb.append("Size");
- sb.append("</strong></font></td>\r\n");
- sb.append("<td align=\"right\"><font size=\"+1\"><strong>");
- sb.append("Last Modified");
- sb.append("</strong></font></td>\r\n");
- sb.append("</tr>");
- 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("<tr>\r\n<td align=\"left\"> \r\n<a href=\"..");
-// sb.append(rewrittenContextPath);
-// if (parent.equals(""))
-// parent = "/";
-// sb.append(rewriteUrl(parent));
-// if (!parent.endsWith("/"))
-// sb.append("/");
- sb.append("\">");
- //sb.append("<b>");
- sb.append("..");
- //sb.append("</b>");
- sb.append("</a></td></tr>");
- shade = true;
- }
-
-
- // Render the directory entries within this directory
- String[] files = cacheEntry.list();
- for (int i=0; i<files.length; i++) {
-
- String resourceName = files[i];
- String trimmed = resourceName;//.substring(trim);
- if (trimmed.equalsIgnoreCase("WEB-INF") ||
- trimmed.equalsIgnoreCase("META-INF"))
- continue;
-
- File childCacheEntry = new File(cacheEntry, resourceName);
-
- sb.append("<tr");
- if (shade)
- sb.append(" bgcolor=\"#eeeeee\"");
- sb.append(">\r\n");
- shade = !shade;
-
- sb.append("<td align=\"left\"> \r\n");
- sb.append("<a href=\"");
- if (! relativePath.endsWith("/")) {
- sb.append(dirName + "/");
- }
- //sb.append(rewrittenContextPath);
-// if (! rewrittenContextPath.endsWith("/")) {
-// sb.append("/");
-// }
-// if ( ! relativePath.equals("")) {
-// String link = rewriteUrl(relativePath);
-// sb.append(link).append("/");
-// }
- sb.append(resourceName);
- boolean isDir = childCacheEntry.isDirectory();
- if (isDir)
- sb.append("/");
- sb.append("\"><tt>");
- sb.append(trimmed);
- if (isDir)
- sb.append("/");
- sb.append("</tt></a></td>\r\n");
-
- sb.append("<td align=\"right\"><tt>");
- if (isDir)
- sb.append(" ");
- else
- displaySize(sb,childCacheEntry.length());
- sb.append("</tt></td>\r\n");
-
- sb.append("<td align=\"right\"><tt>");
- sb.append(DefaultServlet.lastModifiedHttp(childCacheEntry));
- sb.append("</tt></td>\r\n");
-
- sb.append("</tr>\r\n");
- }
-
-
- // Render the page footer
- sb.append("</table>\r\n");
-
- sb.append("<HR size=\"1\" noshade=\"noshade\">");
-
- String readme = getReadme(cacheEntry);
- if (readme!=null) {
- sb.append(readme);
- sb.append("<HR size=\"1\" noshade=\"noshade\">");
- }
-
- sb.append("</body>\r\n");
- sb.append("</html>\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;
- }
-
-}
+++ /dev/null
-/*
- * 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;
-
- }
-}
+++ /dev/null
-/*
- */
-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);
- }
-
-
-}
+++ /dev/null
-/*
- */
-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);
- }
-}
+++ /dev/null
-/*
- * 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.
- * <p>
- * 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);
-
- }
-
-
-}
-
+++ /dev/null
-/*
- * 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();
- }
-}
+++ /dev/null
-/*
- * 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.
- * <p>
- * Key : path of the collection containing the lock-null resource<br>
- * 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<enumeration.length; i++) {
- String childDest = dest;
- if (!childDest.equals("/"))
- childDest += "/";
- childDest += enumeration[i].getName();
- String childSrc = source;
- if (!childSrc.equals("/"))
- childSrc += "/";
- childSrc += enumeration[i].getName();
- copyResource(resources, errorList, childSrc, childDest);
- }
-
- } else {
-
- try {
- CopyUtils.copy(new FileInputStream(object.getPath()),
- getOut(dest));
- } catch(IOException ex ) {
- errorList.put
- (source,
- new Integer(WebdavStatus.SC_INTERNAL_SERVER_ERROR));
- return false;
- }
-
- }
-
- return true;
-
- }
-
-
- /**
- * Delete a resource.
- *
- * @param req Servlet request
- * @param resp Servlet response
- * @return boolean true if the copy is successful
- */
- protected boolean deleteResource(HttpServletRequest req,
- HttpServletResponse resp)
- throws ServletException, IOException {
-
- String path = getRelativePath(req);
-
- return deleteResource(path, req, resp, true);
-
- }
-
-
- /**
- * Delete a resource.
- *
- * @param path Path of the resource which is to be deleted
- * @param req Servlet request
- * @param resp Servlet response
- * @param setStatus Should the response status be set on successful
- * completion
- */
- protected boolean deleteResource(String path, HttpServletRequest req,
- HttpServletResponse resp, boolean setStatus)
- throws ServletException, IOException {
-
- if ((path.toUpperCase().startsWith("/WEB-INF")) ||
- (path.toUpperCase().startsWith("/META-INF"))) {
- resp.sendError(WebdavStatus.SC_FORBIDDEN);
- return false;
- }
-
- String ifHeader = req.getHeader("If");
- if (ifHeader == null)
- ifHeader = "";
-
- String lockTokenHeader = req.getHeader("Lock-Token");
- if (lockTokenHeader == null)
- lockTokenHeader = "";
-
- if (isLocked(path, ifHeader + lockTokenHeader)) {
- resp.sendError(WebdavStatus.SC_LOCKED);
- return false;
- }
-
- boolean exists = true;
- File object = new File(basePath, path);
- if (!object.exists()) {
- exists = false;
- }
-
- if (!exists) {
- resp.sendError(WebdavStatus.SC_NOT_FOUND);
- return false;
- }
-
- boolean collection = object.isDirectory();
-
- if (!collection) {
- boolean deleted = object.delete();
- if (!deleted) {
- resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
- return false;
- }
- } else {
-
- Hashtable errorList = new Hashtable();
-
- deleteCollection(req, basePath, path, errorList);
- boolean deleted = object.delete();
- if (!deleted) {
- errorList.put(path, new Integer
- (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
- }
-
- if (!errorList.isEmpty()) {
-
- sendReport(req, resp, errorList);
- return false;
-
- }
-
- }
- if (setStatus) {
- resp.setStatus(WebdavStatus.SC_NO_CONTENT);
- }
- return true;
-
- }
-
-
- /**
- * Deletes a collection.
- *
- * @param resources Resources implementation associated with the context
- * @param path Path to the collection to be deleted
- * @param errorList Contains the list of the errors which occurred
- */
- protected void deleteCollection(HttpServletRequest req,
- File resources,
- String path, Hashtable errorList) {
-
- if ((path.toUpperCase().startsWith("/WEB-INF")) ||
- (path.toUpperCase().startsWith("/META-INF"))) {
- errorList.put(path, new Integer(WebdavStatus.SC_FORBIDDEN));
- return;
- }
-
- String ifHeader = req.getHeader("If");
- if (ifHeader == null)
- ifHeader = "";
-
- String lockTokenHeader = req.getHeader("Lock-Token");
- if (lockTokenHeader == null)
- lockTokenHeader = "";
-
- File f = new File(basePath, path);
- File[] enumeration = f.listFiles();
-
- for (int i=0; i<enumeration.length; i++) {
- String childName = path;
- if (!childName.equals("/"))
- childName += "/";
-
- childName += enumeration[i].getName();
-
- if (isLocked(childName, ifHeader + lockTokenHeader)) {
-
- errorList.put(childName, new Integer(WebdavStatus.SC_LOCKED));
-
- } else {
- File object = enumeration[i];
- if (object.isDirectory()) {
- deleteCollection(req, resources, childName, errorList);
- }
-
- boolean deleted = object.delete();
- if (!deleted) {
- if (!(object.isDirectory())) {
- // If it's not a collection, then it's an unknown
- // error
- errorList.put
- (childName, new Integer
- (WebdavStatus.SC_INTERNAL_SERVER_ERROR));
- }
- }
- }
-
- }
-
- }
-
-
- /**
- * Send a multistatus element containing a complete error report to the
- * client.
- *
- * @param req Servlet request
- * @param resp Servlet response
- * @param errorList List of error to be displayed
- */
- protected void sendReport(HttpServletRequest req, HttpServletResponse resp,
- Hashtable errorList)
- throws ServletException, IOException {
-
- resp.setStatus(WebdavStatus.SC_MULTI_STATUS);
-
- String absoluteUri = req.getRequestURI();
- String relativePath = getRelativePath(req);
-
- XMLWriter generatedXML = new XMLWriter();
- generatedXML.writeXMLHeader();
-
- generatedXML.writeElement(null, "multistatus"
- + generateNamespaceDeclarations(),
- XMLWriter.OPENING);
-
- Enumeration pathList = errorList.keys();
- while (pathList.hasMoreElements()) {
-
- String errorPath = (String) pathList.nextElement();
- int errorCode = ((Integer) errorList.get(errorPath)).intValue();
-
- generatedXML.writeElement(null, "response", XMLWriter.OPENING);
-
- generatedXML.writeElement(null, "href", XMLWriter.OPENING);
- String toAppend = errorPath.substring(relativePath.length());
- if (!toAppend.startsWith("/"))
- toAppend = "/" + toAppend;
- generatedXML.writeText(absoluteUri + toAppend);
- generatedXML.writeElement(null, "href", XMLWriter.CLOSING);
- generatedXML.writeElement(null, "status", XMLWriter.OPENING);
- generatedXML
- .writeText("HTTP/1.1 " + errorCode + " "
- + WebdavStatus.getStatusText(errorCode));
- generatedXML.writeElement(null, "status", XMLWriter.CLOSING);
-
- generatedXML.writeElement(null, "response", XMLWriter.CLOSING);
-
- }
-
- generatedXML.writeElement(null, "multistatus", XMLWriter.CLOSING);
-
- Writer writer = resp.getWriter();
- writer.write(generatedXML.toString());
- writer.close();
-
- }
-
-
-
-
- /**
- * Return JAXP document builder instance.
- */
- protected DocumentBuilder getDocumentBuilder()
- throws ServletException {
- DocumentBuilder documentBuilder = null;
- DocumentBuilderFactory documentBuilderFactory = null;
- try {
- documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setNamespaceAware(true);
- documentBuilder = documentBuilderFactory.newDocumentBuilder();
- } catch(ParserConfigurationException e) {
- throw new ServletException("Parser error " + e);
- }
- return documentBuilder;
- }
-
-
-
- /**
- * Get creation date in ISO format.
- */
- protected String getISOCreationDate(long creationDate) {
- StringBuilder creationDateValue = new StringBuilder
- (creationDateFormat.format
- (new Date(creationDate)));
- /*
- int offset = Calendar.getInstance().getTimeZone().getRawOffset()
- / 3600000; // FIXME ?
- if (offset < 0) {
- creationDateValue.append("-");
- offset = -offset;
- } else if (offset > 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);
- }
-
-};
-
+++ /dev/null
-/*
- * 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 <a href="mailto:remm@apache.org">Remy Maucherat</a>
- */
-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("</" + namespace + ":" + name + ">\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("</" + name + ">\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("<![CDATA[" + data + "]]>");
- }
-
-
- /**
- * Write XML Header.
- */
- public void writeXMLHeader() {
- buffer.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
- }
-
-
- /**
- * Send data and reinitializes buffer.
- */
- public void sendData()
- throws IOException {
- if (writer != null) {
- writer.write(buffer.toString());
- buffer = new StringBuilder();
- }
- }
-
-
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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 <jsp-file> 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);
- }
- }
-}
+++ /dev/null
-/*
- * 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();
- }
-
-
- }
-}
+++ /dev/null
-/*
- * 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<String, Servlet> jsps=new HashMap<String, Servlet>();
-
- BaseJspLoader mapper;
-
- /**
- * If called from a <jsp-file> 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);
- }
-}
+++ /dev/null
-/*
- */
-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);
- }
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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 {
- }
-
-
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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 <code>allow</code> regular expressions we will evaluate.
- */
- protected Pattern allows[] = new Pattern[0];
-
-
- /**
- * The set of <code>deny</code> 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<patSplit.length; i++) {
- patSplit[i] = patSplit[i].trim();
- if (!patSplit[i].equals("")) {
- allowsAL.add(Pattern.compile(patSplit[i]));
- }
- }
- // TODO
- Pattern[] result = new Pattern[allowsAL.size()];
- allowsAL.toArray(result);
- return result;
- }
-
- public void destroy() {
- }
-
-
- public void doFilter(ServletRequest request,
- ServletResponse servletResponse,
- FilterChain chain)
- throws IOException, ServletException {
-
- HttpServletResponse response = (HttpServletResponse)servletResponse;
- String property = request.getRemoteAddr();
-
- // Check the deny patterns, if any
- for (int i = 0; i < denies.length; i++) {
- if (denies[i].matcher(property).matches()) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
- }
-
- // Check the allow patterns, if any
- for (int i = 0; i < allows.length; i++) {
- if (allows[i].matcher(property).matches()) {
- chain.doFilter(request, response);
- return;
- }
- }
-
- // Allow if denies specified but not allows
- if ((denies.length > 0) && (allows.length == 0)) {
- chain.doFilter(request, response);
- return;
- }
-
- // Deny this request
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
-
-
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
-
-}
+++ /dev/null
-/*
- * 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) {
-
- }
-
-
-}
+++ /dev/null
-/*
- */
-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);
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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 <b>Session</b> 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 <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
- */
-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
- * <code>null</code> 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 <code>Enumeration</code> of <code>String</code> 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
- * <code>null</code> 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
- * <code>getAttribute()</code>
- */
- 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
- * <code>getAttributeNames()</code>
- */
- 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 <code>true</code> 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.
- * <p>
- * After this method executes, and if the object implements
- * <code>HttpSessionBindingListener</code>, the container calls
- * <code>valueBound()</code> 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 <code>isNew</code> flag for this session.
- *
- * @param isNew The new value for the <code>isNew</code> 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 <code>isValid</code> 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.
- * <p>
- * After this method executes, and if the object implements
- * <code>HttpSessionBindingListener</code>, the container calls
- * <code>valueUnbound()</code> 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 <code>HttpSessionContext</code>
- * interface, to conform to the requirement that such an object be returned
- * when <code>HttpSession.getSessionContext()</code> 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 <code>Enumeration</code>
- * and will be removed in a future version of the API.
- */
- public Enumeration getIds() {
-
- return (new Enumerator(dummy));
-
- }
-
-
- /**
- * Return the <code>HttpSession</code> 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);
-
- }
-
-
-
-}
+++ /dev/null
-/*
- * 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
- * <code>java.security.MessageDigest</code> 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;
- }
-}
+++ /dev/null
-/*
- * 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 <b>Manager</b> 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 <code>true</code>, 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
- * <code>null</code>.
- *
- * @param sessionId The session id which should be used to create the
- * new session; if <code>null</code>, 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 <code>null</code>.
- *
- * @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<cookies.length; i++) {
- if (cn.equals(cookies[i].getName())) {
- String id = cookies[i].getValue();
- // TODO: mark session from cookie, check validity
- }
- }
- return null;
- }
-
- public String getSessionIdFromUrl(HttpServletRequest req) {
-
- return null;
- }
-
-
- public boolean isValid(HttpSession session) {
- return ((HttpSessionImpl) session).isValid();
- }
-
- public void endAccess(HttpSession session) {
- ((HttpSessionImpl) session).endAccess();
- }
-
- public void access(HttpSession session) {
- ((HttpSessionImpl) session).access();
- }
-}
+++ /dev/null
-/*
- */
-package org.apache.tomcat.servlets.session;
-
-import java.io.IOException;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
-
-/**
- * Session management plugin. No dependency on tomcat-lite, should
- * be possible to add this to tomcat-trunk or other containers.
- *
- * The container will:
- * - extract the session id from request ( via a filter or built-ins )
- * - call this interface when the user makes the related calls in the
- * servlet API.
- * - provide a context attribute 'context-listeners' with the
- * List<EventListener> 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);
-
-
-}
+++ /dev/null
-/*
- * 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 <code>Enumeration</code> around a Java2
- * collection classes object <code>Iterator</code> 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 <code>Iterator</code> over which the <code>Enumeration</code>
- * represented by this class actually operates.
- */
- private Iterator iterator = null;
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Tests if this enumeration contains more elements.
- *
- * @return <code>true</code> if and only if this enumeration object
- * contains at least one more element to provide, <code>false</code>
- * 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());
-
- }
-
-
-}
+++ /dev/null
-/*
- * 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 <code>Set-Cookie</code> 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. <strong>WARNING</strong> - 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,
- * <code>null</code> 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.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong>: 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.
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong>: 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);
- }
- }
-
- }
-
-
-
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- */
-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();
-// }
- }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-
-}
-
+++ /dev/null
-/*
- */
-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();
-// }
-// }
-
-
-}
+++ /dev/null
-/*
- */
-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");
- }
-}
+++ /dev/null
-/*
- */
-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);
- }
-}
+++ /dev/null
-/*
- * 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);
-// }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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.
- }
-}