diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
index 153b9b0751e7..01fc58ec28fd 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_blob_client.py
@@ -385,7 +385,7 @@ def _upload_blob_options( # pylint:disable=too-many-statements
kwargs['blob_headers'] = BlobHTTPHeaders(
blob_cache_control=content_settings.cache_control,
blob_content_type=content_settings.content_type,
- blob_content_md5=bytearray(content_settings.content_md5) if content_settings.content_md5 else None,
+ blob_content_md5=content_settings.content_md5,
blob_content_encoding=content_settings.content_encoding,
blob_content_language=content_settings.content_language,
blob_content_disposition=content_settings.content_disposition
@@ -1208,7 +1208,7 @@ def _set_http_headers_options(self, content_settings=None, **kwargs):
blob_headers = BlobHTTPHeaders(
blob_cache_control=content_settings.cache_control,
blob_content_type=content_settings.content_type,
- blob_content_md5=bytearray(content_settings.content_md5) if content_settings.content_md5 else None,
+ blob_content_md5=content_settings.content_md5,
blob_content_encoding=content_settings.content_encoding,
blob_content_language=content_settings.content_language,
blob_content_disposition=content_settings.content_disposition
@@ -1376,7 +1376,7 @@ def _create_page_blob_options( # type: ignore
blob_headers = BlobHTTPHeaders(
blob_cache_control=content_settings.cache_control,
blob_content_type=content_settings.content_type,
- blob_content_md5=bytearray(content_settings.content_md5) if content_settings.content_md5 else None,
+ blob_content_md5=content_settings.content_md5,
blob_content_encoding=content_settings.content_encoding,
blob_content_language=content_settings.content_language,
blob_content_disposition=content_settings.content_disposition
@@ -1517,7 +1517,7 @@ def _create_append_blob_options(self, content_settings=None, metadata=None, **kw
blob_headers = BlobHTTPHeaders(
blob_cache_control=content_settings.cache_control,
blob_content_type=content_settings.content_type,
- blob_content_md5=bytearray(content_settings.content_md5) if content_settings.content_md5 else None,
+ blob_content_md5=content_settings.content_md5,
blob_content_encoding=content_settings.content_encoding,
blob_content_language=content_settings.content_language,
blob_content_disposition=content_settings.content_disposition
@@ -2350,7 +2350,7 @@ def _commit_block_list_options( # type: ignore
blob_headers = BlobHTTPHeaders(
blob_cache_control=content_settings.cache_control,
blob_content_type=content_settings.content_type,
- blob_content_md5=bytearray(content_settings.content_md5) if content_settings.content_md5 else None,
+ blob_content_md5=content_settings.content_md5,
blob_content_encoding=content_settings.content_encoding,
blob_content_language=content_settings.content_language,
blob_content_disposition=content_settings.content_disposition
diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
index 2340431bd598..00a53dc68bfb 100644
--- a/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
+++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_models.py
@@ -622,7 +622,7 @@ class ContentSettings(DictMixin):
:param str cache_control:
If the cache_control has previously been set for
the blob, that value is stored.
- :param str content_md5:
+ :param bytearray content_md5:
If the content_md5 has been set for the blob, this response
header is stored so that the client can check for message content
integrity.
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob.test_upload_blob_content_md5.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob.test_upload_blob_content_md5.yaml
new file mode 100644
index 000000000000..3c3b515334a9
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob.test_upload_blob_content_md5.yaml
@@ -0,0 +1,315 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '0'
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ etag:
+ - '"0x8D8DC69063B0887"'
+ last-modified:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8/blob192b711b8
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ etag:
+ - '"0x8D8DC6906463DF5"'
+ last-modified:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - vo7q9sPVKY0=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: HEAD
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8/blob192b711b8
+ response:
+ body:
+ string: ''
+ headers:
+ accept-ranges:
+ - bytes
+ content-length:
+ - '11'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ content-type:
+ - application/octet-stream
+ date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ etag:
+ - '"0x8D8DC6906463DF5"'
+ last-modified:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary:
+ - Origin
+ x-ms-access-tier:
+ - Hot
+ x-ms-access-tier-inferred:
+ - 'true'
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-creation-time:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ x-ms-lease-state:
+ - available
+ x-ms-lease-status:
+ - unlocked
+ x-ms-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 200
+ message: OK
+- request:
+ body: hello world this wont work
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '26'
+ Content-Type:
+ - application/octet-stream
+ If-None-Match:
+ - '*'
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8/blob292b711b8
+ response:
+ body:
+ string: "\uFEFFMd5MismatchThe
+ MD5 value specified in the request did not match with the MD5 value calculated
+ by the server.\nRequestId:22874362-c01e-00be-4c51-0e3b8d000000\nTime:2021-03-01T04:18:10.9305633ZXrY7u+Ae7tCTyyK7j1rNww==jZ0KWGQraqYHX42NEbH9Vg=="
+ headers:
+ content-length:
+ - '405'
+ content-type:
+ - application/xml
+ date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code:
+ - Md5Mismatch
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 400
+ message: The MD5 value specified in the request did not match with the MD5 value
+ calculated by the server.
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ If-None-Match:
+ - '*'
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8/blob292b711b8
+ response:
+ body:
+ string: ''
+ headers:
+ content-length:
+ - '0'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ date:
+ - Mon, 01 Mar 2021 04:18:10 GMT
+ etag:
+ - '"0x8D8DC690666ED45"'
+ last-modified:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64:
+ - vo7q9sPVKY0=
+ x-ms-request-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 201
+ message: Created
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: HEAD
+ uri: https://storagename.blob.core.windows.net/utcontainer92b711b8/blob292b711b8
+ response:
+ body:
+ string: ''
+ headers:
+ accept-ranges:
+ - bytes
+ content-length:
+ - '11'
+ content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ content-type:
+ - application/octet-stream
+ date:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ etag:
+ - '"0x8D8DC690666ED45"'
+ last-modified:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ server:
+ - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary:
+ - Origin
+ x-ms-access-tier:
+ - Hot
+ x-ms-access-tier-inferred:
+ - 'true'
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-creation-time:
+ - Mon, 01 Mar 2021 04:18:11 GMT
+ x-ms-lease-state:
+ - available
+ x-ms-lease-status:
+ - unlocked
+ x-ms-server-encrypted:
+ - 'true'
+ x-ms-version:
+ - '2020-06-12'
+ status:
+ code: 200
+ message: OK
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob_async.test_upload_blob_content_md5.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob_async.test_upload_blob_content_md5.yaml
new file mode 100644
index 000000000000..537eb5ee29e7
--- /dev/null
+++ b/sdk/storage/azure-storage-blob/tests/recordings/test_block_blob_async.test_upload_blob_content_md5.yaml
@@ -0,0 +1,231 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435?restype=container
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ etag: '"0x8D8DC69778E8AD9"'
+ last-modified: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-version: '2020-06-12'
+ status:
+ code: 201
+ message: Created
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435?restype=container
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435/blob187a1435
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ etag: '"0x8D8DC69779243D2"'
+ last-modified: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: vo7q9sPVKY0=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-06-12'
+ status:
+ code: 201
+ message: Created
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435/blob187a1435
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: HEAD
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435/blob187a1435
+ response:
+ body:
+ string: ''
+ headers:
+ accept-ranges: bytes
+ content-length: '11'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ content-type: application/octet-stream
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ etag: '"0x8D8DC69779243D2"'
+ last-modified: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary: Origin
+ x-ms-access-tier: Hot
+ x-ms-access-tier-inferred: 'true'
+ x-ms-blob-type: BlockBlob
+ x-ms-creation-time: Mon, 01 Mar 2021 04:21:20 GMT
+ x-ms-lease-state: available
+ x-ms-lease-status: unlocked
+ x-ms-server-encrypted: 'true'
+ x-ms-version: '2020-06-12'
+ status:
+ code: 200
+ message: OK
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435/blob187a1435
+- request:
+ body: hello world this wont work
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '26'
+ Content-Type:
+ - application/octet-stream
+ If-None-Match:
+ - '*'
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435/blob287a1435
+ response:
+ body:
+ string: "\uFEFFMd5MismatchThe
+ MD5 value specified in the request did not match with the MD5 value calculated
+ by the server.\nRequestId:1d84afe3-e01e-0096-2252-0e5a25000000\nTime:2021-03-01T04:21:20.9369998ZXrY7u+Ae7tCTyyK7j1rNww==jZ0KWGQraqYHX42NEbH9Vg=="
+ headers:
+ content-length: '405'
+ content-type: application/xml
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-error-code: Md5Mismatch
+ x-ms-version: '2020-06-12'
+ status:
+ code: 400
+ message: The MD5 value specified in the request did not match with the MD5 value
+ calculated by the server.
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435/blob287a1435
+- request:
+ body: hello world
+ headers:
+ Accept:
+ - application/xml
+ Content-Length:
+ - '11'
+ Content-Type:
+ - application/octet-stream
+ If-None-Match:
+ - '*'
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-blob-content-md5:
+ - XrY7u+Ae7tCTyyK7j1rNww==
+ x-ms-blob-type:
+ - BlockBlob
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: PUT
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435/blob287a1435
+ response:
+ body:
+ string: ''
+ headers:
+ content-length: '0'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ etag: '"0x8D8DC6977A029EA"'
+ last-modified: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ x-ms-content-crc64: vo7q9sPVKY0=
+ x-ms-request-server-encrypted: 'true'
+ x-ms-version: '2020-06-12'
+ status:
+ code: 201
+ message: Created
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435/blob287a1435
+- request:
+ body: null
+ headers:
+ Accept:
+ - application/xml
+ User-Agent:
+ - azsdk-python-storage-blob/12.8.0b1 Python/3.8.5 (Windows-10-10.0.19041-SP0)
+ x-ms-date:
+ - Mon, 01 Mar 2021 04:21:21 GMT
+ x-ms-encryption-algorithm:
+ - AES256
+ x-ms-version:
+ - '2020-06-12'
+ method: HEAD
+ uri: https://storagename.blob.core.windows.net/utcontainer87a1435/blob287a1435
+ response:
+ body:
+ string: ''
+ headers:
+ accept-ranges: bytes
+ content-length: '11'
+ content-md5: XrY7u+Ae7tCTyyK7j1rNww==
+ content-type: application/octet-stream
+ date: Mon, 01 Mar 2021 04:21:20 GMT
+ etag: '"0x8D8DC6977A029EA"'
+ last-modified: Mon, 01 Mar 2021 04:21:20 GMT
+ server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
+ vary: Origin
+ x-ms-access-tier: Hot
+ x-ms-access-tier-inferred: 'true'
+ x-ms-blob-type: BlockBlob
+ x-ms-creation-time: Mon, 01 Mar 2021 04:21:20 GMT
+ x-ms-lease-state: available
+ x-ms-lease-status: unlocked
+ x-ms-server-encrypted: 'true'
+ x-ms-version: '2020-06-12'
+ status:
+ code: 200
+ message: OK
+ url: https://emilydevtest.blob.core.windows.net/utcontainer87a1435/blob287a1435
+version: 1
diff --git a/sdk/storage/azure-storage-blob/tests/test_block_blob.py b/sdk/storage/azure-storage-blob/tests/test_block_blob.py
index 7e0dfd9453cb..a916f49076d9 100644
--- a/sdk/storage/azure-storage-blob/tests/test_block_blob.py
+++ b/sdk/storage/azure-storage-blob/tests/test_block_blob.py
@@ -61,8 +61,8 @@ def _teardown(self, FILE_PATH):
pass
#--Helpers-----------------------------------------------------------------
- def _get_blob_reference(self):
- return self.get_resource_name(TEST_BLOB_PREFIX)
+ def _get_blob_reference(self, prefix=TEST_BLOB_PREFIX):
+ return self.get_resource_name(prefix)
def _create_blob(self, tags=None, data=b'', **kwargs):
blob_name = self._get_blob_reference()
@@ -566,6 +566,29 @@ def test_create_small_block_blob_with_no_overwrite(self, resource_group, locatio
self.assertEqual(props.last_modified, create_resp.get('last_modified'))
self.assertEqual(props.blob_type, BlobType.BlockBlob)
+ @GlobalStorageAccountPreparer()
+ def test_upload_blob_content_md5(self, resource_group, location, storage_account, storage_account_key):
+ self._setup(storage_account, storage_account_key)
+ blob1_name = self._get_blob_reference(prefix="blob1")
+ blob2_name = self._get_blob_reference(prefix="blob2")
+ blob1 = self.bsc.get_blob_client(self.container_name, blob1_name)
+ blob2 = self.bsc.get_blob_client(self.container_name, blob2_name)
+ data1 = b'hello world'
+ data2 = b'hello world this wont work'
+
+ # Act
+ blob1.upload_blob(data1, overwrite=True)
+ blob1_md5 = blob1.get_blob_properties().content_settings.content_md5
+ blob2_content_settings = ContentSettings(content_md5=blob1_md5)
+
+ # Passing data that does not match the md5
+ with self.assertRaises(HttpResponseError):
+ blob2.upload_blob(data2, content_settings=blob2_content_settings)
+ # Correct data and corresponding md5
+ blob2.upload_blob(data1, content_settings=blob2_content_settings)
+ blob2_md5 = blob2.get_blob_properties().content_settings.content_md5
+ self.assertEqual(blob1_md5, blob2_md5)
+
@GlobalStorageAccountPreparer()
def test_create_small_block_blob_with_overwrite(self, resource_group, location, storage_account, storage_account_key):
self._setup(storage_account, storage_account_key)
diff --git a/sdk/storage/azure-storage-blob/tests/test_block_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_block_blob_async.py
index a481a9cc7efd..a2c9155b762f 100644
--- a/sdk/storage/azure-storage-blob/tests/test_block_blob_async.py
+++ b/sdk/storage/azure-storage-blob/tests/test_block_blob_async.py
@@ -80,8 +80,8 @@ def _teardown(self, FILE_PATH):
except:
pass
- def _get_blob_reference(self):
- return self.get_resource_name(TEST_BLOB_PREFIX)
+ def _get_blob_reference(self, prefix=TEST_BLOB_PREFIX):
+ return self.get_resource_name(prefix)
def _get_blob_with_special_chars_reference(self):
return 'भारत¥test/testsubÐirÍ/'+self.get_resource_name('srcÆblob')
@@ -659,6 +659,31 @@ async def test_get_block_list_committed_blocks(self, resource_group, location, s
self.assertEqual(block_list[0][2].id, '3')
self.assertEqual(block_list[0][2].size, 3)
+ @GlobalStorageAccountPreparer()
+ @AsyncStorageTestCase.await_prepared_test
+ async def test_upload_blob_content_md5(self, resource_group, location, storage_account, storage_account_key):
+ await self._setup(storage_account, storage_account_key)
+ blob1_name = self._get_blob_reference(prefix="blob1")
+ blob2_name = self._get_blob_reference(prefix="blob2")
+ blob1 = self.bsc.get_blob_client(self.container_name, blob1_name)
+ blob2 = self.bsc.get_blob_client(self.container_name, blob2_name)
+ data1 = b'hello world'
+ data2 = b'hello world this wont work'
+
+ # Act
+ await blob1.upload_blob(data1, overwrite=True)
+ blob1_props = await blob1.get_blob_properties()
+ blob1_md5 = blob1_props.content_settings.content_md5
+ blob2_content_settings = ContentSettings(content_md5=blob1_md5)
+
+ # Passing data that does not match the md5
+ with self.assertRaises(HttpResponseError):
+ await blob2.upload_blob(data2, content_settings=blob2_content_settings)
+ # Correct data and corresponding md5
+ await blob2.upload_blob(data1, content_settings=blob2_content_settings)
+ blob2_props = await blob2.get_blob_properties()
+ blob2_md5 = blob2_props.content_settings.content_md5
+ self.assertEqual(blob1_md5, blob2_md5)
@GlobalStorageAccountPreparer()
@AsyncStorageTestCase.await_prepared_test
diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py
index 63b818a037b2..b99f9aa09d78 100644
--- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py
+++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_models.py
@@ -259,7 +259,7 @@ class ContentSettings(BlobContentSettings):
:ivar str cache_control:
If the cache_control has previously been set for
the file, that value is stored.
- :ivar str content_md5:
+ :ivar bytearray content_md5:
If the content_md5 has been set for the file, this response
header is stored so that the client can check for message content
integrity.
@@ -280,7 +280,7 @@ class ContentSettings(BlobContentSettings):
:keyword str cache_control:
If the cache_control has previously been set for
the file, that value is stored.
- :keyword str content_md5:
+ :keyword bytearray content_md5:
If the content_md5 has been set for the file, this response
header is stored so that the client can check for message content
integrity.
diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_models.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_models.py
index 796b43b2e33b..ef937439dffa 100644
--- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_models.py
+++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_models.py
@@ -274,7 +274,7 @@ class ContentSettings(DictMixin):
:param str cache_control:
If the cache_control has previously been set for
the file, that value is stored.
- :param str content_md5:
+ :param bytearray content_md5:
If the content_md5 has been set for the file, this response
header is stored so that the client can check for message content
integrity.