Author: schultz
Date: Fri Jan 21 18:32:39 2011
New Revision: 1061953

URL: http://svn.apache.org/viewvc?rev=1061953&view=rev
Log:
Re-fixed bug #49711: HttpServletRequest#getParts() does not work in a Filter
- Moved allowCasualMultipartParsing setting from <Connector> to <Context>


Modified:
    tomcat/trunk/java/org/apache/catalina/Context.java
    tomcat/trunk/java/org/apache/catalina/connector/Connector.java
    tomcat/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java
    tomcat/trunk/test/org/apache/catalina/core/TestStandardContext.java
    tomcat/trunk/webapps/docs/changelog.xml
    tomcat/trunk/webapps/docs/config/ajp.xml
    tomcat/trunk/webapps/docs/config/context.xml
    tomcat/trunk/webapps/docs/config/http.xml

Modified: tomcat/trunk/java/org/apache/catalina/Context.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Context.java Fri Jan 21 18:32:39 2011
@@ -89,6 +89,26 @@ public interface Context extends Contain
 
     // ------------------------------------------------------------- Properties
 
+    /**
+     * Set to <code>true</code> to allow requests mapped to servlets that
+     * do not explicitly declare @MultipartConfig or have
+     * &lt;multipart-config&gt; specified in web.xml to parse
+     * multipart/form-data requests.
+     *
+     * @param allowCasualMultipartParsing <code>true</code> to allow such
+     *        casual parsing, <code>false</code> otherwise.
+     */
+    public void setAllowCasualMultipartParsing(boolean 
allowCasualMultipartParsing);
+
+    /**
+     * Returns <code>true</code> if requests mapped to servlets without
+     * "multipart config" to parse multipart/form-data requests anyway.
+     *
+     * @return <code>true</code> if requests mapped to servlets without
+     *    "multipart config" to parse multipart/form-data requests,
+     *    <code>false</code> otherwise.
+     */
+    public boolean getAllowCasualMultipartParsing();
 
     /**
      * Return the set of initialized application event listener objects,

Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Connector.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Connector.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Connector.java Fri Jan 21 
18:32:39 2011
@@ -247,13 +247,6 @@ public class Connector extends Lifecycle
      protected boolean useBodyEncodingForURI = false;
 
 
-    /**
-     * Allow multipart/form-data requests to be parsed even when the
-     * target servlet doesn't specify @MultipartConfig or have a
-     * &lt;multipart-config&gt; element.
-     */
-    protected boolean allowCasualMultipartParsing = false;
-     
      protected static HashMap<String,String> replacements =
          new HashMap<String,String>();
      static {
@@ -775,33 +768,6 @@ public class Connector extends Lifecycle
      }
 
     /**
-     * Set to <code>true</code> to allow requests mapped to servlets that
-     * do not explicitly declare @MultipartConfig or have
-     * &lt;multipart-config&gt; specified in web.xml to parse
-     * multipart/form-data requests.
-     *
-     * @param allowCasualMultipartParsing <code>true</code> to allow such
-     *        casual parsing, <code>false</code> otherwise.
-     */
-    public void setAllowCasualMultipartParsing(boolean 
allowCasualMultipartParsing)
-    {
-        this.allowCasualMultipartParsing = allowCasualMultipartParsing;
-    }
-
-    /**
-     * Returns <code>true</code> if requests mapped to servlets without
-     * "multipart config" to parse multipart/form-data requests anyway.
-     *
-     * @return <code>true</code> if requests mapped to servlets without
-     *    "multipart config" to parse multipart/form-data requests,
-     *    <code>false</code> otherwise.
-     */
-    protected boolean getAllowCasualMultipartParsing()
-    {
-        return this.allowCasualMultipartParsing;
-    }
-
-    /**
      * Indicates whether the generation of an X-Powered-By response header for
      * servlet-generated responses is enabled or disabled for this Connector.
      *

Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Jan 21 
18:32:39 2011
@@ -2547,8 +2547,7 @@ public class Request
         MultipartConfigElement mce = getWrapper().getMultipartConfigElement();
 
         if (mce == null) {
-            Connector connector = getConnector();
-            if(connector.getAllowCasualMultipartParsing()) {
+            if(getContext().getAllowCasualMultipartParsing()) {
                 mce = new MultipartConfigElement(null,
                                                  connector.getMaxPostSize(),
                                                  connector.getMaxPostSize(),

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Fri Jan 21 
18:32:39 2011
@@ -191,6 +191,13 @@ public class StandardContext extends Con
 
 
     /**
+     * Allow multipart/form-data requests to be parsed even when the
+     * target servlet doesn't specify @MultipartConfig or have a
+     * &lt;multipart-config&gt; element.
+     */
+    protected boolean allowCasualMultipartParsing = false;
+     
+    /**
      * The alternate deployment descriptor name.
      */
     private String altDDName = null;
