@@ -129,10 +129,10 @@ def _assert_expected_crt_http_request(
129129 )
130130 if expected_missing_headers is not None :
131131 header_names = [
132- header [0 ] for header in crt_http_request .headers
132+ header [0 ]. lower () for header in crt_http_request .headers
133133 ]
134134 for expected_missing_header in expected_missing_headers :
135- self .assertNotIn (expected_missing_header , header_names )
135+ self .assertNotIn (expected_missing_header . lower () , header_names )
136136
137137 def _assert_subscribers_called (self , expected_future = None ):
138138 self .assertTrue (self .record_subscriber .on_queued_called )
@@ -145,6 +145,21 @@ def _assert_subscribers_called(self, expected_future=None):
145145 self .record_subscriber .on_done_future , expected_future
146146 )
147147
148+ def _get_expected_upload_checksum_config (self , ** overrides ):
149+ checksum_config_kwargs = {
150+ 'algorithm' : awscrt .s3 .S3ChecksumAlgorithm .CRC32 ,
151+ 'location' : awscrt .s3 .S3ChecksumLocation .TRAILER ,
152+ }
153+ checksum_config_kwargs .update (overrides )
154+ return awscrt .s3 .S3ChecksumConfig (** checksum_config_kwargs )
155+
156+ def _get_expected_download_checksum_config (self , ** overrides ):
157+ checksum_config_kwargs = {
158+ 'validate_response' : True ,
159+ }
160+ checksum_config_kwargs .update (overrides )
161+ return awscrt .s3 .S3ChecksumConfig (** checksum_config_kwargs )
162+
148163 def _invoke_done_callbacks (self , ** kwargs ):
149164 callargs = self .s3_crt_client .make_request .call_args
150165 callargs_kwargs = callargs [1 ]
@@ -182,6 +197,7 @@ def test_upload(self):
182197 'send_filepath' : self .filename ,
183198 'on_progress' : mock .ANY ,
184199 'on_done' : mock .ANY ,
200+ 'checksum_config' : self ._get_expected_upload_checksum_config (),
185201 },
186202 )
187203 self ._assert_expected_crt_http_request (
@@ -208,6 +224,7 @@ def test_upload_from_seekable_stream(self):
208224 'send_filepath' : None ,
209225 'on_progress' : mock .ANY ,
210226 'on_done' : mock .ANY ,
227+ 'checksum_config' : self ._get_expected_upload_checksum_config (),
211228 },
212229 )
213230 self ._assert_expected_crt_http_request (
@@ -239,6 +256,7 @@ def test_upload_from_nonseekable_stream(self):
239256 'send_filepath' : None ,
240257 'on_progress' : mock .ANY ,
241258 'on_done' : mock .ANY ,
259+ 'checksum_config' : self ._get_expected_upload_checksum_config (),
242260 },
243261 )
244262 self ._assert_expected_crt_http_request (
@@ -253,6 +271,90 @@ def test_upload_from_nonseekable_stream(self):
253271 )
254272 self ._assert_subscribers_called (future )
255273
274+ def test_upload_override_checksum_algorithm (self ):
275+ future = self .transfer_manager .upload (
276+ self .filename ,
277+ self .bucket ,
278+ self .key ,
279+ {'ChecksumAlgorithm' : 'CRC32C' },
280+ [self .record_subscriber ],
281+ )
282+ future .result ()
283+
284+ callargs_kwargs = self .s3_crt_client .make_request .call_args [1 ]
285+ self .assertEqual (
286+ callargs_kwargs ,
287+ {
288+ 'request' : mock .ANY ,
289+ 'type' : awscrt .s3 .S3RequestType .PUT_OBJECT ,
290+ 'send_filepath' : self .filename ,
291+ 'on_progress' : mock .ANY ,
292+ 'on_done' : mock .ANY ,
293+ 'checksum_config' : self ._get_expected_upload_checksum_config (
294+ algorithm = awscrt .s3 .S3ChecksumAlgorithm .CRC32C
295+ ),
296+ },
297+ )
298+ self ._assert_expected_crt_http_request (
299+ callargs_kwargs ["request" ],
300+ expected_http_method = 'PUT' ,
301+ expected_content_length = len (self .expected_content ),
302+ expected_missing_headers = [
303+ 'Content-MD5' ,
304+ 'x-amz-sdk-checksum-algorithm' ,
305+ 'X-Amz-Trailer' ,
306+ ],
307+ )
308+ self ._assert_subscribers_called (future )
309+
310+ def test_upload_override_checksum_algorithm_accepts_lowercase (self ):
311+ future = self .transfer_manager .upload (
312+ self .filename ,
313+ self .bucket ,
314+ self .key ,
315+ {'ChecksumAlgorithm' : 'crc32c' },
316+ [self .record_subscriber ],
317+ )
318+ future .result ()
319+
320+ callargs_kwargs = self .s3_crt_client .make_request .call_args [1 ]
321+ self .assertEqual (
322+ callargs_kwargs ,
323+ {
324+ 'request' : mock .ANY ,
325+ 'type' : awscrt .s3 .S3RequestType .PUT_OBJECT ,
326+ 'send_filepath' : self .filename ,
327+ 'on_progress' : mock .ANY ,
328+ 'on_done' : mock .ANY ,
329+ 'checksum_config' : self ._get_expected_upload_checksum_config (
330+ algorithm = awscrt .s3 .S3ChecksumAlgorithm .CRC32C
331+ ),
332+ },
333+ )
334+ self ._assert_expected_crt_http_request (
335+ callargs_kwargs ["request" ],
336+ expected_http_method = 'PUT' ,
337+ expected_content_length = len (self .expected_content ),
338+ expected_missing_headers = [
339+ 'Content-MD5' ,
340+ 'x-amz-sdk-checksum-algorithm' ,
341+ 'X-Amz-Trailer' ,
342+ ],
343+ )
344+ self ._assert_subscribers_called (future )
345+
346+ def test_upload_throws_error_for_unsupported_checksum (self ):
347+ with self .assertRaisesRegex (
348+ ValueError , 'ChecksumAlgorithm: UNSUPPORTED not supported'
349+ ):
350+ self .transfer_manager .upload (
351+ self .filename ,
352+ self .bucket ,
353+ self .key ,
354+ {'ChecksumAlgorithm' : 'UNSUPPORTED' },
355+ [self .record_subscriber ],
356+ )
357+
256358 def test_download (self ):
257359 future = self .transfer_manager .download (
258360 self .bucket , self .key , self .filename , {}, [self .record_subscriber ]
@@ -269,6 +371,7 @@ def test_download(self):
269371 'on_progress' : mock .ANY ,
270372 'on_done' : mock .ANY ,
271373 'on_body' : None ,
374+ 'checksum_config' : self ._get_expected_download_checksum_config (),
272375 },
273376 )
274377 # the recv_filepath will be set to a temporary file path with some
@@ -306,6 +409,7 @@ def test_download_to_seekable_stream(self):
306409 'on_progress' : mock .ANY ,
307410 'on_done' : mock .ANY ,
308411 'on_body' : mock .ANY ,
412+ 'checksum_config' : self ._get_expected_download_checksum_config (),
309413 },
310414 )
311415 self ._assert_expected_crt_http_request (
@@ -340,6 +444,7 @@ def test_download_to_nonseekable_stream(self):
340444 'on_progress' : mock .ANY ,
341445 'on_done' : mock .ANY ,
342446 'on_body' : mock .ANY ,
447+ 'checksum_config' : self ._get_expected_download_checksum_config (),
343448 },
344449 )
345450 self ._assert_expected_crt_http_request (
0 commit comments