From aa0edd00966237163451fc44cda2c593a5215cbe Mon Sep 17 00:00:00 2001
From: Tim Burke <tim.burke@gmail.com>
Date: Fri, 26 Feb 2016 11:25:10 -0800
Subject: [PATCH] Force header keys/values to bytes/unicode before coercing to
 unicode

Previously, parse_header_string was only called with data coming out of
requests, which would be either bytes or unicode. Now that we're sending
it request headers as well (see related change), we need to be more
defensive.

If the value given is neither bytes nor unicode, convert it to a native
string. This will allow developers using the client API to continue
sending header dicts like

  {'X-Delete-After': 2}

...as in Swift's test/probe/test_object_expirer.py

Change-Id: Ie57a93274507b184af5cad4260f244359a585f09
Related-Change: I43dd7254f7281d4db59b286aa2145643c64e1705
---
 swiftclient/client.py          | 2 ++
 tests/unit/test_swiftclient.py | 7 +++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/swiftclient/client.py b/swiftclient/client.py
index 8375fede..d2f089a2 100644
--- a/swiftclient/client.py
+++ b/swiftclient/client.py
@@ -169,6 +169,8 @@ def http_log(args, kwargs, resp, body):
 
 
 def parse_header_string(data):
+    if not isinstance(data, (six.text_type, six.binary_type)):
+        data = str(data)
     if six.PY2:
         if isinstance(data, six.text_type):
             # Under Python2 requests only returns binary_type, but if we get
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index ae144e24..2c552be0 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -1203,13 +1203,16 @@ class TestPostObject(MockHttpTest):
 
     def test_ok(self):
         c.http_connection = self.fake_http_connection(200)
+        delete_at = 2.1  # not str! we don't know what other devs will use!
         args = ('http://www.test.com', 'token', 'container', 'obj',
-                {'X-Object-Meta-Test': 'mymeta'})
+                {'X-Object-Meta-Test': 'mymeta',
+                 'X-Delete-At': delete_at})
         c.post_object(*args)
         self.assertRequests([
             ('POST', '/container/obj', '', {
                 'x-auth-token': 'token',
-                'X-Object-Meta-Test': 'mymeta'}),
+                'X-Object-Meta-Test': 'mymeta',
+                'X-Delete-At': delete_at}),
         ])
 
     def test_unicode_ok(self):