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.