@@ -77,8 +77,9 @@ public HttpChecksumStage(ClientType clientType) {
77
77
public SdkHttpFullRequest .Builder execute (SdkHttpFullRequest .Builder request , RequestExecutionContext context )
78
78
throws Exception {
79
79
80
+ ensurePayloadChecksumStorePresent (context .executionAttributes ());
81
+
80
82
if (sraSigningEnabled (context )) {
81
- ensurePayloadChecksumStorePresent (context .executionAttributes ());
82
83
return sraChecksum (request , context );
83
84
}
84
85
@@ -87,9 +88,10 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re
87
88
88
89
private SdkHttpFullRequest .Builder legacyChecksum (SdkHttpFullRequest .Builder request , RequestExecutionContext context ) {
89
90
ChecksumSpecs resolvedChecksumSpecs = getResolvedChecksumSpecs (context .executionAttributes ());
91
+ PayloadChecksumStore checksumStore = getPayloadChecksumStore (context .executionAttributes ());
90
92
91
93
if (md5ChecksumRequired (request , context )) {
92
- addMd5ChecksumInHeader (request );
94
+ addMd5ChecksumInHeader (request , checksumStore );
93
95
return request ;
94
96
}
95
97
@@ -99,7 +101,7 @@ private SdkHttpFullRequest.Builder legacyChecksum(SdkHttpFullRequest.Builder req
99
101
}
100
102
101
103
if (flexibleChecksumInHeaderRequired (context , resolvedChecksumSpecs )) {
102
- addFlexibleChecksumInHeader (request , context , resolvedChecksumSpecs );
104
+ addFlexibleChecksumInHeader (request , context , resolvedChecksumSpecs , checksumStore );
103
105
return request ;
104
106
}
105
107
@@ -174,10 +176,14 @@ private boolean md5ChecksumRequired(SdkHttpFullRequest.Builder request, RequestE
174
176
* request body to use that buffered content. We obviously don't want to do that for giant streams, so we haven't opted to do
175
177
* that yet.
176
178
*/
177
- private void addMd5ChecksumInHeader (SdkHttpFullRequest .Builder request ) {
179
+ private void addMd5ChecksumInHeader (SdkHttpFullRequest .Builder request , PayloadChecksumStore checksumStore ) {
178
180
try {
179
- String payloadMd5 = Md5Utils .md5AsBase64 (request .contentStreamProvider ().newStream ());
180
- request .putHeader (Header .CONTENT_MD5 , payloadMd5 );
181
+ byte [] payloadMd5 = checksumStore .getChecksumValue (DefaultChecksumAlgorithm .MD5 );
182
+ if (payloadMd5 == null ) {
183
+ payloadMd5 = Md5Utils .computeMD5Hash (request .contentStreamProvider ().newStream ());
184
+ checksumStore .putChecksumValue (DefaultChecksumAlgorithm .MD5 , payloadMd5 );
185
+ }
186
+ request .putHeader (Header .CONTENT_MD5 , BinaryUtils .toBase64 (payloadMd5 ));
181
187
} catch (IOException e ) {
182
188
throw new UncheckedIOException (e );
183
189
}
@@ -237,7 +243,11 @@ private void addFlexibleChecksumInTrailer(SdkHttpFullRequest.Builder request, Re
237
243
int chunkSize = 0 ;
238
244
239
245
if (clientType == ClientType .SYNC ) {
240
- request .contentStreamProvider (new ChecksumCalculatingStreamProvider (request .contentStreamProvider (), checksumSpecs ));
246
+ request .contentStreamProvider (
247
+ new ChecksumCalculatingStreamProvider (request .contentStreamProvider (),
248
+ checksumSpecs ,
249
+ getPayloadChecksumStore (context .executionAttributes ())
250
+ ));
241
251
originalContentLength =
242
252
context .executionContext ().interceptorContext ().requestBody ().get ().optionalContentLength ().orElse (0L );
243
253
chunkSize = DEFAULT_CHUNK_SIZE ;
@@ -311,13 +321,19 @@ private boolean flexibleChecksumInHeaderRequired(RequestExecutionContext context
311
321
* that yet.
312
322
*/
313
323
private void addFlexibleChecksumInHeader (SdkHttpFullRequest .Builder request , RequestExecutionContext context ,
314
- ChecksumSpecs checksumSpecs ) {
324
+ ChecksumSpecs checksumSpecs , PayloadChecksumStore checksumStore ) {
315
325
try {
316
326
Algorithm legacyAlgorithm = checksumSpecs .algorithm ();
317
- String payloadChecksum = BinaryUtils .toBase64 (HttpChecksumUtils .computeChecksum (
318
- context .executionContext ().interceptorContext ().requestBody ().get ().contentStreamProvider ().newStream (),
319
- legacyAlgorithm ));
320
- request .putHeader (checksumSpecs .headerName (), payloadChecksum );
327
+ ChecksumAlgorithm newAlgorithm = HttpChecksumUtils .toNewChecksumAlgorithm (legacyAlgorithm );
328
+ byte [] payloadChecksum = checksumStore .getChecksumValue (newAlgorithm );
329
+ if (payloadChecksum == null ) {
330
+ payloadChecksum = HttpChecksumUtils .computeChecksum (
331
+ context .executionContext ().interceptorContext ().requestBody ().get ().contentStreamProvider ().newStream (),
332
+ legacyAlgorithm );
333
+ checksumStore .putChecksumValue (newAlgorithm , payloadChecksum );
334
+ }
335
+ String headerValue = BinaryUtils .toBase64 (payloadChecksum );
336
+ request .putHeader (checksumSpecs .headerName (), headerValue );
321
337
} catch (IOException e ) {
322
338
throw new UncheckedIOException (e );
323
339
}
@@ -339,24 +355,31 @@ static final class ChecksumCalculatingStreamProvider implements ContentStreamPro
339
355
private final ContentStreamProvider underlyingInputStreamProvider ;
340
356
private final String checksumHeaderForTrailer ;
341
357
private final ChecksumSpecs checksumSpecs ;
358
+ private final PayloadChecksumStore checksumStore ;
342
359
private InputStream currentStream ;
360
+ private final ChecksumAlgorithm checksumAlgorithm ;
343
361
private software .amazon .awssdk .core .checksums .SdkChecksum sdkChecksum ;
344
362
345
363
ChecksumCalculatingStreamProvider (ContentStreamProvider underlyingInputStreamProvider ,
346
- ChecksumSpecs checksumSpecs ) {
364
+ ChecksumSpecs checksumSpecs ,
365
+ PayloadChecksumStore checksumStore ) {
347
366
this .underlyingInputStreamProvider = underlyingInputStreamProvider ;
348
367
this .sdkChecksum = software .amazon .awssdk .core .checksums .SdkChecksum .forAlgorithm (
349
368
checksumSpecs .algorithm ());
369
+ this .checksumAlgorithm = HttpChecksumUtils .toNewChecksumAlgorithm (checksumSpecs .algorithm ());
350
370
this .checksumHeaderForTrailer = checksumSpecs .headerName ();
351
371
this .checksumSpecs = checksumSpecs ;
372
+ this .checksumStore = checksumStore ;
352
373
}
353
374
354
375
@ Override
355
376
public InputStream newStream () {
356
377
closeCurrentStream ();
357
378
currentStream = AwsUnsignedChunkedEncodingInputStream .builder ()
358
379
.inputStream (underlyingInputStreamProvider .newStream ())
380
+ .checksumAlgorithm (checksumAlgorithm )
359
381
.sdkChecksum (sdkChecksum )
382
+ .checksumStore (checksumStore )
360
383
.checksumHeaderForTrailer (checksumHeaderForTrailer )
361
384
.build ();
362
385
return currentStream ;
0 commit comments