Federico Mariani created CAMEL-24593:
----------------------------------------
Summary: camel-platform-http-starter - accepted multipart uploads
are copied to the servlet temp directory and never deleted
Key: CAMEL-24593
URL: https://issues.apache.org/jira/browse/CAMEL-24593
Project: Camel
Issue Type: Bug
Components: camel-platform-http, camel-spring-boot-starters
Reporter: Federico Mariani
Assignee: Federico Mariani
Fix For: 4.23.0
{{SpringBootPlatformHttpBinding.populateAttachments()}} copies every accepted
multipart upload into the servlet temp directory and never removes the copy:
{code:java}
File tmpFolder = (File)
request.getServletContext().getAttribute(ServletContext.TEMPDIR);
...
Path uploadedTmpFile = Paths.get(tmpFolder.getPath(),
UUID.randomUUID().toString());
multipartFile.transferTo(uploadedTmpFile);
AttachmentMessage am = new DefaultAttachmentMessage(message);
File uploadedFile = uploadedTmpFile.toFile();
am.addAttachment(name, new DataHandler(new CamelFileDataSource(uploadedFile,
name)));
...
message.setBody(uploadedTmpFile);
{code}
(components-starter/camel-platform-http-starter:
SpringBootPlatformHttpBinding.java:101-133)
{{transferTo}} moves the container's part file, so the container's own
end-of-request cleanup no longer finds it, and there is no delete,
{{deleteOnExit}} or exchange completion hook anywhere in the starter. Verified
with a route doing {{from("platform-http:/upload")}}: after the response is
returned, the file under
{{<java.io.tmpdir>/tomcat.<n>/work/Tomcat/localhost/ROOT/<uuid>}} is still on
disk. Every upload the application ever accepts therefore accumulates for the
life of the process, including uploads the route only inspected and discarded.
The other HTTP bindings do not leak:
* camel-http-common {{DefaultHttpBinding}} reads the part through the
container-managed file, which the container deletes at the end of the request.
* camel-platform-http-vertx has {{deleteUploadedFilesOnEnd}}, defaulting to
{{true}}.
The copy was introduced in CAMEL-21461 so that the body can be a {{Path}} and
the attachment can be read after the servlet request has completed, which is a
fair reason to own the file - but owning it means removing it.
*Proposal*
* Register an {{onCompletion}} synchronization on the exchange (via
{{ExchangeExtension.addOnCompletion}}) that deletes the temp file once routing
is done. The attachment {{DataSource}} and the {{Path}} body both point at the
file until then, so deletion cannot happen earlier.
* Mirror the Vert.x option with a component/endpoint setting such as
{{deleteUploadedFilesOnEnd}} defaulting to {{true}}, so a route that
intentionally keeps the file can opt out.
* Add a test that uploads a file, captures the path the route saw, and asserts
the file is gone once the exchange completed, plus the opt-out case.
Since routing a {{Path}} body to a file producer copies the content, existing
routes are unaffected; only a route that stores the temp path and reads it
after the exchange has finished would need the opt-out, and that should go in
the upgrade guide.
----
_This issue was drafted by Claude Code on behalf of Federico Mariani._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)