diff options
author | Daniel Wakefield <daniel.wakefield@hp.com> | 2014-10-29 10:11:29 +0000 |
---|---|---|
committer | Daniel Wakefield <daniel.wakefield@hp.com> | 2015-02-19 11:21:32 +0000 |
commit | f0300e3714e0d8cdd0ed9e4744b813e3b263d034 (patch) | |
tree | eb7e6c155b70d06338812c01dfe417f1fd2f0e68 /swiftclient/client.py | |
parent | 45cce75e505043bc3aae0a7e889cb1272d80915b (diff) | |
download | python-swiftclient-f0300e3714e0d8cdd0ed9e4744b813e3b263d034.tar.gz |
Verify MD5 of uploaded objects.
Changed existing code to calculate the MD5 of the object
during the upload stream. Checks this MD5 against the etag
returned in the response.
An exception is raised if they do not match.
Closes-Bug: 1379263
Change-Id: I6c8bc1366dfb591a26d934a30cd21c9e6b9a04ce
Diffstat (limited to 'swiftclient/client.py')
-rw-r--r-- | swiftclient/client.py | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/swiftclient/client.py b/swiftclient/client.py index d0ff52e..985cad8 100644 --- a/swiftclient/client.py +++ b/swiftclient/client.py @@ -36,7 +36,7 @@ import six from swiftclient import version as swiftclient_version from swiftclient.exceptions import ClientException -from swiftclient.utils import LengthWrapper +from swiftclient.utils import LengthWrapper, ReadableToIterable AUTH_VERSIONS_V1 = ('1.0', '1', 1) AUTH_VERSIONS_V2 = ('2.0', '2', 2) @@ -333,8 +333,8 @@ def get_auth_keystone(auth_url, user, key, os_options, **kwargs): except exceptions.Unauthorized: msg = 'Unauthorized. Check username, password and tenant name/id.' if auth_version in AUTH_VERSIONS_V3: - msg = 'Unauthorized. Check username/id, password, ' \ - + 'tenant name/id and user/tenant domain name/id.' + msg = ('Unauthorized. Check username/id, password, ' + 'tenant name/id and user/tenant domain name/id.') raise ClientException(msg) except exceptions.AuthorizationFailure as err: raise ClientException('Authorization Failure. %s' % err) @@ -388,8 +388,7 @@ def get_auth(auth_url, user, key, **kwargs): # We are handling a special use case here where the user argument # specifies both the user name and tenant name in the form tenant:user if user and not kwargs.get('tenant_name') and ':' in user: - (os_options['tenant_name'], - user) = user.split(':') + os_options['tenant_name'], user = user.split(':') # We are allowing to have an tenant_name argument in get_auth # directly without having os_options @@ -929,7 +928,8 @@ def put_object(url, token=None, container=None, name=None, contents=None, container name is expected to be part of the url :param name: object name to put; if None, the object name is expected to be part of the url - :param contents: a string or a file like object to read object data from; + :param contents: a string, a file like object or an iterable + to read object data from; if None, a zero-byte put will be done :param content_length: value to send as content-length header; also limits the amount read from contents; if None, it will be @@ -983,27 +983,26 @@ def put_object(url, token=None, container=None, name=None, contents=None, headers['Content-Type'] = '' if not contents: headers['Content-Length'] = '0' - if hasattr(contents, 'read'): + + if isinstance(contents, (ReadableToIterable, LengthWrapper)): + conn.putrequest(path, headers=headers, data=contents) + elif hasattr(contents, 'read'): if chunk_size is None: chunk_size = 65536 + if content_length is None: - def chunk_reader(): - while True: - data = contents.read(chunk_size) - if not data: - break - yield data - conn.putrequest(path, headers=headers, data=chunk_reader()) + data = ReadableToIterable(contents, chunk_size, md5=False) else: - # Fixes https://github.com/kennethreitz/requests/issues/1648 - data = LengthWrapper(contents, content_length) - conn.putrequest(path, headers=headers, data=data) + data = LengthWrapper(contents, content_length, md5=False) + + conn.putrequest(path, headers=headers, data=data) else: if chunk_size is not None: - warn_msg = '%s object has no \"read\" method, ignoring chunk_size'\ - % type(contents).__name__ + warn_msg = ('%s object has no "read" method, ignoring chunk_size' + % type(contents).__name__) warnings.warn(warn_msg, stacklevel=2) conn.request('PUT', path, contents, headers) + resp = conn.getresponse() body = resp.read() headers = {'X-Auth-Token': token} @@ -1018,7 +1017,8 @@ def put_object(url, token=None, container=None, name=None, contents=None, http_status=resp.status, http_reason=resp.reason, http_response_content=body) - return resp.getheader('etag', '').strip('"') + etag = resp.getheader('etag', '').strip('"') + return etag def post_object(url, token, container, name, headers, http_conn=None, |