summaryrefslogtreecommitdiff
path: root/tests/unit/test_swiftclient.py
diff options
context:
space:
mode:
authorTimur Alperovich <timur@timuralp.com>2018-04-17 14:36:57 -0700
committerTimur Alperovich <timur@timuralp.com>2018-07-23 14:38:40 -0700
commitf4a2b16c2cc65410765abdff7a45532305a4548f (patch)
tree918fef8f12ec8cfdebddb378753c1d4aa5ec6047 /tests/unit/test_swiftclient.py
parent23d29eda8d03785c22d67930e21a0ba4098ba23c (diff)
downloadpython-swiftclient-f4a2b16c2cc65410765abdff7a45532305a4548f.tar.gz
Properly handle unicode headers.
Fix unicode handling in Python 3 and Python 2. There are currently two failure modes. In python 2, swiftclient fails to log in debug mode if the account name has a non-ASCII character. This is because the account name will appear in the storage URL, which we attempt to pass to the logger as a byte string (whereas it should be a unicode string). This patch changes the behavior to convert the path strings into unicode by calling the parse_header_string() function. The second failure mode is with Python 3, where http_lib returns headers that are latin-1 encoded, but swiftclient expects UTF-8. The patch automatically converts headers from latin-1 (iso-8859-1) to UTF-8, so that we can properly handle non-ASCII headers in responses. Change-Id: Ifa7f3d5af71bde8127129f1f8603772d80d063c1
Diffstat (limited to 'tests/unit/test_swiftclient.py')
-rw-r--r--tests/unit/test_swiftclient.py61
1 files changed, 61 insertions, 0 deletions
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index b6d6856..3303372 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -1896,6 +1896,57 @@ class TestHTTPConnection(MockHttpTest):
self.assertFalse(resp.read())
self.assertTrue(resp.closed)
+ @unittest.skipIf(six.PY3, 'python2 specific test')
+ def test_response_python2_headers(self):
+ '''Test utf-8 headers in Python 2.
+ '''
+ _, conn = c.http_connection(u'http://www.test.com/')
+ conn.resp = MockHttpResponse(
+ status=200,
+ headers={
+ '\xd8\xaa-unicode': '\xd8\xaa-value',
+ 'empty-header': ''
+ }
+ )
+
+ resp = conn.getresponse()
+ self.assertEqual(
+ '\xd8\xaa-value', resp.getheader('\xd8\xaa-unicode'))
+ self.assertEqual(
+ '\xd8\xaa-value', resp.getheader('\xd8\xaa-UNICODE'))
+ self.assertEqual('', resp.getheader('empty-header'))
+ self.assertEqual(
+ dict([('\xd8\xaa-unicode', '\xd8\xaa-value'),
+ ('empty-header', ''),
+ ('etag', '"%s"' % EMPTY_ETAG)]),
+ dict(resp.getheaders()))
+
+ @unittest.skipIf(six.PY2, 'python3 specific test')
+ def test_response_python3_headers(self):
+ '''Test latin1-encoded headers in Python 3.
+ '''
+ _, conn = c.http_connection(u'http://www.test.com/')
+ conn.resp = MockHttpResponse(
+ status=200,
+ headers={
+ b'\xd8\xaa-unicode'.decode('iso-8859-1'):
+ b'\xd8\xaa-value'.decode('iso-8859-1'),
+ 'empty-header': ''
+ }
+ )
+
+ resp = conn.getresponse()
+ self.assertEqual(
+ '\u062a-value', resp.getheader('\u062a-unicode'))
+ self.assertEqual(
+ '\u062a-value', resp.getheader('\u062a-UNICODE'))
+ self.assertEqual('', resp.getheader('empty-header'))
+ self.assertEqual(
+ dict([('\u062a-unicode', '\u062a-value'),
+ ('empty-header', ''),
+ ('etag', ('"%s"' % EMPTY_ETAG))]),
+ dict(resp.getheaders()))
+
class TestConnection(MockHttpTest):
@@ -2839,6 +2890,16 @@ class TestLogging(MockHttpTest):
self.assertIn('X-Storage-Token', output)
self.assertIn(unicode_token_value, output)
+ @mock.patch('swiftclient.client.logger.debug')
+ def test_unicode_path(self, mock_log):
+ path = u'http://swift/v1/AUTH_account-\u062a'.encode('utf-8')
+ c.http_log(['GET', path], {},
+ MockHttpResponse(status=200, headers=[]), '')
+ request_log_line = mock_log.mock_calls[0]
+ self.assertEqual('REQ: %s', request_log_line[1][0])
+ self.assertEqual(u'curl -i -X GET %s' % path.decode('utf-8'),
+ request_log_line[1][1])
+
class TestCloseConnection(MockHttpTest):