summaryrefslogtreecommitdiff
path: root/swiftclient/utils.py
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2016-06-29 11:07:41 -0700
committerTim Burke <tim.burke@gmail.com>2016-07-19 12:52:51 -0700
commitdca4ea5fd6e1a4eb15eeea9879913f64f2851446 (patch)
treefe77962265218fa0b18f118e55936addc21f0a53 /swiftclient/utils.py
parent07c960d46fe8412d98799b1820d57810a9a8a3e7 (diff)
downloadpython-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.py45
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):