Skip to content

Commit 46fbe9a

Browse files
committed
New context attribute "swallowAbortedUploads" allows
to make request data swallowing configurable for requests that are too large. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1079444 13f79535-47bb-0310-9956-ffa450edef68
1 parent 99f0960 commit 46fbe9a

11 files changed

Lines changed: 522 additions & 1 deletion

File tree

java/org/apache/catalina/Context.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,24 @@ public interface Context extends Container {
110110
*/
111111
public boolean getAllowCasualMultipartParsing();
112112

113+
/**
114+
* Set to <code>false</code> to disable request data swallowing
115+
* after an upload was aborted due to size constraints.
116+
*
117+
* @param swallowAbortedUploads <code>false</code> to disable
118+
* swallowing, <code>true</code> otherwise (default).
119+
*/
120+
public void setSwallowAbortedUploads(boolean swallowAbortedUploads);
121+
122+
/**
123+
* Returns <code>true</code> if remaining request data will be read
124+
* (swallowed) even the request violates a data size constraint.
125+
*
126+
* @return <code>true</code> if data will be swallowed (default),
127+
* <code>false</code> otherwise.
128+
*/
129+
public boolean getSwallowAbortedUploads();
130+
113131
/**
114132
* Return the set of initialized application event listener objects,
115133
* in the order they were specified in the web application deployment

java/org/apache/catalina/connector/Request.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,9 @@ public ServletInputStream createInputStream()
800800
*/
801801
public void finishRequest() throws IOException {
802802
// The reader and input stream don't need to be closed
803+
// TODO: Is this ever called?
804+
// If so, move input swallow disabling from
805+
// Response.finishResponse() to here
803806
}
804807

805808

@@ -2450,6 +2453,16 @@ public boolean getAvailable() {
24502453
return (inputBuffer.available() > 0);
24512454
}
24522455

2456+
/**
2457+
* Disable swallowing of remaining input if configured
2458+
*/
2459+
protected void disableSwallowInput() {
2460+
Context context = getContext();
2461+
if (context != null && !context.getSwallowAbortedUploads()) {
2462+
coyoteRequest.action(ActionCode.DISABLE_SWALLOW_INPUT, null);
2463+
}
2464+
}
2465+
24532466
public void cometClose() {
24542467
coyoteRequest.action(ActionCode.COMET_CLOSE,getEvent());
24552468
}
@@ -2620,6 +2633,7 @@ private void parseParts() {
26202633
} catch (InvalidContentTypeException e) {
26212634
partsParseException = new ServletException(e);
26222635
} catch (FileUploadBase.SizeException e) {
2636+
disableSwallowInput();
26232637
partsParseException = new IllegalStateException(e);
26242638
} catch (FileUploadException e) {
26252639
partsParseException = new IOException(e);
@@ -2845,6 +2859,7 @@ protected void parseParameters() {
28452859
context.getLogger().debug(
28462860
sm.getString("coyoteRequest.postTooLarge"));
28472861
}
2862+
disableSwallowInput();
28482863
return;
28492864
}
28502865
byte[] formData = null;
@@ -2922,6 +2937,7 @@ protected byte[] readChunkedPostBody() throws IOException {
29222937
if (connector.getMaxPostSize() > 0 &&
29232938
(body.getLength() + len) > connector.getMaxPostSize()) {
29242939
// Too much data
2940+
disableSwallowInput();
29252941
throw new IllegalArgumentException(
29262942
sm.getString("coyoteRequest.chunkedPostTooLarge"));
29272943
}

java/org/apache/catalina/connector/Response.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.apache.catalina.security.SecurityUtil;
5050
import org.apache.catalina.util.CharsetMapper;
5151
import org.apache.catalina.util.DateTool;
52+
import org.apache.coyote.ActionCode;
5253
import org.apache.tomcat.util.buf.CharChunk;
5354
import org.apache.tomcat.util.buf.UEncoder;
5455
import org.apache.tomcat.util.http.FastHttpDateFormat;
@@ -497,6 +498,15 @@ public ServletOutputStream createOutputStream()
497498
*/
498499
public void finishResponse()
499500
throws IOException {
501+
// Optionally disable swallowing of additional request data.
502+
// TODO: Should be in Request.finishRequest(), but that method
503+
// seems to get called never.
504+
Context context = getContext();
505+
if (context != null
506+
&& getStatus() == HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE
507+
&& !context.getSwallowAbortedUploads()) {
508+
coyoteResponse.action(ActionCode.DISABLE_SWALLOW_INPUT, null);
509+
}
500510
// Writing leftover bytes
501511
outputBuffer.close();
502512
}

java/org/apache/catalina/core/StandardContext.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ public StandardContext() {
196196
*/
197197
protected boolean allowCasualMultipartParsing = false;
198198

199+
/**
200+
* Control whether remaining request data will be read
201+
* (swallowed) even if the request violates a data size constraint.
202+
*/
203+
public boolean swallowAbortedUploads = true;
204+
199205
/**
200206
* The alternate deployment descriptor name.
201207
*/
@@ -1065,6 +1071,30 @@ public boolean getAllowCasualMultipartParsing() {
10651071
return this.allowCasualMultipartParsing;
10661072
}
10671073

1074+
/**
1075+
* Set to <code>false</code> to disable request data swallowing
1076+
* after an upload was aborted due to size constraints.
1077+
*
1078+
* @param swallowAbortedUploads <code>false</code> to disable
1079+
* swallowing, <code>true</code> otherwise (default).
1080+
*/
1081+
@Override
1082+
public void setSwallowAbortedUploads(boolean swallowAbortedUploads) {
1083+
this.swallowAbortedUploads = swallowAbortedUploads;
1084+
}
1085+
1086+
/**
1087+
* Returns <code>true</code> if remaining request data will be read
1088+
* (swallowed) even the request violates a data size constraint.
1089+
*
1090+
* @return <code>true</code> if data will be swallowed (default),
1091+
* <code>false</code> otherwise.
1092+
*/
1093+
@Override
1094+
public boolean getSwallowAbortedUploads() {
1095+
return this.swallowAbortedUploads;
1096+
}
1097+
10681098
/**
10691099
* Set cache TTL.
10701100
*/
@@ -6440,4 +6470,4 @@ public boolean isStatisticsProvider() {
64406470
return false;
64416471
}
64426472

6443-
}
6473+
}

java/org/apache/coyote/ActionCode.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ public enum ActionCode {
4848
*/
4949
POST_REQUEST,
5050

51+
/**
52+
* Hook called if swallowing request input should be disabled.
53+
* Example: Cancel a large file upload.
54+
*
55+
*/
56+
DISABLE_SWALLOW_INPUT,
57+
5158
/**
5259
* Callback for lazy evaluation - extract the remote host address.
5360
*/

java/org/apache/coyote/ajp/AbstractAjpProcessor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ public final void action(ActionCode actionCode, Object param) {
266266
error = true;
267267
}
268268

269+
} else if (actionCode == ActionCode.DISABLE_SWALLOW_INPUT) {
270+
// TODO: Do not swallow request input but
271+
// make sure we are closing the connection
272+
error = true;
273+
269274
} else if (actionCode == ActionCode.CLOSE) {
270275
// Close
271276
// End the processing of the current request, and stop any further

java/org/apache/coyote/http11/AbstractHttp11Processor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,12 @@ public final void action(ActionCode actionCode, Object param) {
767767
response.setErrorException(e);
768768
}
769769

770+
} else if (actionCode == ActionCode.DISABLE_SWALLOW_INPUT) {
771+
// Do not swallow request input but
772+
// make sure we are closing the connection
773+
error = true;
774+
getInputBuffer().setSwallowInput(false);
775+
770776
} else if (actionCode == ActionCode.RESET) {
771777
// Reset response
772778
// Note: This must be called before the response is committed

0 commit comments

Comments
 (0)