[backport camel-spring-boot-4.18.x] CAMEL-24593: platform-http-starter - delete multipart uploads when the exchange is done - #1965
Merged
Croway merged 1 commit intoSep 9, 2026
Conversation
…e exchange is done
SpringBootPlatformHttpBinding.populateAttachments() copies every accepted
multipart upload into the servlet temp directory and uses that copy as the
attachment DataSource and, for a single upload, as the Path message body and
the CamelFilePath header. MultipartFile.transferTo() moves the container's part
file, so the container's own end-of-request cleanup no longer finds it, and
nothing in the starter deleted the copy either: every upload the application
accepted stayed on disk for the life of the process.
The copy was introduced in CAMEL-21461 so the body can be a Path and the
attachment stays readable after the servlet request completed, which is a good
reason to own the file - but owning it means removing it. The other HTTP
bindings do not leak: camel-http-common reads the part through the container
managed file, which the container deletes, and camel-platform-http-vertx has
deleteUploadedFilesOnEnd defaulting to true.
The binding now collects the temp files it created for a request and registers
a Synchronization through ExchangeExtension.addOnCompletion that deletes them
when the exchange is done being routed. The DataSource and the Path body point
at the files until then, so they cannot be deleted any earlier; the consumer
writes the HTTP response before doneUoW, so the response is already out.
The opt-out mirrors the Vert.x option. Endpoint options are defined in upstream
camel-platform-http and cannot be extended from here, so the option is a new
starter owned configuration class, SpringBootPlatformHttpServerProperties,
next to the existing camel.component.platform-http.server.undertow.accesslog
properties:
camel.component.platform-http.server.delete-uploaded-files-on-end=false
It is wired from the auto configuration through the engine and the consumer
onto the binding, and defaults to true. Existing public constructors are
unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit cf374a9)
Croway
force-pushed
the
backport/1934-to-camel-spring-boot-4.18.x
branch
from
September 9, 2026 15:06
cbd32a3 to
13a5812
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cherry-pick of #1934 onto
camel-spring-boot-4.18.x.Original PR: #1934 — platform-http-starter - delete multipart uploads when the exchange is done
JIRA: CAMEL-24593
What it fixes
SpringBootPlatformHttpBinding.populateAttachments()copies every accepted multipart upload out ofthe servlet container into the servlet temp directory, and uses that copy as the attachment
DataSourceand, for a single upload, as thePathmessage body and theCamelFilePathheader.Because
MultipartFile.transferTo()moves the container's part file, the container's ownend-of-request cleanup can no longer find it, and nothing in the starter deleted the copy either —
every accepted upload stayed on disk for the life of the process.
The copy was introduced in CAMEL-21461 so the body can be a
Pathand the attachment stays readableafter the servlet request has completed, which is a good reason to own the file — but owning it means
being responsible for removing it too. The other HTTP bindings don't have this problem:
camel-http-commonreads the part through the container-managed file (which the container deletes),and
camel-platform-http-vertxalready defaultsdeleteUploadedFilesOnEndtotrue.The binding now tracks the temp files it created for a request and registers a
Synchronizationvia
ExchangeExtension.addOnCompletionthat deletes them once the exchange is done being routed —after the HTTP response has already been written, so nothing currently reading the files is
affected. A new opt-out property,
camel.component.platform-http.server.delete-uploaded-files-on-end(default
true), mirrors the Vert.x option, for routes that hand the file to something that reads itafter the exchange completes.
This is a resource-leak fix only: no default-behavior change to existing routes, and existing public
constructors are unchanged.
Depends on CAMEL-24496
This cherry-picks onto
camel-spring-boot-4.18.xon top of CAMEL-24496 (#1952), merged into thisbranch just before this PR was opened. It did not apply fully cleanly — four conflicts, all
because this branch's
SpringBootPlatformHttpAutoConfiguration/SpringBootPlatformHttpEnginecarrypre-existing 4.18.x-only code (a more elaborate executor-selection strategy for virtual threads /
Spring Security executors, and
env.getProperty("server.port", ...)instead of aServerPropertiesbean) that main no longer has. I resolved these by keeping this branch's existing structure and
wiring the new
SpringBootPlatformHttpServerProperties/deleteUploadedFilesOnEndplumbing through it,rather than pulling in main's unrelated refactors:
SpringBootPlatformHttpAutoConfiguration.java— kept this branch's@Configuration/executor-selectionlogic, added
SpringBootPlatformHttpServerPropertiesto@EnableConfigurationPropertiesand threadedit into
springBootPlatformHttpEngine(...).SpringBootPlatformHttpEngine.java— kept this branch's mutableexecutorfield / constructorchaining (no
executor == nullbranch increateConsumer, which is a pre-existing main-onlyrefactor unrelated to this fix), added the
deleteUploadedFilesOnEndfield, the new 3-argconstructor, and wired
setDeleteUploadedFilesOnEndonto the created consumer.components-starter/camel-platform-http-starter/src/main/docs/platform-http.adoc— this PR wasoriginally opened before CAMEL-24577 ([backport camel-spring-boot-4.18.x] CAMEL-24577: platform-http path variables follow the path Spring matched #1958, "platform-http path variables follow the path Spring
matched") was merged into
camel-spring-boot-4.18.x, so the file conflicted twice: first againstCAMEL-24496 (resolved by taking only the new "File uploads" section), and again after rebasing onto
the now-merged CAMEL-24577, whose "Path variables" section landed in the same spot. Both sections
now coexist: "Path variables" (CAMEL-24577) followed by "File uploads" (this PR).
docs/spring-boot/modules/ROOT/pages/starters/platform-http.adoc— modify/delete conflict: thisaggregated docs page no longer exists on this branch (removed as part of an earlier, unrelated docs
restructuring), so I kept it deleted rather than resurrecting it.
SpringBootPlatformHttpBinding.javaandSpringBootPlatformHttpConsumer.javaauto-merged cleanlyagainst CAMEL-24496 and, after the later rebase, against CAMEL-24577 as well — they coexist correctly
with CAMEL-24496's filename-whitelist checks (which run earlier in
populateAttachments(), beforethis fix's cleanup registration) and with CAMEL-24577's path-variable extraction (
getMatchedPath()),which lives in an entirely separate part of the class.
I also updated the two new test classes'
CamelSpringBootTestimport fromorg.apache.camel.test.spring.junit6(main) toorg.apache.camel.test.spring.junit5(this branch isSpring Boot 3 / JUnit 5), matching every neighboring test in this module.
Verification on this branch
reviewed against both sides of the diff. Re-verified after rebasing onto the merged CAMEL-24577.
./mvnw -DskipTests -Dfastinstall install -pl components-starter/camel-platform-http-starter -am(parent/
camel-versiontemporarily repointed to the released4.18.4for local resolution, revertedafterwards) — succeeded.
../../mvnw verifyincomponents-starter/camel-platform-http-starter: 124 tests run, 1failure. The failure is
SpringBootPlatformHttpRequestTimeoutTest.testGetAsync, a pre-existing,unrelated flake on this branch (retried 3 times by surefire, failed each time) — not caused by this
change. Both this fix's tests (
SpringBootPlatformHttpUploadCleanupTest,SpringBootPlatformHttpUploadCleanupDisabledTest) and CAMEL-24577's path-variable tests(
SpringBootPlatformHttpPathVariableTest,SpringBootPlatformHttpBindingPathVariableTest) passed.git diff origin/camel-spring-boot-4.18.x --statonly shows the 10 files touched by thecherry-picked commit itself (temporary pom.xml/catalog build artifacts reverted).
Claude Code on behalf of Federico Mariani