Ensure lists inside parameters are UTF-8 encoded

Recurse properly into embedded lists
Ensure all parameter contents are UTF-8 encoded
This commit is contained in:
sneakypete81 2014-01-31 18:57:33 +00:00
parent f497adcabd
commit 43f533a419
2 changed files with 37 additions and 27 deletions

View file

@ -193,7 +193,8 @@ class TestHttp(unittest.TestCase):
self.client.get(self.test_endpoint,
photo=photo, album=album, tag=tag,
list_=[photo, album, tag],
list2=["1", "2", "3"],
list2=["1", False, 3],
unicode_list=["1", "2", "\xfcmlaut"],
boolean=True,
unicode_="\xfcmlaut")
params = self._last_request().querystring
@ -201,7 +202,8 @@ class TestHttp(unittest.TestCase):
self.assertEqual(params["album"], ["album_id"])
self.assertEqual(params["tag"], ["tag_id"])
self.assertEqual(params["list_"], ["photo_id,album_id,tag_id"])
self.assertEqual(params["list2"], ["1,2,3"])
self.assertEqual(params["list2"], ["1,0,3"])
self.assertIn(params["unicode_list"], [["1,2,\xc3\xbcmlaut"], ["1,2,\xfcmlaut"]])
self.assertEqual(params["boolean"], ["1"])
self.assertIn(params["unicode_"], [["\xc3\xbcmlaut"], ["\xfcmlaut"]])

View file

@ -193,37 +193,45 @@ class Http(object):
endpoint = "/v%d%s" % (self.config["api_version"], endpoint)
return urlunparse((scheme, host, endpoint, '', '', ''))
@staticmethod
def _process_params(params):
def _process_params(self, params):
""" Converts Unicode/lists/booleans inside HTTP parameters """
processed_params = {}
for key, value in params.items():
# Extract IDs from objects
if isinstance(value, TroveboxObject):
value = value.id
# Ensure value is UTF-8 encoded
if isinstance(value, TEXT_TYPE):
value = value.encode("utf-8")
# Handle lists
if isinstance(value, list):
# Make a copy of the list, to avoid overwriting the original
new_list = list(value)
# Extract IDs from objects in the list
for i, item in enumerate(new_list):
if isinstance(item, TroveboxObject):
new_list[i] = item.id
# Convert list to string
value = ','.join([str(item) for item in new_list])
# Handle booleans
if isinstance(value, bool):
value = 1 if value else 0
processed_params[key] = value
processed_params[key] = self._process_param_value(value)
return processed_params
def _process_param_value(self, value):
"""
Returns a UTF-8 string representation of the parameter value,
recursing into lists.
"""
# Extract IDs from objects
if isinstance(value, TroveboxObject):
return str(value.id).encode('utf-8')
# Ensure strings are UTF-8 encoded
elif isinstance(value, TEXT_TYPE):
return value.encode("utf-8")
# Handle lists
elif isinstance(value, list):
# Make a copy of the list, to avoid overwriting the original
new_list = list(value)
# Process each item in the list
for i, item in enumerate(new_list):
new_list[i] = self._process_param_value(item)
# new_list elements are UTF-8 encoded strings - simply join up
return b','.join(new_list)
# Handle booleans
elif isinstance(value, bool):
return b"1" if value else b"0"
# Unknown - just do our best
else:
return str(value).encode("utf-8")
@staticmethod
def _process_response(response):
"""