@@ -1001,6 +1008,34 @@ public class StandardContext extends Con
         return allowLinking;
     }
 
+    /**
+     * Set to <code>true</code> to allow requests mapped to servlets that
+     * do not explicitly declare @MultipartConfig or have
+     * &lt;multipart-config&gt; specified in web.xml to parse
+     * multipart/form-data requests.
+     *
+     * @param allowCasualMultipartParsing <code>true</code> to allow such
+     *        casual parsing, <code>false</code> otherwise.
+     */
+    @Override
+    public void setAllowCasualMultipartParsing(boolean 
allowCasualMultipartParsing)
+    {
+        this.allowCasualMultipartParsing = allowCasualMultipartParsing;
+    }
+
+    /**
+     * Returns <code>true</code> if requests mapped to servlets without
+     * "multipart config" to parse multipart/form-data requests anyway.
+     *
+     * @return <code>true</code> if requests mapped to servlets without
+     *    "multipart config" to parse multipart/form-data requests,
+     *    <code>false</code> otherwise.
+     */
+    @Override
+    public boolean getAllowCasualMultipartParsing()
+    {
+        return this.allowCasualMultipartParsing;
+    }
 
     /**
      * Set cache TTL.

Modified: tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java (original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java Fri Jan 21 
18:32:39 2011
@@ -25,9 +25,7 @@ import java.net.URL;
 import java.util.Enumeration;
 import java.util.TreeMap;
 
-import javax.servlet.MultipartConfigElement;
 import javax.servlet.ServletException;
-import javax.servlet.annotation.MultipartConfig;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -527,167 +525,6 @@ public class TestRequest extends TomcatB
         }
     }
 
-    /**
-     * Test case for bug 49711: HttpServletRequest.getParts does not work
-     * in a filter.
-     */
-    public void testBug49711() {
-        Bug49711Client client = new Bug49711Client();
-        client.setPort(getPort());
-
-        // Make sure non-multipart works properly
-        client.doRequest("/regular", false, false);
-
-        assertEquals("Incorrect response for GET request",
-                     "parts=0",
-                     client.getResponseBody());
-
-        client.reset();
-
-        // Make sure regular multipart works properly
-        client.doRequest("/multipart", false, true); // send multipart request
-
-        assertEquals("Regular multipart doesn't work",
-                     "parts=1",
-                     client.getResponseBody());
-
-        client.reset();
-
-        // Make casual multipart request to "regular" servlet w/o config
-        // We expect that no parts will be available
-        client.doRequest("/regular", false, true); // send multipart request
-
-        assertEquals("Incorrect response for non-configured casual multipart 
request",
-                     "parts=0", // multipart request should be ignored
-                     client.getResponseBody());
-
-        client.reset();
-
-        // Make casual multipart request to "regular" servlet w/config
-        // We expect that the server /will/ parse the parts, even though
-        // there is no @MultipartConfig
-        client.doRequest("/regular", true, true); // send multipart request
-
-        assertEquals("Incorrect response for configured casual multipart 
request",
-                     "parts=1",
-                     client.getResponseBody());
-
-        client.reset();
-    }
-
-    private static class Bug49711Servlet extends HttpServlet {
-        @Override
-        protected void service(HttpServletRequest req, HttpServletResponse 
resp)
-            throws ServletException, IOException {
-            // Just echo the parameters and values back as plain text
-            resp.setContentType("text/plain");
-            resp.setCharacterEncoding("UTF-8");
-
-            PrintWriter out = resp.getWriter();
-            
-            out.println("parts=" + (null == req.getParts()
-                                    ? "null"
-                                    : req.getParts().size()));
-        }
-    }
-
-    @MultipartConfig
-    private static class Bug49711Servlet_multipart extends Bug49711Servlet {
-    }
-
-    /**
-     * Bug 49711 test client: test for casual getParts calls.
-     */
-    private class Bug49711Client extends SimpleHttpClient {
-
-        private boolean init;
-        
-        private synchronized void init() throws Exception {
-            if (init) return;
-            
-            Tomcat tomcat = getTomcatInstance();
-            Context root = tomcat.addContext("", TEMP_DIR);
-            Tomcat.addServlet(root, "regular", new Bug49711Servlet());
-            Wrapper w = Tomcat.addServlet(root, "multipart", new 
Bug49711Servlet_multipart());
-
-            // Tomcat.addServlet does not respect annotations, so we have
-            // to set our own MultipartConfigElement.
-            w.setMultipartConfigElement(new MultipartConfigElement(""));
-
-            root.addServletMapping("/regular", "regular");
-            root.addServletMapping("/multipart", "multipart");
-            tomcat.start();
-            
-            init = true;
-        }
-        
-        private Exception doRequest(String uri,
-                                    boolean allowCasualMultipart,
-                                    boolean makeMultipartRequest) {
-            Tomcat tomcat = getTomcatInstance();
-
-            
tomcat.getConnector().setAllowCasualMultipartParsing(allowCasualMultipart);
-
-            try {
-                init();
-
-                // Open connection
-                connect();
-
-                // Send specified request body using method
-                String[] request;
-
-                if(makeMultipartRequest) {
-                    String boundary = "--simpleboundary";
-
-                    String content = "--" + boundary + CRLF
-                        + "Content-Disposition: form-data; name=\"name\"" + 
CRLF + CRLF
-                        + "value" + CRLF
-                        + "--" + boundary + "--" + CRLF
-                        ;
-
-                    // Re-encode the content so that bytes = characters
-                    if(null != content)
-                        content = new String(content.getBytes("UTF-8"), 
"ASCII");
-
-                    request = new String[] {
-                        "POST http://localhost:"; + getPort() + uri + " 
HTTP/1.1" + CRLF
-                        + "Host: localhost" + CRLF
-                        + "Connection: close" + CRLF
-                        + "Content-Type: multipart/form-data; boundary=" + 
boundary + CRLF
-                        + "Content-Length: " + content.length() + CRLF
-                        + CRLF
-                        + content
-                        + CRLF
-                    };
-                }
-                else
-                {
-                    request = new String[] {
-                        "GET http://localhost:"; + getPort() + uri + " 
HTTP/1.1" + CRLF
-                        + "Host: localhost" + CRLF
-                        + "Connection: close" + CRLF
-                        + CRLF
-                    };
-                }
-
-                setRequest(request);
-                processRequest(); // blocks until response has been read
-                
-                // Close the connection
-                disconnect();
-            } catch (Exception e) {
-                return e;
-            }
-            return null;
-        }
-
-        @Override
-        public boolean isResponseBodyOK() {
-            return false; // Don't care
-        }
-    }
-
     private HttpURLConnection getConnection() throws IOException {
         final String query = "http://localhost:"; + getPort() + "/";
         URL postURL;

Modified: tomcat/trunk/test/org/apache/catalina/core/TestStandardContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestStandardContext.java?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestStandardContext.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestStandardContext.java Fri Jan 
21 18:32:39 2011
@@ -19,12 +19,14 @@ package org.apache.catalina.core;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.util.Set;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.HttpConstraintElement;
+import javax.servlet.MultipartConfigElement;
 import javax.servlet.Servlet;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
@@ -33,12 +35,14 @@ import javax.servlet.ServletRegistration
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.ServletSecurityElement;
+import javax.servlet.annotation.MultipartConfig;
 import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
 import org.apache.catalina.authenticator.BasicAuthenticator;
 import org.apache.catalina.deploy.FilterDef;
 import org.apache.catalina.deploy.FilterMap;
@@ -316,4 +320,165 @@ public class TestStandardContext extends
         }
         
     }
