diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java index aaf1c27428d9..92f617bbd5f6 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java @@ -19,6 +19,7 @@ import static software.amazon.awssdk.core.HttpChecksumConstant.CONTENT_SHA_256_FOR_UNSIGNED_TRAILER; import static software.amazon.awssdk.core.HttpChecksumConstant.DEFAULT_ASYNC_CHUNK_SIZE; import static software.amazon.awssdk.core.HttpChecksumConstant.SIGNING_METHOD; +import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.AUTH_SCHEMES; import static software.amazon.awssdk.core.internal.io.AwsChunkedEncodingInputStream.DEFAULT_CHUNK_SIZE; import static software.amazon.awssdk.core.internal.util.ChunkContentUtils.calculateChecksumTrailerLength; import static software.amazon.awssdk.core.internal.util.ChunkContentUtils.calculateStreamContentLength; @@ -67,6 +68,11 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re return request; } + // Check for SRA code-path + if (context.executionAttributes().getAttribute(AUTH_SCHEMES) != null) { + return request; + } + ChecksumSpecs resolvedChecksumSpecs = getResolvedChecksumSpecs(context.executionAttributes()); if (flexibleChecksumInTrailerRequired(context, resolvedChecksumSpecs)) { diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStageTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStageTest.java index 3e7f97cbe0fc..f01a1daadfc0 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStageTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStageTest.java @@ -19,10 +19,12 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static software.amazon.awssdk.core.HttpChecksumConstant.HEADER_FOR_TRAILER_REFERENCE; import static software.amazon.awssdk.core.HttpChecksumConstant.SIGNING_METHOD; +import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.AUTH_SCHEMES; import static software.amazon.awssdk.core.internal.signer.SigningMethod.UNSIGNED_PAYLOAD; import static software.amazon.awssdk.http.Header.CONTENT_LENGTH; import static software.amazon.awssdk.http.Header.CONTENT_MD5; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @@ -87,14 +89,12 @@ public void async_nonStreaming_md5Required_addsMd5Checksum_doesNotAddFlexibleChe } @Test - public void async_streaming_md5Required_throws_IllegalArgumentException() throws Exception { + public void async_streaming_md5Required_throws_IllegalArgumentException() { SdkHttpFullRequest.Builder requestBuilder = createHttpRequestBuilder(); boolean isAsyncStreaming = true; RequestExecutionContext ctx = md5RequiredRequestContext(isAsyncStreaming); - Exception exception = assertThrows(IllegalArgumentException.class, () -> { - asyncStage.execute(requestBuilder, ctx); - }); + Exception exception = assertThrows(IllegalArgumentException.class, () -> asyncStage.execute(requestBuilder, ctx)); assertThat(exception.getMessage()).isEqualTo("This operation requires a content-MD5 checksum, but one cannot be " + "calculated for non-blocking content."); @@ -172,6 +172,22 @@ public void async_flexibleChecksumInHeaderRequired_addsFlexibleChecksumInHeader_ assertThat(requestBuilder.firstMatchingHeader(CONTENT_MD5)).isEmpty(); } + @Test + public void execute_whenSraCodepath_doesNotAddChecksumOrChunkEncode() throws Exception { + SdkHttpFullRequest.Builder requestBuilder = createHttpRequestBuilder(); + RequestExecutionContext ctx = sraRequestContext(); + + asyncStage.execute(requestBuilder, ctx); + + assertThat(requestBuilder.firstMatchingHeader(CHECKSUM_SPECS_HEADER)).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader(HEADER_FOR_TRAILER_REFERENCE)).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader("Content-encoding")).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader("x-amz-content-sha256")).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader("x-amz-decoded-content-length")).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader(CONTENT_LENGTH)).isEmpty(); + assertThat(requestBuilder.firstMatchingHeader(CONTENT_MD5)).isEmpty(); + } + private SdkHttpFullRequest.Builder createHttpRequestBuilder() { return SdkHttpFullRequest.builder().contentStreamProvider(REQUEST_BODY.contentStreamProvider()); } @@ -245,6 +261,21 @@ private RequestExecutionContext asyncFlexibleChecksumRequiredRequestContext(bool return createRequestExecutionContext(executionAttributes, interceptorContextBuilder.build(), isStreaming); } + private RequestExecutionContext sraRequestContext() { + ExecutionAttributes executionAttributes = + ExecutionAttributes.builder() + .put(AUTH_SCHEMES, Collections.emptyMap()) + .build(); + + InterceptorContext.Builder interceptorContextBuilder = + InterceptorContext.builder() + .request(NoopTestRequest.builder().build()) + .httpRequest(ValidSdkObjects.sdkHttpFullRequest().build()) + .requestBody(REQUEST_BODY); + + return createRequestExecutionContext(executionAttributes, interceptorContextBuilder.build(), false); + } + private RequestExecutionContext createRequestExecutionContext(ExecutionAttributes executionAttributes, InterceptorContext interceptorContext, boolean isAsyncStreaming) {