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 <[email protected]>
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 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../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);

Reply via email to