From 3c53db684e25cab93f5c59cf8eeaf891b6ad2735 Mon Sep 17 00:00:00 2001 From: Aviram Hassan Date: Wed, 26 Aug 2020 23:03:06 +0300 Subject: [PATCH 1/2] fix authorization header on asyncio requests containing url-encoded-able characters (=, ! etc) --- .../azure/storage/blob/_shared/authentication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py index b11dc5757808..c20fb878aaeb 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py @@ -79,7 +79,8 @@ def _get_canonicalized_resource(self, request): uri_path = urlparse(request.http_request.url).path try: if isinstance(request.context.transport, AioHttpTransport) or \ - isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport): + isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \ + isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), AioHttpTransport): uri_path = URL(uri_path) return '/' + self.account_name + str(uri_path) except TypeError: From da81ae5d460e0e3f02210f0296a52d95f590c99b Mon Sep 17 00:00:00 2001 From: xiafu Date: Wed, 26 Aug 2020 18:51:01 -0700 Subject: [PATCH 2/2] edit all authentication files and add a test --- .../storage/blob/_shared/authentication.py | 3 +- ...sync.test_create_blob_with_equal_sign.yaml | 104 ++++++++++++++++++ .../tests/test_common_blob_async.py | 18 +++ .../filedatalake/_shared/authentication.py | 4 +- .../fileshare/_shared/authentication.py | 4 +- .../storage/queue/_shared/authentication.py | 4 +- 6 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_create_blob_with_equal_sign.yaml diff --git a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py index c20fb878aaeb..d04c1e4fb539 100644 --- a/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py +++ b/sdk/storage/azure-storage-blob/azure/storage/blob/_shared/authentication.py @@ -80,7 +80,8 @@ def _get_canonicalized_resource(self, request): try: if isinstance(request.context.transport, AioHttpTransport) or \ isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \ - isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), AioHttpTransport): + isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), + AioHttpTransport): uri_path = URL(uri_path) return '/' + self.account_name + str(uri_path) except TypeError: diff --git a/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_create_blob_with_equal_sign.yaml b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_create_blob_with_equal_sign.yaml new file mode 100644 index 000000000000..67ecf96393b5 --- /dev/null +++ b/sdk/storage/azure-storage-blob/tests/recordings/test_common_blob_async.test_create_blob_with_equal_sign.yaml @@ -0,0 +1,104 @@ +interactions: +- request: + body: null + headers: + User-Agent: + - azsdk-python-storage-blob/12.4.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 27 Aug 2020 01:48:41 GMT + x-ms-version: + - '2019-12-12' + method: PUT + uri: https://storagename.blob.core.windows.net/utcontainer775c1685?timeout=5&restype=container + response: + body: + string: '' + headers: + content-length: '0' + date: Thu, 27 Aug 2020 01:48:40 GMT + etag: '"0x8D84A2B5357BF80"' + last-modified: Thu, 27 Aug 2020 01:48:41 GMT + server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-version: '2019-12-12' + status: + code: 201 + message: Created + url: https://emilyeuap.blob.core.windows.net/utcontainer775c1685?timeout=5&restype=container +- request: + body: ??? + headers: + Content-Length: + - '3' + Content-Type: + - application/octet-stream + If-None-Match: + - '*' + User-Agent: + - azsdk-python-storage-blob/12.4.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + x-ms-blob-type: + - BlockBlob + x-ms-date: + - Thu, 27 Aug 2020 01:48:41 GMT + x-ms-version: + - '2019-12-12' + method: PUT + uri: https://storagename.blob.core.windows.net/utcontainer775c1685/=ques=tion! + response: + body: + string: '' + headers: + content-length: '0' + content-md5: DRsIw0hYkhvHxmKyKKy3ug== + date: Thu, 27 Aug 2020 01:48:40 GMT + etag: '"0x8D84A2B536556A6"' + last-modified: Thu, 27 Aug 2020 01:48:41 GMT + server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-content-crc64: VtoDJyOMw/A= + x-ms-request-server-encrypted: 'true' + x-ms-version: '2019-12-12' + x-ms-version-id: '2020-08-27T01:48:41.6124582Z' + status: + code: 201 + message: Created + url: https://emilyeuap.blob.core.windows.net/utcontainer775c1685/=ques=tion! +- request: + body: null + headers: + Accept: + - application/xml + User-Agent: + - azsdk-python-storage-blob/12.4.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 27 Aug 2020 01:48:41 GMT + x-ms-range: + - bytes=0-33554431 + x-ms-version: + - '2019-12-12' + method: GET + uri: https://storagename.blob.core.windows.net/utcontainer775c1685/=ques=tion! + response: + body: + string: ??? + headers: + accept-ranges: bytes + content-length: '3' + content-range: bytes 0-2/3 + content-type: application/octet-stream + date: Thu, 27 Aug 2020 01:48:41 GMT + etag: '"0x8D84A2B536556A6"' + last-modified: Thu, 27 Aug 2020 01:48:41 GMT + server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-blob-content-md5: DRsIw0hYkhvHxmKyKKy3ug== + x-ms-blob-type: BlockBlob + x-ms-creation-time: Thu, 27 Aug 2020 01:48:41 GMT + x-ms-is-current-version: 'true' + x-ms-lease-state: available + x-ms-lease-status: unlocked + x-ms-server-encrypted: 'true' + x-ms-version: '2019-12-12' + x-ms-version-id: '2020-08-27T01:48:41.6124582Z' + status: + code: 206 + message: Partial Content + url: https://emilyeuap.blob.core.windows.net/utcontainer775c1685/=ques=tion! +version: 1 diff --git a/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py b/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py index c99a9a9fc152..b2a7bc6235d8 100644 --- a/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py +++ b/sdk/storage/azure-storage-blob/tests/test_common_blob_async.py @@ -272,6 +272,24 @@ async def test_create_blob_with_question_mark(self, resource_group, location, st content = data.decode('utf-8') self.assertEqual(content, blob_data) + @GlobalStorageAccountPreparer() + @AsyncStorageTestCase.await_prepared_test + async def test_create_blob_with_equal_sign(self, resource_group, location, storage_account, storage_account_key): + # Arrange + await self._setup(storage_account, storage_account_key) + blob_name = '=ques=tion!' + blob_data = u'???' + + # Act + blob = self.bsc.get_blob_client(self.container_name, blob_name) + await blob.upload_blob(blob_data) + + # Assert + stream = await blob.download_blob() + data = await stream.readall() + self.assertIsNotNone(data) + content = data.decode('utf-8') + self.assertEqual(content, blob_data) @GlobalStorageAccountPreparer() @AsyncStorageTestCase.await_prepared_test diff --git a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/authentication.py b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/authentication.py index b11dc5757808..d04c1e4fb539 100644 --- a/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/authentication.py +++ b/sdk/storage/azure-storage-file-datalake/azure/storage/filedatalake/_shared/authentication.py @@ -79,7 +79,9 @@ def _get_canonicalized_resource(self, request): uri_path = urlparse(request.http_request.url).path try: if isinstance(request.context.transport, AioHttpTransport) or \ - isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport): + isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \ + isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), + AioHttpTransport): uri_path = URL(uri_path) return '/' + self.account_name + str(uri_path) except TypeError: diff --git a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/authentication.py b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/authentication.py index b11dc5757808..d04c1e4fb539 100644 --- a/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/authentication.py +++ b/sdk/storage/azure-storage-file-share/azure/storage/fileshare/_shared/authentication.py @@ -79,7 +79,9 @@ def _get_canonicalized_resource(self, request): uri_path = urlparse(request.http_request.url).path try: if isinstance(request.context.transport, AioHttpTransport) or \ - isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport): + isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \ + isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), + AioHttpTransport): uri_path = URL(uri_path) return '/' + self.account_name + str(uri_path) except TypeError: diff --git a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/authentication.py b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/authentication.py index b11dc5757808..d04c1e4fb539 100644 --- a/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/authentication.py +++ b/sdk/storage/azure-storage-queue/azure/storage/queue/_shared/authentication.py @@ -79,7 +79,9 @@ def _get_canonicalized_resource(self, request): uri_path = urlparse(request.http_request.url).path try: if isinstance(request.context.transport, AioHttpTransport) or \ - isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport): + isinstance(getattr(request.context.transport, "_transport", None), AioHttpTransport) or \ + isinstance(getattr(getattr(request.context.transport, "_transport", None), "_transport", None), + AioHttpTransport): uri_path = URL(uri_path) return '/' + self.account_name + str(uri_path) except TypeError: