Author: rjung
Date: Tue Mar 8 17:18:16 2011
New Revision: 1079444
URL: http://svn.apache.org/viewvc?rev=1079444&view=rev
Log:
New context attribute "swallowAbortedUploads" allows
to make request data swallowing configurable for requests
that are too large.
Added:
tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java
(with props)
Modified:
tomcat/trunk/java/org/apache/catalina/Context.java
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/connector/Response.java
tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/trunk/java/org/apache/coyote/ActionCode.java
tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
tomcat/trunk/test/org/apache/catalina/startup/SimpleHttpClient.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/context.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=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Context.java Tue Mar 8 17:18:16 2011
@@ -111,6 +111,24 @@ public interface Context extends Contain
public boolean getAllowCasualMultipartParsing();
/**
+ * Set to <code>false</code> to disable request data swallowing
+ * after an upload was aborted due to size constraints.
+ *
+ * @param swallowAbortedUploads <code>false</code> to disable
+ * swallowing, <code>true</code> otherwise (default).
+ */
+ public void setSwallowAbortedUploads(boolean swallowAbortedUploads);
+
+ /**
+ * Returns <code>true</code> if remaining request data will be read
+ * (swallowed) even the request violates a data size constraint.
+ *
+ * @return <code>true</code> if data will be swallowed (default),
+ * <code>false</code> otherwise.
+ */
+ public boolean getSwallowAbortedUploads();
+
+ /**
* Return the set of initialized application event listener objects,
* in the order they were specified in the web application deployment
* descriptor, for this application.
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=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Tue Mar 8
17:18:16 2011
@@ -800,6 +800,9 @@ public class Request
*/
public void finishRequest() throws IOException {
// The reader and input stream don't need to be closed
+ // TODO: Is this ever called?
+ // If so, move input swallow disabling from
+ // Response.finishResponse() to here
}
@@ -2450,6 +2453,16 @@ public class Request
return (inputBuffer.available() > 0);
}
+ /**
+ * Disable swallowing of remaining input if configured
+ */
+ protected void disableSwallowInput() {
+ Context context = getContext();
+ if (context != null && !context.getSwallowAbortedUploads()) {
+ coyoteRequest.action(ActionCode.DISABLE_SWALLOW_INPUT, null);
+ }
+ }
+
public void cometClose() {
coyoteRequest.action(ActionCode.COMET_CLOSE,getEvent());
}
@@ -2620,6 +2633,7 @@ public class Request
} catch (InvalidContentTypeException e) {
partsParseException = new ServletException(e);
} catch (FileUploadBase.SizeException e) {
+ disableSwallowInput();
partsParseException = new IllegalStateException(e);
} catch (FileUploadException e) {
partsParseException = new IOException(e);
@@ -2845,6 +2859,7 @@ public class Request
context.getLogger().debug(
sm.getString("coyoteRequest.postTooLarge"));
}
+ disableSwallowInput();
return;
}
byte[] formData = null;
@@ -2922,6 +2937,7 @@ public class Request
if (connector.getMaxPostSize() > 0 &&
(body.getLength() + len) > connector.getMaxPostSize()) {
// Too much data
+ disableSwallowInput();
throw new IllegalArgumentException(
sm.getString("coyoteRequest.chunkedPostTooLarge"));
}
Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Tue Mar 8
17:18:16 2011
@@ -49,6 +49,7 @@ import org.apache.catalina.core.Applicat
import org.apache.catalina.security.SecurityUtil;
import org.apache.catalina.util.CharsetMapper;
import org.apache.catalina.util.DateTool;
+import org.apache.coyote.ActionCode;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.UEncoder;
import org.apache.tomcat.util.http.FastHttpDateFormat;
@@ -497,6 +498,15 @@ public class Response
*/
public void finishResponse()
throws IOException {
+ // Optionally disable swallowing of additional request data.
+ // TODO: Should be in Request.finishRequest(), but that method
+ // seems to get called never.
+ Context context = getContext();
+ if (context != null
+ && getStatus() ==
HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE
+ && !context.getSwallowAbortedUploads()) {
+ coyoteResponse.action(ActionCode.DISABLE_SWALLOW_INPUT, null);
+ }
// Writing leftover bytes
outputBuffer.close();
}
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=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Mar 8
17:18:16 2011
@@ -197,6 +197,12 @@ public class StandardContext extends Con
protected boolean allowCasualMultipartParsing = false;
/**
+ * Control whether remaining request data will be read
+ * (swallowed) even if the request violates a data size constraint.
+ */
+ public boolean swallowAbortedUploads = true;
+
+ /**
* The alternate deployment descriptor name.
*/
private String altDDName = null;
@@ -1066,6 +1072,30 @@ public class StandardContext extends Con
}
/**
+ * Set to <code>false</code> to disable request data swallowing
+ * after an upload was aborted due to size constraints.
+ *
+ * @param swallowAbortedUploads <code>false</code> to disable
+ * swallowing, <code>true</code> otherwise (default).
+ */
+ @Override
+ public void setSwallowAbortedUploads(boolean swallowAbortedUploads) {
+ this.swallowAbortedUploads = swallowAbortedUploads;
+ }
+
+ /**
+ * Returns <code>true</code> if remaining request data will be read
+ * (swallowed) even the request violates a data size constraint.
+ *
+ * @return <code>true</code> if data will be swallowed (default),
+ * <code>false</code> otherwise.
+ */
+ @Override
+ public boolean getSwallowAbortedUploads() {
+ return this.swallowAbortedUploads;
+ }
+
+ /**
* Set cache TTL.
*/
public void setCacheTTL(int cacheTTL) {
@@ -6440,4 +6470,4 @@ public class StandardContext extends Con
return false;
}
-}
+}
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Tue Mar 8 17:18:16 2011
@@ -49,6 +49,13 @@ public enum ActionCode {
POST_REQUEST,
/**
+ * Hook called if swallowing request input should be disabled.
+ * Example: Cancel a large file upload.
+ *
+ */
+ DISABLE_SWALLOW_INPUT,
+
+ /**
* Callback for lazy evaluation - extract the remote host address.
*/
REQ_HOST_ATTRIBUTE,
Modified: tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Tue Mar
8 17:18:16 2011
@@ -266,6 +266,11 @@ public abstract class AbstractAjpProcess
error = true;
}
+ } else if (actionCode == ActionCode.DISABLE_SWALLOW_INPUT) {
+ // TODO: Do not swallow request input but
+ // make sure we are closing the connection
+ error = true;
+
} else if (actionCode == ActionCode.CLOSE) {
// Close
// End the processing of the current request, and stop any further
Modified:
tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Tue
Mar 8 17:18:16 2011
@@ -767,6 +767,12 @@ public abstract class AbstractHttp11Proc
response.setErrorException(e);
}
+ } else if (actionCode == ActionCode.DISABLE_SWALLOW_INPUT) {
+ // Do not swallow request input but
+ // make sure we are closing the connection
+ error = true;
+ getInputBuffer().setSwallowInput(false);
+
} else if (actionCode == ActionCode.RESET) {
// Reset response
// Note: This must be called before the response is committed
Added: tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java?rev=1079444&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java
(added)
+++ tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java
Tue Mar 8 17:18:16 2011
@@ -0,0 +1,399 @@
+/*
+ * 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.catalina.core;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+
+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 javax.servlet.http.Part;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.startup.SimpleHttpClient;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public class TestSwallowAbortedUploads extends TomcatBaseTest {
+
+ private static Log log =
LogFactory.getLog(TestSwallowAbortedUploads.class);
+
+ /**
+ * Test whether size limited uploads correctly handle connection draining.
+ */
+ public Exception doAbortedUploadTest(AbortedUploadClient client, boolean
limited,
+ boolean swallow) {
+ client.setPort(getPort());
+ Exception ex = client.doRequest(limited, swallow);
+ if (log.isDebugEnabled()) {
+ log.debug("Response line: " + client.getResponseLine());
+ log.debug("Response headers: " + client.getResponseHeaders());
+ log.debug("Response body: " + client.getResponseBody());
+ if (ex != null) {
+ log.debug("Exception in client: ", ex);
+ }
+
+ }
+ return ex;
+ }
+
+ /**
+ * Test whether aborted POST correctly handle connection draining.
+ */
+ public Exception doAbortedPOSTTest(AbortedPOSTClient client, int status,
+ boolean swallow) {
+ client.setPort(getPort());
+ Exception ex = client.doRequest(status, swallow);
+ if (log.isDebugEnabled()) {
+ log.debug("Response line: " + client.getResponseLine());
+ log.debug("Response headers: " + client.getResponseHeaders());
+ log.debug("Response body: " + client.getResponseBody());
+ if (ex != null) {
+ log.info("Exception in client: ", ex);
+ }
+
+ }
+ return ex;
+ }
+
+ public void testAbortedUploadUnlimitedSwallow() {
+ log.info("Unlimited, swallow enabled");
+ AbortedUploadClient client = new AbortedUploadClient();
+ Exception ex = doAbortedUploadTest(client, false, true);
+ assertNull("Unlimited upload with swallow enabled generates client
exception",
+ ex);
+ assertTrue("Unlimited upload with swallow enabled returns error status
code",
+ client.isResponse200());
+ client.reset();
+ }
+
+ public void testAbortedUploadUnlimitedNoSwallow() {
+ log.info("Unlimited, swallow disabled");
+ AbortedUploadClient client = new AbortedUploadClient();
+ Exception ex = doAbortedUploadTest(client, false, false);
+ assertNull("Unlimited upload with swallow disabled generates client
exception",
+ ex);
+ assertTrue("Unlimited upload with swallow disabled returns error
status code",
+ client.isResponse200());
+ client.reset();
+ }
+
+ public void testAbortedUploadLimitedSwallow() {
+ log.info("Limited, swallow enabled");
+ AbortedUploadClient client = new AbortedUploadClient();
+ Exception ex = doAbortedUploadTest(client, true, true);
+ assertNull("Limited upload with swallow enabled generates client
exception",
+ ex);
+ assertTrue("Limited upload with swallow enabled returns error status
code",
+ client.isResponse500());
+ client.reset();
+ }
+
+ public void testAbortedUploadLimitedNoSwallow() {
+ log.info("Limited, swallow disabled");
+ AbortedUploadClient client = new AbortedUploadClient();
+ Exception ex = doAbortedUploadTest(client, true, false);
+ assertTrue("Limited upload with swallow disabled does not generate
client exception",
+ ex != null && ex instanceof java.net.SocketException);
+ client.reset();
+ }
+
+ public void testAbortedPOSTOKSwallow() {
+ log.info("Aborted (OK), swallow enabled");
+ AbortedPOSTClient client = new AbortedPOSTClient();
+ Exception ex = doAbortedPOSTTest(client, HttpServletResponse.SC_OK,
true);
+ assertNull("Unlimited upload with swallow enabled generates client
exception",
+ ex);
+ assertTrue("Unlimited upload with swallow enabled returns error status
code",
+ client.isResponse200());
+ client.reset();
+ }
+
+ public void testAbortedPOSTOKNoSwallow() {
+ log.info("Aborted (OK), swallow disabled");
+ AbortedPOSTClient client = new AbortedPOSTClient();
+ Exception ex = doAbortedPOSTTest(client, HttpServletResponse.SC_OK,
false);
+ assertNull("Unlimited upload with swallow disabled generates client
exception",
+ ex);
+ assertTrue("Unlimited upload with swallow disabled returns error
status code",
+ client.isResponse200());
+ client.reset();
+ }
+
+ public void testAbortedPOST413Swallow() {
+ log.info("Aborted (413), swallow enabled");
+ AbortedPOSTClient client = new AbortedPOSTClient();
+ Exception ex = doAbortedPOSTTest(client,
HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, true);
+ assertNull("Limited upload with swallow enabled generates client
exception",
+ ex);
+ assertTrue("Limited upload with swallow enabled returns error status
code",
+ client.isResponse413());
+ client.reset();
+ }
+
+ public void testAbortedPOST413NoSwallow() {
+ log.info("Aborted (413), swallow disabled");
+ AbortedPOSTClient client = new AbortedPOSTClient();
+ Exception ex = doAbortedPOSTTest(client,
HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, false);
+ assertTrue("Limited upload with swallow disabled does not generate
client exception",
+ ex != null && ex instanceof java.net.SocketException);
+ client.reset();
+ }
+
+ @MultipartConfig
+ private static class AbortedUploadServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ PrintWriter out = resp.getWriter();
+ resp.setContentType("text/plain");
+ resp.setCharacterEncoding("UTF-8");
+ StringBuilder sb = new StringBuilder();
+ try {
+ Collection<Part> c = req.getParts();
+ if (c == null) {
+ log.debug("Count: -1");
+ sb.append("Count: -1\n");
+ } else {
+ log.debug("Count: " + c.size());
+ sb.append("Count: " + c.size() + "\n");
+ for (Part p : c) {
+ log.debug("Name: " + p.getName() + ", Size: "
+ + p.getSize());
+ sb.append("Name: " + p.getName() + ", Size: "
+ + p.getSize() + "\n");
+ }
+ }
+ } catch (IllegalStateException ex) {
+ log.debug("IllegalStateException during getParts()");
+ sb.append("IllegalStateException during getParts()\n");
+ resp.setStatus(500);
+ } catch (Throwable ex) {
+ log.error("Exception during getParts()", ex);
+ sb.append(ex);
+ resp.setStatus(500);
+ }
+ out.print(sb.toString());
+ resp.flushBuffer();
+ }
+
+ }
+
+ /**
+ * Test no connection draining when upload too large
+ */
+ private class AbortedUploadClient extends SimpleHttpClient {
+
+ private static final String URI = "/uploadAborted";
+ private static final String servletName = "uploadAborted";
+ private static final int limitSize = 100;
+ private static final int hugeSize = 200000;
+
+ private boolean init;
+ private Context context;
+
+ private synchronized void init(boolean limited, boolean swallow)
+ throws Exception {
+ if (init)
+ return;
+
+ Tomcat tomcat = getTomcatInstance();
+ context = tomcat.addContext("", TEMP_DIR);
+ Wrapper w;
+ w = Tomcat.addServlet(context, servletName,
+ new AbortedUploadServlet());
+ // Tomcat.addServlet does not respect annotations, so we have
+ // to set our own MultipartConfigElement.
+ // Choose upload file size limit.
+ if (limited) {
+ w.setMultipartConfigElement(new MultipartConfigElement("",
+ limitSize, -1, -1));
+ } else {
+ w.setMultipartConfigElement(new MultipartConfigElement(""));
+ }
+ context.addServletMapping(URI, servletName);
+ context.setSwallowAbortedUploads(swallow);
+
+ tomcat.start();
+
+ init = true;
+ }
+
+ private Exception doRequest(boolean limited, boolean swallow) {
+ char body[] = new char[hugeSize];
+ Arrays.fill(body, 'X');
+
+ try {
+ init(limited, swallow);
+
+ // Open connection
+ connect();
+
+ // Send specified request body using method
+ String[] request;
+
+ String boundary = "--simpleboundary";
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("--");
+ sb.append(boundary);
+ sb.append(CRLF);
+ sb.append("Content-Disposition: form-data; name=\"part\"");
+ sb.append(CRLF);
+ sb.append(CRLF);
+ sb.append(body);
+ sb.append(CRLF);
+ sb.append("--");
+ sb.append(boundary);
+ sb.append("--");
+ sb.append(CRLF);
+
+ // Re-encode the content so that bytes = characters
+ String content = new String(sb.toString().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 };
+
+ 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 static class AbortedPOSTServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private int status = 200;
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ resp.setCharacterEncoding("UTF-8");
+ resp.setStatus(status);
+ PrintWriter out = resp.getWriter();
+ out.print("OK");
+ resp.flushBuffer();
+ }
+
+ }
+
+ /**
+ * Test no connection draining when upload too large
+ */
+ private class AbortedPOSTClient extends SimpleHttpClient {
+
+ private static final String URI = "/uploadAborted";
+ private static final String servletName = "uploadAborted";
+ private static final int hugeSize = 200000;
+
+ private boolean init;
+ private Context context;
+
+ private synchronized void init(int status, boolean swallow)
+ throws Exception {
+ if (init)
+ return;
+
+ Tomcat tomcat = getTomcatInstance();
+ context = tomcat.addContext("", TEMP_DIR);
+ AbortedPOSTServlet servlet = new AbortedPOSTServlet();
+ servlet.setStatus(status);
+ Tomcat.addServlet(context, servletName,
+ servlet);
+ context.addServletMapping(URI, servletName);
+ context.setSwallowAbortedUploads(swallow);
+
+ tomcat.start();
+
+ init = true;
+ }
+
+ private Exception doRequest(int status, boolean swallow) {
+ char body[] = new char[hugeSize];
+ Arrays.fill(body, 'X');
+
+ try {
+ init(status, swallow);
+
+ // Open connection
+ connect();
+
+ // Send specified request body using method
+ String[] request;
+
+ String content = new String(body);
+
+ request = new String[] { "POST http://localhost:" + getPort()
+ URI + " HTTP/1.1" + CRLF
+ + "Host: localhost" + CRLF
+ + "Connection: close" + CRLF
+ + "Content-Length: " + content.length() + CRLF
+ + CRLF
+ + content + 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
+ }
+ }
+
+}
Propchange:
tomcat/trunk/test/org/apache/catalina/core/TestSwallowAbortedUploads.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/test/org/apache/catalina/startup/SimpleHttpClient.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/SimpleHttpClient.java?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/startup/SimpleHttpClient.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/startup/SimpleHttpClient.java Tue Mar
8 17:18:16 2011
@@ -48,6 +48,7 @@ public abstract class SimpleHttpClient {
public static final String OK_200 = "HTTP/1.1 200";
public static final String REDIRECT_302 = "HTTP/1.1 302";
public static final String FAIL_404 = "HTTP/1.1 404";
+ public static final String FAIL_413 = "HTTP/1.1 413";
public static final String FAIL_50X = "HTTP/1.1 50";
public static final String FAIL_500 = "HTTP/1.1 500";
public static final String FAIL_501 = "HTTP/1.1 501";
@@ -218,6 +219,10 @@ public abstract class SimpleHttpClient {
return getResponseLine().startsWith(FAIL_404);
}
+ public boolean isResponse413() {
+ return getResponseLine().startsWith(FAIL_413);
+ }
+
public boolean isResponse50x() {
return getResponseLine().startsWith(FAIL_50X);
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 8 17:18:16 2011
@@ -53,6 +53,11 @@
<bug>50855</bug>: Fix NPE on HttpServletRequest.logout() when debug
logging is enabled. (markt)
</fix>
+ <fix>
+ New context attribute "swallowAbortedUploads" allows
+ to make request data swallowing configurable for requests
+ that are too large. (rjung)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
Modified: tomcat/trunk/webapps/docs/config/context.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1079444&r1=1079443&r2=1079444&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Tue Mar 8 17:18:16 2011
@@ -569,6 +569,26 @@
default value of <code>true</code> will be used.</p>
</attribute>
+ <attribute name="swallowAbortedUploads" required="false">
+ <p>Set to false if Tomcat should <b>not</b> read any additional
+ request body data for aborted uploads and instead abort the client
+ connection. This setting is used in the following situations:
+ <ul>
+ <li>the size of the request body is larger than the
+ <code>maxPostSize</code> configured in the connector
+ </li>
+ <li>the size limit of a MultiPart upload is reached
+ </li>
+ <li>the servlet sets the response status to 413
+ (Request Entity Too Large)
+ </li>
+ </ul>
+ Not reading the additional data will free the request processing thread
+ more quickly. Unfortunately most HTTP clients will not read the
response
+ in case they can not write the full request.</p>
+ <p>The default is <code>true</code>, so additional data is being
read.</p>
+ </attribute>
+
<attribute name="swallowOutput" required="false">
<p>If the value of this flag is <code>true</code>, the bytes output to
System.out and System.err by the web application will be redirected to
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]