summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2016-08-25 10:51:29 -0700
committerTim Burke <tim.burke@gmail.com>2016-08-25 11:32:08 -0700
commitab60e08e2e34ac4a87bc6c1701c6ace69bb392cf (patch)
treeb955ac317d9463bb8a2a6f453f56fd116050ef04
parent5acefd27e4e4de01414cc67f6652cc946b51957b (diff)
downloadpython-swiftclient-ab60e08e2e34ac4a87bc6c1701c6ace69bb392cf.tar.gz
Convert numeric and boolean header values to strings
Recently, requests got a bit more picky about what types of data it will accept as header values [1]. The reasons for this are generally sound; str()ing arbitrary objects just before pushing them out a socket may not do what the developer wanted/expected. However, there are a few standard types that developers may be sending that we should convert for them as a convenience. Now, we'll convert all int, float, and bool values to strings before sending them on to requests. Change-Id: I6c2f451009cb03cb78812f54e4ed8566076de821 Closes-Bug: 1614932
-rw-r--r--swiftclient/client.py7
-rw-r--r--tests/functional/test_swiftclient.py11
-rw-r--r--tests/unit/test_swiftclient.py7
3 files changed, 21 insertions, 4 deletions
diff --git a/swiftclient/client.py b/swiftclient/client.py
index 602489d..7515f7c 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -211,6 +211,13 @@ def quote(value, safe='/'):
def encode_utf8(value):
+ if type(value) in six.integer_types + (float, bool):
+ # As of requests 2.11.0, headers must be byte- or unicode-strings.
+ # Convert some known-good types as a convenience for developers.
+ # Note that we *don't* convert subclasses, as they may have overriddden
+ # __str__ or __repr__.
+ # See https://github.com/kennethreitz/requests/pull/3366 for more info
+ value = str(value)
if isinstance(value, six.text_type):
value = value.encode('utf8')
return value
diff --git a/tests/functional/test_swiftclient.py b/tests/functional/test_swiftclient.py
index 6e19abd..0e6a346 100644
--- a/tests/functional/test_swiftclient.py
+++ b/tests/functional/test_swiftclient.py
@@ -400,10 +400,19 @@ class TestFunctional(unittest.TestCase):
def test_post_object(self):
self.conn.post_object(self.containername,
self.objectname,
- {'x-object-meta-color': 'Something'})
+ {'x-object-meta-color': 'Something',
+ 'x-object-meta-uni': b'\xd8\xaa'.decode('utf8'),
+ 'x-object-meta-int': 123,
+ 'x-object-meta-float': 45.67,
+ 'x-object-meta-bool': False})
headers = self.conn.head_object(self.containername, self.objectname)
self.assertEqual('Something', headers.get('x-object-meta-color'))
+ self.assertEqual(b'\xd8\xaa'.decode('utf-8'),
+ headers.get('x-object-meta-uni'))
+ self.assertEqual('123', headers.get('x-object-meta-int'))
+ self.assertEqual('45.67', headers.get('x-object-meta-float'))
+ self.assertEqual('False', headers.get('x-object-meta-bool'))
def test_copy_object(self):
self.conn.put_object(
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index 4e4c9f4..09d8e76 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -185,9 +185,9 @@ class TestHttpHelpers(MockHttpTest):
def test_encode_meta_headers(self):
headers = {'abc': '123',
- u'x-container-meta-\u0394': '123',
- u'x-account-meta-\u0394': '123',
- u'x-object-meta-\u0394': '123'}
+ u'x-container-meta-\u0394': 123,
+ u'x-account-meta-\u0394': 12.3,
+ u'x-object-meta-\u0394': True}
r = swiftclient.encode_meta_headers(headers)
@@ -199,6 +199,7 @@ class TestHttpHelpers(MockHttpTest):
for k, v in r.items():
self.assertIs(type(k), binary_type)
self.assertIs(type(v), binary_type)
+ self.assertIn(v, (b'123', b'12.3', b'True'))
def test_set_user_agent_default(self):
_junk, conn = c.http_connection('http://www.example.com')