+
+    /**
+     * Test case for bug 49711: HttpServletRequest.getParts does not work
+     * in a filter.
+     */
+    public void testBug49711() {
+        Bug49711Client client = new Bug49711Client();
+        client.setPort(getPort());
+
+        // Make sure non-multipart works properly
+        client.doRequest("/regular", false, false);
+
+        assertEquals("Incorrect response for GET request",
+                     "parts=0",
+                     client.getResponseBody());
+
+        client.reset();
+
+        // Make sure regular multipart works properly
+        client.doRequest("/multipart", false, true); // send multipart request
+
+        assertEquals("Regular multipart doesn't work",
+                     "parts=1",
+                     client.getResponseBody());
+
+        client.reset();
+
+        // Make casual multipart request to "regular" servlet w/o config
+        // We expect that no parts will be available
+        client.doRequest("/regular", false, true); // send multipart request
+
+        assertEquals("Incorrect response for non-configured casual multipart 
request",
+                     "parts=0", // multipart request should be ignored
+                     client.getResponseBody());
+
+        client.reset();
+
+        // Make casual multipart request to "regular" servlet w/config
+        // We expect that the server /will/ parse the parts, even though
+        // there is no @MultipartConfig
+        client.doRequest("/regular", true, true); // send multipart request
+
+        assertEquals("Incorrect response for configured casual multipart 
request",
+                     "parts=1",
+                     client.getResponseBody());
+
+        client.reset();
+    }
+
+    private static class Bug49711Servlet extends HttpServlet {
+        @Override
+        protected void service(HttpServletRequest req, HttpServletResponse 
resp)
+            throws ServletException, IOException {
+            // Just echo the parameters and values back as plain text
+            resp.setContentType("text/plain");
+            resp.setCharacterEncoding("UTF-8");
+
+            PrintWriter out = resp.getWriter();
+            
+            out.println("parts=" + (null == req.getParts()
+                                    ? "null"
+                                    : req.getParts().size()));
+        }
+    }
+
+    @MultipartConfig
+    private static class Bug49711Servlet_multipart extends Bug49711Servlet {
+    }
+
+    /**
+     * Bug 49711 test client: test for casual getParts calls.
+     */
+    private class Bug49711Client extends SimpleHttpClient {
+
+        private boolean init;
+        private Context context;
+
+        private synchronized void init() throws Exception {
+            if (init) return;
+            
+            Tomcat tomcat = getTomcatInstance();
+            context = tomcat.addContext("", TEMP_DIR);
+            Tomcat.addServlet(context, "regular", new Bug49711Servlet());
+            Wrapper w = Tomcat.addServlet(context, "multipart", new 
Bug49711Servlet_multipart());
+
+            // Tomcat.addServlet does not respect annotations, so we have
+            // to set our own MultipartConfigElement.
+            w.setMultipartConfigElement(new MultipartConfigElement(""));
+
+            context.addServletMapping("/regular", "regular");
+            context.addServletMapping("/multipart", "multipart");
+            tomcat.start();
+            
+            init = true;
+        }
+        
+        private Exception doRequest(String uri,
+                                    boolean allowCasualMultipart,
+                                    boolean makeMultipartRequest) {
+            try {
+                init();
+
+                context.setAllowCasualMultipartParsing(allowCasualMultipart);
+
+                // Open connection
+                connect();
+
+                // Send specified request body using method
+                String[] request;
+
+                if(makeMultipartRequest) {
+                    String boundary = "--simpleboundary";
+
+                    String content = "--" + boundary + CRLF
+                        + "Content-Disposition: form-data; name=\"name\"" + 
CRLF + CRLF
+                        + "value" + CRLF
+                        + "--" + boundary + "--" + CRLF
+                        ;
+
+                    // Re-encode the content so that bytes = characters
+                    if(null != content)
+                        content = new String(content.getBytes("UTF-8"), 
"ASCII");
+
+                    request = new String[] {
+                        "POST http://localhost:"; + getPort() + uri + " 
HTTP/1.1" + CRLF
+                        + "Host: localhost" + CRLF
+                        + "Connection: close" + CRLF
+                        + "Content-Type: multipart/form-data; boundary=" + 
boundary + CRLF
+                        + "Content-Length: " + content.length() + CRLF
+                        + CRLF
+                        + content
+                        + CRLF
+                    };
+                }
+                else
+                {
+                    request = new String[] {
+                        "GET http://localhost:"; + getPort() + uri + " 
HTTP/1.1" + CRLF
+                        + "Host: localhost" + CRLF
+                        + "Connection: close" + CRLF
+                        + CRLF
+                    };
+                }
+
+                setRequest(request);
+                processRequest(); // blocks until response has been read
+                
+                // Close the connection
+                disconnect();
+            } catch (Exception e) {
+                return e;
+            }
+
+            return null;
+        }
+
+        @Override
+        public boolean isResponseBodyOK() {
+            return false; // Don't care
+        }
+    }
 }

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 21 18:32:39 2011
@@ -69,7 +69,7 @@
         <bug>49711</bug>: HttpServletRequest#getParts will work in a filter
         or servlet without an @MultipartConfig annotation or
         MultipartConfigElement if the new "allowCasualMultipartParsing"
