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 + * <multipart-config> 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 - * <multipart-config> 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 - * <multipart-config> 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 + * <multipart-config> 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 + * <multipart-config> 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