diff options
author | Tim Burke <tim.burke@gmail.com> | 2016-06-29 11:07:41 -0700 |
---|---|---|
committer | Tim Burke <tim.burke@gmail.com> | 2016-07-19 12:52:51 -0700 |
commit | dca4ea5fd6e1a4eb15eeea9879913f64f2851446 (patch) | |
tree | fe77962265218fa0b18f118e55936addc21f0a53 /swiftclient/utils.py | |
parent | 07c960d46fe8412d98799b1820d57810a9a8a3e7 (diff) | |
download | python-swiftclient-dca4ea5fd6e1a4eb15eeea9879913f64f2851446.tar.gz |
Fix unicode issues in tempurl command
Previously, we weren't encoding paths and keys as UTF-8, which would
trigger a UnicodeEncodeError on py27.
Change-Id: I2fad428369406c2ae32343a5e943ffb2cd1ca6ef
Diffstat (limited to 'swiftclient/utils.py')
-rw-r--r-- | swiftclient/utils.py | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/swiftclient/utils.py b/swiftclient/utils.py index 0abaed6..10687bf 100644 --- a/swiftclient/utils.py +++ b/swiftclient/utils.py @@ -78,15 +78,20 @@ def generate_temp_url(path, seconds, key, method, absolute=False): :raises: TypeError if seconds is not an integer :return: the path portion of a temporary URL """ - if seconds < 0: - raise ValueError('seconds must be a positive integer') try: - if not absolute: - expiration = int(time.time() + seconds) - else: - expiration = int(seconds) - except TypeError: + seconds = int(seconds) + except ValueError: raise TypeError('seconds must be an integer') + if seconds < 0: + raise ValueError('seconds must be a positive integer') + + if isinstance(path, six.binary_type): + try: + path_for_body = path.decode('utf-8') + except UnicodeDecodeError: + raise ValueError('path must be representable as UTF-8') + else: + path_for_body = path standard_methods = ['GET', 'PUT', 'HEAD', 'POST', 'DELETE'] if method.upper() not in standard_methods: @@ -94,18 +99,24 @@ def generate_temp_url(path, seconds, key, method, absolute=False): logger.warning('Non default HTTP method %s for tempurl specified, ' 'possibly an error', method.upper()) - hmac_body = '\n'.join([method.upper(), str(expiration), path]) + if not absolute: + expiration = int(time.time() + seconds) + else: + expiration = seconds + hmac_body = u'\n'.join([method.upper(), str(expiration), path_for_body]) # Encode to UTF-8 for py3 compatibility - sig = hmac.new(key.encode(), - hmac_body.encode(), - hashlib.sha1).hexdigest() - - return ('{path}?temp_url_sig=' - '{sig}&temp_url_expires={exp}'.format( - path=path, - sig=sig, - exp=expiration)) + if not isinstance(key, six.binary_type): + key = key.encode('utf-8') + sig = hmac.new(key, hmac_body.encode('utf-8'), hashlib.sha1).hexdigest() + + temp_url = u'{path}?temp_url_sig={sig}&temp_url_expires={exp}'.format( + path=path_for_body, sig=sig, exp=expiration) + # Have return type match path from caller + if isinstance(path, six.binary_type): + return temp_url.encode('utf-8') + else: + return temp_url def parse_api_response(headers, body): |