Skip to content

Commit afa422b

Browse files
committed
Explicitly clean up after failed multi-part upload
1 parent da6dd97 commit afa422b

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

java/org/apache/catalina/connector/LocalStrings.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ request.asyncNotSupported=A filter or servlet of the current chain does not supp
9494
request.fragmentInDispatchPath=The fragment in dispatch path [{0}] has been removed
9595
request.illegalWrap=The request wrapper must wrap the request obtained from getRequest()
9696
request.notAsync=It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
97+
request.partCleanup.failed=Unable to delete temporary file for uploaded part after multi-part processing failed
9798
request.session.failed=Failed to load session [{0}] due to [{1}]
9899

99100
requestFacade.nullRequest=The request object has been recycled and is no longer associated with this facade

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2711,8 +2711,9 @@ private void parseParts(boolean explicit) {
27112711
upload.setFileCountMax(partLimit);
27122712

27132713
parts = new ArrayList<>();
2714+
List<FileItem> items = null;
27142715
try {
2715-
List<FileItem> items = upload.parseRequest(new ServletRequestContext(this));
2716+
items = upload.parseRequest(new ServletRequestContext(this));
27162717
int maxPostSize = getConnector().getMaxPostSize();
27172718
long postSize = 0;
27182719
Charset charset = getCharset();
@@ -2765,6 +2766,24 @@ private void parseParts(boolean explicit) {
27652766
// addParameters() will set parseFailedReason
27662767
checkSwallowInput();
27672768
partsParseException = e;
2769+
} finally {
2770+
/*
2771+
* GC will delete any temporary copies of uploaded files left in the work directory but if we know that the
2772+
* upload has failed then explicitly clean up now.
2773+
*/
2774+
if (!success) {
2775+
parts.clear();
2776+
if (items != null) {
2777+
for (FileItem item : items) {
2778+
try {
2779+
item.delete();
2780+
} catch (Throwable t) {
2781+
ExceptionUtils.handleThrowable(t);
2782+
log.warn(sm.getString("request.partCleanup.failed"), t);
2783+
}
2784+
}
2785+
}
2786+
}
27682787
}
27692788
} finally {
27702789
// This might look odd but is correct. setParseFailedReason() only

webapps/docs/changelog.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@
131131
<fix>
132132
Fix a case-sensitivity issue in the trailer header allow list. (markt)
133133
</fix>
134+
<fix>
135+
Be proactive in cleaning up temporary files after a failed multi-part
136+
upload rather than waiting for GC to do it. (markt)
137+
</fix>
134138
</changelog>
135139
</subsection>
136140
<subsection name="Coyote">

0 commit comments

Comments
 (0)