From: schultz 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 A boolean value which can be used to enable or disable the TRACE
HTTP method. If not specified, this attribute is set to false.true 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 true to allow such
+ * casual parsing, false otherwise.
+ */
+ public void setAllowCasualMultipartParsing(boolean allowCasualMultipartParsing);
+
+ /**
+ * Returns true if requests mapped to servlets without
+ * "multipart config" to parse multipart/form-data requests anyway.
+ *
+ * @return true if requests mapped to servlets without
+ * "multipart config" to parse multipart/form-data requests,
+ * false otherwise.
+ */
+ public boolean getAllowCasualMultipartParsing();
/**
* Return the set of initialized application event listener objects,
diff --git a/java/org/apache/catalina/connector/Connector.java b/java/org/apache/catalina/connector/Connector.java
index 6f54c66d6..98fbc1c2e 100644
--- a/java/org/apache/catalina/connector/Connector.java
+++ b/java/org/apache/catalina/connector/Connector.java
@@ -247,13 +247,6 @@ public class Connector extends LifecycleMBeanBase {
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 HashMaptrue 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 true to allow such
- * casual parsing, false otherwise.
- */
- public void setAllowCasualMultipartParsing(boolean allowCasualMultipartParsing)
- {
- this.allowCasualMultipartParsing = allowCasualMultipartParsing;
- }
-
- /**
- * Returns true if requests mapped to servlets without
- * "multipart config" to parse multipart/form-data requests anyway.
- *
- * @return true if requests mapped to servlets without
- * "multipart config" to parse multipart/form-data requests,
- * false 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.
*
diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
index f65607878..0163c6ba7 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -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(),
diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java
index 0556cdd1b..331d78daf 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -191,6 +191,13 @@ public class StandardContext extends ContainerBase
/**
+ * 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 ContainerBase
return allowLinking;
}
+ /**
+ * Set to true 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 true to allow such
+ * casual parsing, false otherwise.
+ */
+ @Override
+ public void setAllowCasualMultipartParsing(boolean allowCasualMultipartParsing)
+ {
+ this.allowCasualMultipartParsing = allowCasualMultipartParsing;
+ }
+
+ /**
+ * Returns true if requests mapped to servlets without
+ * "multipart config" to parse multipart/form-data requests anyway.
+ *
+ * @return true if requests mapped to servlets without
+ * "multipart config" to parse multipart/form-data requests,
+ * false otherwise.
+ */
+ @Override
+ public boolean getAllowCasualMultipartParsing()
+ {
+ return this.allowCasualMultipartParsing;
+ }
/**
* Set cache TTL.
diff --git a/test/org/apache/catalina/connector/TestRequest.java b/test/org/apache/catalina/connector/TestRequest.java
index 8195543d0..90358ce20 100644
--- a/test/org/apache/catalina/connector/TestRequest.java
+++ b/test/org/apache/catalina/connector/TestRequest.java
@@ -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 TomcatBaseTest {
}
}
- /**
- * 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;
diff --git a/test/org/apache/catalina/core/TestStandardContext.java b/test/org/apache/catalina/core/TestStandardContext.java
index 270d4340b..dd344ae75 100644
--- a/test/org/apache/catalina/core/TestStandardContext.java
+++ b/test/org/apache/catalina/core/TestStandardContext.java
@@ -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 TomcatBaseTest {
}
}
+
+ /**
+ * 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
+ }
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 7a7d89603..fa0d90cd2 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -69,7 +69,7 @@
true causes Tomcat
- to behave in a way that is not technically spec-compliant.
- The default is false
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 true causes Tomcat
+ to behave in a way that is not technically spec-compliant.
+ The default is false
If the value of this flag is 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 A boolean value which can be used to enable or disable the TRACE
HTTP method. If not specified, this attribute is set to false.true, symlinks will be
allowed inside the web application, pointing to resources outside the
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index ce51cd82c..9cdf55682 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -74,17 +74,6 @@
true causes Tomcat
- to behave in a way that is not technically spec-compliant.
- The default is false