All, Oops. I over-committed files. Evidently, svn commit doesn't work like cvs commit.
I'll back-out my changes to: tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Sorry for the noise. Thanks, -chris On 1/21/2011 12:46 PM, schu...@apache.org wrote: > Author: schultz > Date: Fri Jan 21 17:46:03 2011 > New Revision: 1061929 > > URL: http://svn.apache.org/viewvc?rev=1061929&view=rev > Log: > Fixed bug #49711: HttpServletRequest#getParts() does not work in a Filter > - Added <Connector> attribute allowCasualMultipartParsing (default false) > - Requests that contain multipart/form-data will be parsed in the absence of > @MultipartConfig when the above attribute is set to "true" > > > Modified: > tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java > tomcat/trunk/java/org/apache/catalina/connector/Connector.java > tomcat/trunk/java/org/apache/catalina/connector/Request.java > tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java > tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java > tomcat/trunk/webapps/docs/changelog.xml > tomcat/trunk/webapps/docs/config/ajp.xml > tomcat/trunk/webapps/docs/config/http.xml > > Modified: tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java?rev=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java > (original) > +++ tomcat/trunk/java/org/apache/catalina/ant/AbstractCatalinaTask.java Fri > Jan 21 17:46:03 2011 > @@ -170,6 +170,7 @@ public abstract class AbstractCatalinaTa > URLConnection conn = null; > InputStreamReader reader = null; > try { > + openRedirector(); > > // Create a connection for this command > conn = (new URL(url + command)).openConnection(); > > 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=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/connector/Connector.java (original) > +++ tomcat/trunk/java/org/apache/catalina/connector/Connector.java Fri Jan 21 > 17:46:03 2011 > @@ -246,6 +246,13 @@ 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>(); > @@ -767,6 +774,32 @@ 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 > > 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=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) > +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Jan 21 > 17:46:03 2011 > @@ -2537,7 +2537,7 @@ public class Request > > return parts; > } > - > + > private void parseParts() { > > // Return immediately if the parts have already been parsed > @@ -2545,13 +2545,22 @@ public class Request > return; > > MultipartConfigElement mce = > getWrapper().getMultipartConfigElement(); > + > if (mce == null) { > - parts = Collections.emptyList(); > - return; > + Connector connector = getConnector(); > + if(connector.getAllowCasualMultipartParsing()) { > + mce = new MultipartConfigElement(null, > + connector.getMaxPostSize(), > + connector.getMaxPostSize(), > + connector.getMaxPostSize()); > + } else { > + parts = Collections.emptyList(); > + return; > + } > } > > Parameters parameters = coyoteRequest.getParameters(); > - > + > File location; > String locationStr = mce.getLocation(); > if (locationStr == null || locationStr.length() == 0) { > @@ -2582,7 +2591,7 @@ public class Request > upload.setFileItemFactory(factory); > upload.setFileSizeMax(mce.getMaxFileSize()); > upload.setSizeMax(mce.getMaxRequestSize()); > - > + > parts = new ArrayList<Part>(); > try { > List<FileItem> items = upload.parseRequest(this); > @@ -2604,11 +2613,12 @@ public class Request > Parameters.DEFAULT_ENCODING)}); > } catch (UnsupportedEncodingException e) { > // Should not be possible > + e.printStackTrace(); > } > } > } > } > - > + > } catch (InvalidContentTypeException e) { > partsParseException = new ServletException(e); > } catch (FileUploadBase.SizeException e) { > > Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original) > +++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri Jan 21 > 17:46:03 2011 > @@ -242,6 +242,9 @@ public class AprEndpoint extends Abstrac > public String getSSLCipherSuite() { return SSLCipherSuite; } > public void setSSLCipherSuite(String SSLCipherSuite) { > this.SSLCipherSuite = SSLCipherSuite; } > > + protected boolean SSLFIPSMode = false; > + public boolean getSSLFIPSMode() { return SSLFIPSMode; } > + public void setSSLFIPSMode(boolean SSLFIPSMode) { this.SSLFIPSMode = > SSLFIPSMode; } > > /** > * SSL certificate file. > > 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=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java > (original) > +++ tomcat/trunk/test/org/apache/catalina/connector/TestRequest.java Fri Jan > 21 17:46:03 2011 > @@ -25,12 +25,15 @@ 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; > > import org.apache.catalina.Context; > +import org.apache.catalina.Wrapper; > import org.apache.catalina.authenticator.BasicAuthenticator; > import org.apache.catalina.deploy.LoginConfig; > import org.apache.catalina.startup.SimpleHttpClient; > @@ -524,6 +527,167 @@ 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/webapps/docs/changelog.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/webapps/docs/changelog.xml (original) > +++ tomcat/trunk/webapps/docs/changelog.xml Fri Jan 21 17:46:03 2011 > @@ -66,6 +66,12 @@ > Fix NPE in RemoteAddrFilter, RemoteHostFilter. (kkolinko) > </fix> > <fix> > + <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) > + </fix> > + <fix> > <bug>50582</bug>: Refactor access logging so chunked encoding is not > forced for all requests if bytes sent is logged. (markt) > </fix> > > Modified: tomcat/trunk/webapps/docs/config/ajp.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/ajp.xml?rev=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/webapps/docs/config/ajp.xml (original) > +++ tomcat/trunk/webapps/docs/config/ajp.xml Fri Jan 21 17:46:03 2011 > @@ -74,6 +74,17 @@ > > <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> > @@ -121,7 +132,7 @@ > to POST. This is useful in RESTful applications that want to > support POST-style semantics for PUT requests. > Note that any setting other than <code>POST</code> causes Tomcat > - to behave in a way that does against the intent of the servlet > + to behave in a way that goes against the intent of the servlet > specification. > The HTTP method TRACE is specifically forbidden here in accordance > with the HTTP specification. > > Modified: tomcat/trunk/webapps/docs/config/http.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1061929&r1=1061928&r2=1061929&view=diff > ============================================================================== > --- tomcat/trunk/webapps/docs/config/http.xml (original) > +++ tomcat/trunk/webapps/docs/config/http.xml Fri Jan 21 17:46:03 2011 > @@ -74,6 +74,17 @@ > > <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> > @@ -121,7 +132,7 @@ > to POST. This is useful in RESTful applications that want to > support POST-style semantics for PUT requests. > Note that any setting other than <code>POST</code> causes Tomcat > - to behave in a way that does against the intent of the servlet > + to behave in a way that goes against the intent of the servlet > specification. > The HTTP method TRACE is specifically forbidden here in accordance > with the HTTP specification. > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org >
signature.asc
Description: OpenPGP digital signature