-        connector attribute is set to "true". (schultz)
+        context attribute is set to "true". (schultz)
       </fix>
       <fix>
         <bug>50582</bug>: Refactor access logging so chunked encoding is not

Modified: tomcat/trunk/webapps/docs/config/ajp.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/ajp.xml?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/ajp.xml (original)
+++ tomcat/trunk/webapps/docs/config/ajp.xml Fri Jan 21 18:32:39 2011
@@ -74,17 +74,6 @@
 
   <attributes>
 
-    <attribute name="allowCasualMultipartParsing" required="false">
-      <p>Set to true if Tomcat should automatically parse
-      multipart/form-data request bodies when HttpServletRequest.getPart*
-      or HttpServletRequest.getParameter* is called, even when the
-      target servlet isn't marked with the @MultipartConfig annotation
-      (See Servlet Specification 3.0, Section 3.2 for details).
-      Note that any setting other than <code>true</code> causes Tomcat
-      to behave in a way that is not technically spec-compliant.
-      The default is <code>false</code></p>
-    </attribute>
-
     <attribute name="allowTrace" required="false">
       <p>A boolean value which can be used to enable or disable the TRACE
       HTTP method. If not specified, this attribute is set to false.</p>

Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Fri Jan 21 18:32:39 2011
@@ -425,6 +425,17 @@
         is un-deployed.</p>
       </attribute>
 
