Skip to content

Commit

Permalink
Customize HTTP vendor prefix for Google Storage
Browse files Browse the repository at this point in the history
Google storage uses/expects custom headers like meta data
and storage class to be prefixed with "x-goog" instead of
"x-amz". This enables use of object tagging in the Google
Storage provider.

Closes #356

Signed-off-by: Tomaz Muraus <tomaz@apache.org>
  • Loading branch information
sfriesel authored and Kami committed Sep 13, 2014
1 parent 688ec75 commit d1b6bb7
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ Storage
- Fix a bug with CDN requests in the CloudFiles driver.
[Tomaz Muraus]

- Fix a bug with not being able to specify meta_data / tags when uploading an
object using Google Storage driver.
(LIBCLOUD-612, GITHUB-356)
[Stefan Friesel]

Loadbalancer
~~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions libcloud/storage/drivers/google_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@ class GoogleStorageDriver(BaseS3StorageDriver):
namespace = NAMESPACE
supports_chunked_encoding = False
supports_s3_multipart_upload = False
http_vendor_prefix = 'x-goog'
12 changes: 7 additions & 5 deletions libcloud/storage/drivers/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class BaseS3StorageDriver(StorageDriver):
supports_s3_multipart_upload = True
ex_location_name = ''
namespace = NAMESPACE
http_vendor_prefix = 'x-amz'

def iterate_containers(self):
response = self.connection.request('/')
Expand Down Expand Up @@ -799,19 +800,20 @@ def _put_object(self, container, object_name, upload_func,
raise ValueError(
'Invalid storage class value: %s' % (storage_class))

headers['x-amz-storage-class'] = storage_class.upper()
key = self.http_vendor_prefix + '-storage-class'
headers[key] = storage_class.upper()

content_type = extra.get('content_type', None)
meta_data = extra.get('meta_data', None)
acl = extra.get('acl', None)

if meta_data:
for key, value in list(meta_data.items()):
key = 'x-amz-meta-%s' % (key)
key = self.http_vendor_prefix + '-meta-%s' % (key)
headers[key] = value

if acl:
headers['x-amz-acl'] = acl
headers[self.http_vendor_prefix + '-acl'] = acl

request_path = self._get_object_path(container, object_name)

Expand Down Expand Up @@ -883,10 +885,10 @@ def _headers_to_object(self, object_name, container, headers):
extra['last_modified'] = headers['last-modified']

for key, value in headers.items():
if not key.lower().startswith('x-amz-meta-'):
if not key.lower().startswith(self.http_vendor_prefix + '-meta-'):
continue

key = key.replace('x-amz-meta-', '')
key = key.replace(self.http_vendor_prefix + '-meta-', '')
meta_data[key] = value

obj = Object(name=object_name, size=headers['content-length'],
Expand Down
18 changes: 18 additions & 0 deletions libcloud/test/storage/test_google_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import sys
import unittest

from libcloud.utils.py3 import httplib

from libcloud.storage.drivers.google_storage import GoogleStorageDriver
from libcloud.test.storage.test_s3 import S3Tests, S3MockHttp

Expand All @@ -26,6 +28,22 @@
class GoogleStorageMockHttp(S3MockHttp):
fixtures = StorageFileFixtures('google_storage')

def _test2_test_get_object(self, method, url, body, headers):
# test_get_object
# Google uses a different HTTP header prefix for meta data
body = self.fixtures.load('list_containers.xml')
headers = {'content-type': 'application/zip',
'etag': '"e31208wqsdoj329jd"',
'x-goog-meta-rabbits': 'monkeys',
'content-length': 12345,
'last-modified': 'Thu, 13 Sep 2012 07:13:22 GMT'
}

return (httplib.OK,
body,
headers,
httplib.responses[httplib.OK])


class GoogleStorageTests(S3Tests):
driver_type = GoogleStorageDriver
Expand Down

0 comments on commit d1b6bb7

Please sign in to comment.