Skip to content

Commit 4f59426

Browse files
authored
Copy SSE-C parameters when performing multipart copy (#4219)
This commit fixes a bug where the SSE-C parameters are not copied to the CompleteMultipartUpload request when transforming to a multipart copy.
1 parent 28d14d2 commit 4f59426

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "bugfix",
3+
"category": "S3 Transfer Manager",
4+
"contributor": "",
5+
"description": "Fix a bug where the SSE-C parameters are not copied to the CompleteMultipartUpload request when transforming to a multipart copy."
6+
}

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/CopyObjectHelper.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ private CompletableFuture<CompleteMultipartUploadResponse> completeMultipartUplo
189189
.multipartUpload(CompletedMultipartUpload.builder()
190190
.parts(parts)
191191
.build())
192+
.sseCustomerAlgorithm(copyObjectRequest.sseCustomerAlgorithm())
193+
.sseCustomerKey(copyObjectRequest.sseCustomerKey())
194+
.sseCustomerKeyMD5(copyObjectRequest.sseCustomerKeyMD5())
192195
.build();
193196

194197
return s3AsyncClient.completeMultipartUpload(completeMultipartUploadRequest);

services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/CopyObjectHelperTest.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.mockito.Mockito.when;
2525

2626
import java.util.List;
27+
import java.util.Random;
2728
import java.util.concurrent.CompletableFuture;
2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.Test;
@@ -47,7 +48,9 @@
4748
import software.amazon.awssdk.services.s3.model.NoSuchBucketException;
4849
import software.amazon.awssdk.services.s3.model.UploadPartCopyRequest;
4950
import software.amazon.awssdk.services.s3.model.UploadPartCopyResponse;
51+
import software.amazon.awssdk.utils.BinaryUtils;
5052
import software.amazon.awssdk.utils.CompletableFutureUtils;
53+
import software.amazon.awssdk.utils.Md5Utils;
5154

5255
class CopyObjectHelperTest {
5356

@@ -56,13 +59,15 @@ class CopyObjectHelperTest {
5659
private static final String DESTINATION_BUCKET = "destination";
5760
private static final String DESTINATION_KEY = "destinationKey";
5861
private static final String MULTIPART_ID = "multipartId";
62+
63+
private static final Long PART_SIZE_BYTES = 1024L;
5964
private S3AsyncClient s3AsyncClient;
6065
private CopyObjectHelper copyHelper;
6166

6267
@BeforeEach
6368
public void setUp() {
6469
s3AsyncClient = Mockito.mock(S3AsyncClient.class);
65-
copyHelper = new CopyObjectHelper(s3AsyncClient, 1024L);
70+
copyHelper = new CopyObjectHelper(s3AsyncClient, PART_SIZE_BYTES);
6671
}
6772

6873
@Test
@@ -256,6 +261,35 @@ void multiPartCopy_contentSizeExceeds10000Parts_shouldAdjustPartSize() {
256261
}
257262
}
258263

264+
@Test
265+
public void multiPartCopy_sseCHeadersSetInOriginalRequest_includedInCompleteMultipart() {
266+
String customerAlgorithm = "algorithm";
267+
String customerKey = "key";
268+
String customerKeyMd5 = "keyMd5";
269+
270+
CopyObjectRequest copyRequest = copyObjectRequest().copy(r -> r.sseCustomerAlgorithm(customerAlgorithm)
271+
.sseCustomerKey(customerKey)
272+
.sseCustomerKeyMD5(customerKeyMd5));
273+
274+
stubSuccessfulHeadObjectCall(2 * PART_SIZE_BYTES);
275+
stubSuccessfulCreateMulipartCall();
276+
stubSuccessfulUploadPartCopyCalls();
277+
stubSuccessfulCompleteMultipartCall();
278+
279+
copyHelper.copyObject(copyRequest).join();
280+
281+
ArgumentCaptor<CompleteMultipartUploadRequest> completeMultipartCaptor =
282+
ArgumentCaptor.forClass(CompleteMultipartUploadRequest.class);
283+
284+
verify(s3AsyncClient).completeMultipartUpload(completeMultipartCaptor.capture());
285+
286+
CompleteMultipartUploadRequest completeRequest = completeMultipartCaptor.getValue();
287+
288+
assertThat(completeRequest.sseCustomerAlgorithm()).isEqualTo(customerAlgorithm);
289+
assertThat(completeRequest.sseCustomerKey()).isEqualTo(customerKey);
290+
assertThat(completeRequest.sseCustomerKeyMD5()).isEqualTo(customerKeyMd5);
291+
}
292+
259293
@Test
260294
void copy_cancelResponseFuture_shouldPropagate() {
261295
CopyObjectRequest copyObjectRequest = copyObjectRequest();

0 commit comments

Comments
 (0)