+      <attribute name="allowCasualMultipartParsing" required="false">
+        <p>Set to true if Tomcat should automatically parse
+        multipart/form-data request bodies when HttpServletRequest.getPart*
+        or HttpServletRequest.getParameter* is called, even when the
+        target servlet isn't marked with the @MultipartConfig annotation
+        (See Servlet Specification 3.0, Section 3.2 for details).
+        Note that any setting other than <code>true</code> causes Tomcat
+        to behave in a way that is not technically spec-compliant.
+        The default is <code>false</code></p>
+      </attribute>
+
       <attribute name="allowLinking" required="false">
         <p>If the value of this flag is <code>true</code>, symlinks will be
         allowed inside the web application, pointing to resources outside the

Modified: tomcat/trunk/webapps/docs/config/http.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1061953&r1=1061952&r2=1061953&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/trunk/webapps/docs/config/http.xml Fri Jan 21 18:32:39 2011
@@ -74,17 +74,6 @@
 
   <attributes>
  
-    <attribute name="allowCasualMultipartParsing" required="false">
-      <p>Set to true if Tomcat should automatically parse
-      multipart/form-data request bodies when HttpServletRequest.getPart*
-      or HttpServletRequest.getParameter* is called, even when the
-      target servlet isn't marked with the @MultipartConfig annotation
-      (See Servlet Specification 3.0, Section 3.2 for details).
-      Note that any setting other than <code>true</code> causes Tomcat
-      to behave in a way that is not technically spec-compliant.
-      The default is <code>false</code></p>
-    </attribute>
-
     <attribute name="allowTrace" required="false">
       <p>A boolean value which can be used to enable or disable the TRACE
       HTTP method. If not specified, this attribute is set to false.</p>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to