From f7587e8cbb5dd0c735584fd3d68daa0292616130 Mon Sep 17 00:00:00 2001 From: Hyungoo Kang Date: Fri, 12 Feb 2016 13:35:25 +0900 Subject: [PATCH 1/4] Adding optional content type argument to generate signed URI method --- gcloud/storage/blob.py | 14 ++++++++++---- gcloud/storage/test_blob.py | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py index 2947cef50761..3dd5d4f2d1dd 100644 --- a/gcloud/storage/blob.py +++ b/gcloud/storage/blob.py @@ -149,10 +149,10 @@ def public_url(self): bucket_name=self.bucket.name, quoted_name=quote(self.name, safe='')) - def generate_signed_url(self, expiration, method='GET', - client=None, credentials=None, - response_type=None, response_disposition=None, - generation=None): + def generate_signed_url(self, expiration, method='GET', client=None, + content_type="application/octet-stream", + credentials=None, response_type=None, + response_disposition=None, generation=None): """Generates a signed URL for this blob. .. note:: @@ -183,6 +183,11 @@ def generate_signed_url(self, expiration, method='GET', :param client: (Optional) The client to use. If not passed, falls back to the ``client`` stored on the blob's bucket. + :type content_type: str + :param content_type: (Optional) The content type of the object + referenced by ``resource``, defaults to + ``application/octet-stream``. + :type credentials: :class:`oauth2client.client.OAuth2Credentials` or :class:`NoneType` :param credentials: (Optional) The OAuth2 credentials to use to sign @@ -222,6 +227,7 @@ def generate_signed_url(self, expiration, method='GET', credentials, resource=resource, api_access_endpoint=_API_ACCESS_ENDPOINT, expiration=expiration, method=method, + content_type=content_type, response_type=response_type, response_disposition=response_disposition, generation=generation) diff --git a/gcloud/storage/test_blob.py b/gcloud/storage/test_blob.py index 2b958e6d4308..07cc56c03b64 100644 --- a/gcloud/storage/test_blob.py +++ b/gcloud/storage/test_blob.py @@ -146,6 +146,7 @@ def _basic_generate_signed_url_helper(self, credentials=None): 'expiration': EXPIRATION, 'method': 'GET', 'resource': PATH, + 'content_type': "application/octet-stream", 'response_type': None, 'response_disposition': None, 'generation': None, @@ -183,6 +184,7 @@ def test_generate_signed_url_w_slash_in_name(self): 'expiration': EXPIRATION, 'method': 'GET', 'resource': '/name/parent%2Fchild', + 'content_type': "application/octet-stream", 'response_type': None, 'response_disposition': None, 'generation': None, @@ -214,6 +216,7 @@ def test_generate_signed_url_w_method_arg(self): 'expiration': EXPIRATION, 'method': 'POST', 'resource': PATH, + 'content_type': "application/octet-stream", 'response_type': None, 'response_disposition': None, 'generation': None, From e7b50826c0e6fb30ac298e1d58eed4f3a6377fa2 Mon Sep 17 00:00:00 2001 From: Hyungoo Kang Date: Sat, 13 Feb 2016 15:31:04 +0900 Subject: [PATCH 2/4] Reordering argument --- gcloud/storage/blob.py | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py index 3dd5d4f2d1dd..c9b02659e556 100644 --- a/gcloud/storage/blob.py +++ b/gcloud/storage/blob.py @@ -149,10 +149,10 @@ def public_url(self): bucket_name=self.bucket.name, quoted_name=quote(self.name, safe='')) - def generate_signed_url(self, expiration, method='GET', client=None, - content_type="application/octet-stream", - credentials=None, response_type=None, - response_disposition=None, generation=None): + def generate_signed_url(self, expiration, method='GET', + content_type='application/octet-stream', + generation=None, response_disposition=None, + response_type=None, client=None, credentials=None): """Generates a signed URL for this blob. .. note:: @@ -179,25 +179,14 @@ def generate_signed_url(self, expiration, method='GET', client=None, :type method: str :param method: The HTTP verb that will be used when requesting the URL. - :type client: :class:`gcloud.storage.client.Client` or ``NoneType`` - :param client: (Optional) The client to use. If not passed, falls back - to the ``client`` stored on the blob's bucket. - :type content_type: str :param content_type: (Optional) The content type of the object referenced by ``resource``, defaults to ``application/octet-stream``. - :type credentials: :class:`oauth2client.client.OAuth2Credentials` or - :class:`NoneType` - :param credentials: (Optional) The OAuth2 credentials to use to sign - the URL. Defaults to the credentials stored on the - client used. - - :type response_type: str - :param response_type: (Optional) Content type of responses to requests - for the signed URL. Used to over-ride the content - type of the underlying blob/object. + :type generation: str + :param generation: (Optional) A value that indicates which generation + of the resource to fetch. :type response_disposition: str :param response_disposition: (Optional) Content disposition of @@ -207,9 +196,21 @@ def generate_signed_url(self, expiration, method='GET', client=None, the value ``'attachment; filename=blob.png'``. - :type generation: str - :param generation: (Optional) A value that indicates which generation - of the resource to fetch. + :type response_type: str + :param response_type: (Optional) Content type of responses to requests + for the signed URL. Used to over-ride the content + type of the underlying blob/object. + + :type client: :class:`gcloud.storage.client.Client` or ``NoneType`` + :param client: (Optional) The client to use. If not passed, falls back + to the ``client`` stored on the blob's bucket. + + + :type credentials: :class:`oauth2client.client.OAuth2Credentials` or + :class:`NoneType` + :param credentials: (Optional) The OAuth2 credentials to use to sign + the URL. Defaults to the credentials stored on the + client used. :rtype: str :returns: A signed URL you can use to access the resource From bae74e89d14f616615c89c9800c46b0ced71384e Mon Sep 17 00:00:00 2001 From: Hyungoo Kang Date: Sat, 13 Feb 2016 18:49:45 +0900 Subject: [PATCH 3/4] Drop default content type --- gcloud/storage/blob.py | 5 ++--- gcloud/storage/test_blob.py | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py index c9b02659e556..c8ced994f856 100644 --- a/gcloud/storage/blob.py +++ b/gcloud/storage/blob.py @@ -150,7 +150,7 @@ def public_url(self): quoted_name=quote(self.name, safe='')) def generate_signed_url(self, expiration, method='GET', - content_type='application/octet-stream', + content_type=None, generation=None, response_disposition=None, response_type=None, client=None, credentials=None): """Generates a signed URL for this blob. @@ -181,8 +181,7 @@ def generate_signed_url(self, expiration, method='GET', :type content_type: str :param content_type: (Optional) The content type of the object - referenced by ``resource``, defaults to - ``application/octet-stream``. + referenced by ``resource``. :type generation: str :param generation: (Optional) A value that indicates which generation diff --git a/gcloud/storage/test_blob.py b/gcloud/storage/test_blob.py index 07cc56c03b64..3b120c3c7d83 100644 --- a/gcloud/storage/test_blob.py +++ b/gcloud/storage/test_blob.py @@ -146,7 +146,7 @@ def _basic_generate_signed_url_helper(self, credentials=None): 'expiration': EXPIRATION, 'method': 'GET', 'resource': PATH, - 'content_type': "application/octet-stream", + 'content_type': None, 'response_type': None, 'response_disposition': None, 'generation': None, @@ -184,7 +184,7 @@ def test_generate_signed_url_w_slash_in_name(self): 'expiration': EXPIRATION, 'method': 'GET', 'resource': '/name/parent%2Fchild', - 'content_type': "application/octet-stream", + 'content_type': None, 'response_type': None, 'response_disposition': None, 'generation': None, @@ -216,7 +216,7 @@ def test_generate_signed_url_w_method_arg(self): 'expiration': EXPIRATION, 'method': 'POST', 'resource': PATH, - 'content_type': "application/octet-stream", + 'content_type': None, 'response_type': None, 'response_disposition': None, 'generation': None, From 791e1e76571ee1346d6a44633e0c198a34b80fc1 Mon Sep 17 00:00:00 2001 From: Hyungoo Kang Date: Tue, 16 Feb 2016 10:28:38 +0900 Subject: [PATCH 4/4] Adding test that covers explicit content type argument - Testing with plain name (+2 squashed commits) Squashed commits: [d3ffb14] Keep code DRY [73c285c] Adding test that covers explicit content type argument --- gcloud/storage/test_blob.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gcloud/storage/test_blob.py b/gcloud/storage/test_blob.py index 3b120c3c7d83..868498555587 100644 --- a/gcloud/storage/test_blob.py +++ b/gcloud/storage/test_blob.py @@ -156,6 +156,40 @@ def _basic_generate_signed_url_helper(self, credentials=None): def test_generate_signed_url_w_default_method(self): self._basic_generate_signed_url_helper() + def test_generate_signed_url_w_content_type(self): + from gcloud._testing import _Monkey + from gcloud.storage import blob as MUT + + BLOB_NAME = 'blob-name' + EXPIRATION = '2014-10-16T20:34:37.000Z' + connection = _Connection() + client = _Client(connection) + bucket = _Bucket(client) + blob = self._makeOne(BLOB_NAME, bucket=bucket) + URI = ('http://example.com/abucket/a-blob-name?Signature=DEADBEEF' + '&Expiration=2014-10-16T20:34:37.000Z') + + SIGNER = _Signer() + CONTENT_TYPE = "text/html" + with _Monkey(MUT, generate_signed_url=SIGNER): + signed_url = blob.generate_signed_url(EXPIRATION, + content_type=CONTENT_TYPE) + self.assertEqual(signed_url, URI) + + PATH = '/name/%s' % (BLOB_NAME,) + EXPECTED_ARGS = (_Connection.credentials,) + EXPECTED_KWARGS = { + 'api_access_endpoint': 'https://storage.googleapis.com', + 'expiration': EXPIRATION, + 'method': 'GET', + 'resource': PATH, + 'content_type': CONTENT_TYPE, + 'response_type': None, + 'response_disposition': None, + 'generation': None, + } + self.assertEqual(SIGNER._signed, [(EXPECTED_ARGS, EXPECTED_KWARGS)]) + def test_generate_signed_url_w_credentials(self): credentials = object() self._basic_generate_signed_url_helper(credentials=credentials)