You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/07/17 15:24:22 UTC
(camel) 01/06: CAMEL-24156: camel-aws2-s3 - Fix resource leaks and multipart bucket mismatch
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch fix/CAMEL-24156
in repository https://gitbox.apache.org/repos/asf/camel.git
commit a7c28e995666430777188d36e9fa6e42307caca4
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Jul 17 17:17:42 2026 +0200
CAMEL-24156: camel-aws2-s3 - Fix resource leaks and multipart bucket mismatch
- Close ResponseInputStream when ignoreBody=true to prevent connection pool
exhaustion (both POJO and non-POJO getObject paths)
- Use dynamic bucket name (from header/expression) in all multipart upload
API calls instead of raw configured bucket
- Close FileInputStream on the contentLength < partSize shortcut path where
doPutObject uses RequestBody.fromFile() and the stream is never consumed
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
.../camel/component/aws2/s3/AWS2S3Producer.java | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
index 728cc5d946ef..c4d8267b72ad 100644
--- a/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
+++ b/components/camel-aws/camel-aws2-s3/src/main/java/org/apache/camel/component/aws2/s3/AWS2S3Producer.java
@@ -212,7 +212,11 @@ public class AWS2S3Producer extends DefaultProducer {
if (contentLength == 0 || contentLength < partSize) {
// optimize to do a single op if content length is known and < part size
LOG.debug("Payload size < partSize ({} > {}). Uploading payload in single operation", contentLength, partSize);
- doPutObject(exchange, objectMetadata, filePayload, inputStream, contentLength);
+ try {
+ doPutObject(exchange, objectMetadata, filePayload, inputStream, contentLength);
+ } finally {
+ IOHelper.close(inputStream);
+ }
return;
}
@@ -222,7 +226,7 @@ public class AWS2S3Producer extends DefaultProducer {
final String keyName = AWS2S3Utils.determineKey(exchange, getConfiguration());
final String bucketName = AWS2S3Utils.determineBucketName(exchange, getConfiguration());
CreateMultipartUploadRequest.Builder createMultipartUploadRequest
- = CreateMultipartUploadRequest.builder().bucket(getConfiguration().getBucketName()).key(keyName);
+ = CreateMultipartUploadRequest.builder().bucket(bucketName).key(keyName);
String storageClass = AWS2S3Utils.determineStorageClass(exchange, getConfiguration());
if (ObjectHelper.isNotEmpty(storageClass)) {
@@ -277,7 +281,7 @@ public class AWS2S3Producer extends DefaultProducer {
for (int part = 1; position < contentLength; part++) {
partSize = Math.min(partSize, contentLength - position);
- UploadPartRequest uploadRequest = UploadPartRequest.builder().bucket(getConfiguration().getBucketName())
+ UploadPartRequest uploadRequest = UploadPartRequest.builder().bucket(bucketName)
.key(keyName).uploadId(initResponse.uploadId())
.partNumber(part).build();
@@ -293,7 +297,7 @@ public class AWS2S3Producer extends DefaultProducer {
LOG.debug("Completing multi-part upload for {}", keyName);
CompletedMultipartUpload completeMultipartUpload = CompletedMultipartUpload.builder().parts(completedParts).build();
CompleteMultipartUploadRequest.Builder compRequestBuilder = CompleteMultipartUploadRequest.builder()
- .multipartUpload(completeMultipartUpload).bucket(getConfiguration().getBucketName()).key(keyName)
+ .multipartUpload(completeMultipartUpload).bucket(bucketName).key(keyName)
.uploadId(initResponse.uploadId());
if (getConfiguration().isConditionalWritesEnabled()) {
compRequestBuilder.ifNoneMatch("*");
@@ -302,7 +306,7 @@ public class AWS2S3Producer extends DefaultProducer {
} catch (Exception e) {
getEndpoint().getS3Client()
- .abortMultipartUpload(AbortMultipartUploadRequest.builder().bucket(getConfiguration().getBucketName())
+ .abortMultipartUpload(AbortMultipartUploadRequest.builder().bucket(bucketName)
.key(keyName).uploadId(initResponse.uploadId()).build());
throw e;
} finally {
@@ -614,7 +618,9 @@ public class AWS2S3Producer extends DefaultProducer {
ResponseInputStream<GetObjectResponse> res
= s3Client.getObject(req, ResponseTransformer.toInputStream());
Message message = getMessageForResponse(exchange);
- if (!getConfiguration().isIgnoreBody()) {
+ if (getConfiguration().isIgnoreBody()) {
+ IOHelper.close(res);
+ } else {
message.setBody(res);
}
populateMetadata(res, message);
@@ -645,7 +651,9 @@ public class AWS2S3Producer extends DefaultProducer {
ResponseInputStream<GetObjectResponse> res = s3Client.getObject(req.build(), ResponseTransformer.toInputStream());
Message message = getMessageForResponse(exchange);
- if (!getConfiguration().isIgnoreBody()) {
+ if (getConfiguration().isIgnoreBody()) {
+ IOHelper.close(res);
+ } else {
message.setBody(res);
}
populateMetadata(res, message);