Skip to content

Commit 0b9f12e

Browse files
authored
Use HttpChecksumStage for async trailer support (#4503)
* Use HttpChecksumStage for async trailer support
1 parent 54e6b96 commit 0b9f12e

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/internal/signer/DefaultAwsV4HttpSigner.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,33 @@ private static V4PayloadSigner v4PayloadSigner(
168168
return V4PayloadSigner.create();
169169
}
170170

171+
private static V4PayloadSigner v4PayloadAsyncSigner(
172+
BaseSignRequest<?, ? extends AwsCredentialsIdentity> request,
173+
V4Properties properties) {
174+
175+
boolean isPayloadSigning = request.requireProperty(PAYLOAD_SIGNING_ENABLED, true);
176+
boolean isEventStreaming = isEventStreaming(request.request());
177+
boolean isChunkEncoding = request.requireProperty(CHUNK_ENCODING_ENABLED, false);
178+
179+
if (isEventStreaming) {
180+
if (isPayloadSigning) {
181+
return getEventStreamV4PayloadSigner(
182+
properties.getCredentials(),
183+
properties.getCredentialScope(),
184+
properties.getSigningClock()
185+
);
186+
}
187+
throw new UnsupportedOperationException("Unsigned payload is not supported with event-streaming.");
188+
}
189+
190+
if (isChunkEncoding && isPayloadSigning) {
191+
throw new UnsupportedOperationException("Chunked encoding and payload signing is not supported in async client. Use"
192+
+ " sync client instead");
193+
}
194+
195+
return V4PayloadSigner.create();
196+
}
197+
171198
private static SignedRequest doSign(SignRequest<? extends AwsCredentialsIdentity> request,
172199
Checksummer checksummer,
173200
V4RequestSigner requestSigner,
@@ -250,7 +277,7 @@ public CompletableFuture<AsyncSignedRequest> signAsync(AsyncSignRequest<? extend
250277
Checksummer checksummer = checksummer(request);
251278
V4Properties v4Properties = v4Properties(request);
252279
V4RequestSigner v4RequestSigner = v4RequestSigner(request, v4Properties);
253-
V4PayloadSigner payloadSigner = v4PayloadSigner(request, v4Properties);
280+
V4PayloadSigner payloadSigner = v4PayloadAsyncSigner(request, v4Properties);
254281

255282
return doSign(request, checksummer, v4RequestSigner, payloadSigner);
256283
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/HttpChecksumStage.java

+18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static software.amazon.awssdk.core.HttpChecksumConstant.CONTENT_SHA_256_FOR_UNSIGNED_TRAILER;
2020
import static software.amazon.awssdk.core.HttpChecksumConstant.DEFAULT_ASYNC_CHUNK_SIZE;
2121
import static software.amazon.awssdk.core.HttpChecksumConstant.SIGNING_METHOD;
22+
import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.AUTH_SCHEMES;
2223
import static software.amazon.awssdk.core.internal.io.AwsChunkedEncodingInputStream.DEFAULT_CHUNK_SIZE;
2324
import static software.amazon.awssdk.core.internal.util.ChunkContentUtils.calculateChecksumTrailerLength;
2425
import static software.amazon.awssdk.core.internal.util.ChunkContentUtils.calculateStreamContentLength;
@@ -74,6 +75,12 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re
7475
return request;
7576
}
7677

78+
// If SRA is enabled, we skip flexible checksum in header
79+
// TODO(post-sra-identity-auth): we should remove this after SRA is fully released
80+
if (sraSigningEnabled(context)) {
81+
return request;
82+
}
83+
7784
if (flexibleChecksumInHeaderRequired(context, resolvedChecksumSpecs)) {
7885
addFlexibleChecksumInHeader(request, context, resolvedChecksumSpecs);
7986
return request;
@@ -128,6 +135,13 @@ private void addMd5ChecksumInHeader(SdkHttpFullRequest.Builder request) {
128135
}
129136

130137
private boolean flexibleChecksumInTrailerRequired(RequestExecutionContext context, ChecksumSpecs checksumSpecs) {
138+
139+
// If SRA is enabled and it's sync client,
140+
// skip it since flexible checksum trailer is handled in SRA signer
141+
if (sraSigningEnabled(context) && clientType == ClientType.SYNC) {
142+
return false;
143+
}
144+
131145
boolean hasRequestBody = true;
132146
if (clientType == ClientType.SYNC) {
133147
hasRequestBody = context.executionContext().interceptorContext().requestBody().isPresent();
@@ -146,6 +160,10 @@ private boolean flexibleChecksumInTrailerRequired(RequestExecutionContext contex
146160
clientType, checksumSpecs, hasRequestBody, isContentStreaming);
147161
}
148162

163+
private static boolean sraSigningEnabled(RequestExecutionContext context) {
164+
return context.executionAttributes().getAttribute(AUTH_SCHEMES) != null;
165+
}
166+
149167
/**
150168
* Adds flexible checksum to trailers.
151169
*

services/s3/src/it/java/software/amazon/awssdk/services/s3/checksum/AsyncHttpChecksumIntegrationTest.java

+10
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ void asyncValidSignedTrailerChecksumCalculatedBySdkClient() {
234234
assertThat(response).isEqualTo("Hello world");
235235
}
236236

237+
/**
238+
* If http is used, payload signing will be enforced, but it's not currently supported in async path
239+
* TODO: re-enable it once it's supported
240+
*/
241+
@Disabled("Payload signing is not supported for S3 async client")
237242
@Test
238243
public void putObject_with_bufferCreatedFromEmptyString() {
239244

@@ -256,6 +261,11 @@ public void putObject_with_bufferCreatedFromEmptyString() {
256261
assertThat(response).isEqualTo("");
257262
}
258263

264+
/**
265+
* If http is used, payload signing will be enforced, but it's not currently supported in async path
266+
* TODO: re-enable it once it's supported
267+
*/
268+
@Disabled("Payload signing is not supported for S3 async client")
259269
@Test
260270
public void putObject_with_bufferCreatedFromZeroCapacityByteBuffer() {
261271
ByteBuffer content = ByteBuffer.allocate(0);

0 commit comments

Comments
 (0)