diff --git a/botocore/utils.py b/botocore/utils.py index a643d888d4..8eda6148b6 100644 --- a/botocore/utils.py +++ b/botocore/utils.py @@ -2215,7 +2215,7 @@ def conditionally_calculate_md5(params, **kwargs): """Only add a Content-MD5 if the system supports it.""" headers = params['headers'] body = params['body'] - if MD5_AVAILABLE and body and 'Content-MD5' not in headers: + if MD5_AVAILABLE and body is not None and 'Content-MD5' not in headers: md5_digest = calculate_md5(body, **kwargs) params['headers']['Content-MD5'] = md5_digest diff --git a/tests/functional/test_s3.py b/tests/functional/test_s3.py index 00917d93f1..b7645125d0 100644 --- a/tests/functional/test_s3.py +++ b/tests/functional/test_s3.py @@ -919,6 +919,18 @@ def test_content_md5_set(self): self.client.put_object(Bucket='foo', Key='bar', Body='baz') self.assertIn('content-md5', self.get_sent_headers()) + def test_content_md5_set_empty_body(self): + with self.http_stubber: + self.client.put_object(Bucket='foo', Key='bar', Body='') + self.assertIn('content-md5', self.get_sent_headers()) + + def test_content_md5_set_empty_file(self): + with self.http_stubber: + with temporary_file('rb') as f: + assert f.read() == b'' + self.client.put_object(Bucket='foo', Key='bar', Body=f) + self.assertIn('content-md5', self.get_sent_headers()) + def test_content_sha256_set_if_config_value_is_true(self): config = Config(signature_version='s3v4', s3={ 'payload_signing_enabled': True diff --git a/tests/unit/test_handlers.py b/tests/unit/test_handlers.py index 7857ef67a8..fde22e34e6 100644 --- a/tests/unit/test_handlers.py +++ b/tests/unit/test_handlers.py @@ -1217,6 +1217,17 @@ def test_add_md5_with_bytes_object(self): request_dict['headers']['Content-MD5'], 'OFj2IjCsPJFfMAxmQxLGPw==') + def test_add_md5_with_empty_body(self): + request_dict = { + 'body': b'', + 'headers': {} + } + self.md5_digest.return_value = b'8X\xf6"0\xac<\x91_0\x0cfC\x12\xc6?' + conditionally_calculate_md5(request_dict) + self.assertEqual( + request_dict['headers']['Content-MD5'], + 'OFj2IjCsPJFfMAxmQxLGPw==') + def test_add_md5_with_bytearray_object(self): request_dict = { 'body': bytearray(b'foobar'),