Commit 1e079cdf authored by Zuul's avatar Zuul Committed by Gerrit Code Review

Merge "py3: Fix header_to_environ_key"

parents b2022923 06e4533c
......@@ -209,8 +209,12 @@ def header_to_environ_key(header_name):
# Why the to/from wsgi dance? Headers that include something like b'\xff'
# on the wire get translated to u'\u00ff' on py3, which gets upper()ed to
# u'\u0178', which is nonsense in a WSGI string.
real_header = wsgi_to_str(header_name)
header_name = 'HTTP_' + str_to_wsgi(real_header.upper()).replace('-', '_')
# Note that we have to only get as far as bytes because something like
# b'\xc3\x9f' on the wire would be u'\u00df' as a native string on py3,
# which would upper() to 'SS'.
real_header = wsgi_to_bytes(header_name)
header_name = 'HTTP_' + bytes_to_wsgi(
real_header.upper()).replace('-', '_')
if header_name == 'HTTP_CONTENT_LENGTH':
if header_name == 'HTTP_CONTENT_TYPE':
......@@ -257,8 +261,9 @@ class HeaderEnvironProxy(MutableMapping):
def keys(self):
# See the to/from WSGI comment in header_to_environ_key
keys = [str_to_wsgi(wsgi_to_str(key[5:]).replace('_', '-').title())
for key in self.environ if key.startswith('HTTP_')]
keys = [
bytes_to_wsgi(wsgi_to_bytes(key[5:]).replace(b'_', b'-').title())
for key in self.environ if key.startswith('HTTP_')]
if 'CONTENT_LENGTH' in self.environ:
if 'CONTENT_TYPE' in self.environ:
......@@ -32,21 +32,26 @@ class TestHeaderEnvironProxy(unittest.TestCase):
def test_proxy(self):
environ = {}
proxy = swift.common.swob.HeaderEnvironProxy(environ)
self.assertIs(environ, proxy.environ)
proxy['Content-Length'] = 20
proxy['Content-Type'] = 'text/plain'
proxy['Something-Else'] = 'somevalue'
proxy.environ, {'CONTENT_LENGTH': '20',
'CONTENT_TYPE': 'text/plain',
'HTTP_SOMETHING_ELSE': 'somevalue'})
# NB: WSGI strings
proxy['X-Object-Meta-Unicode-\xff-Bu\xc3\x9fe'] = '\xe2\x98\xb9'
self.assertEqual(proxy.environ, {
'CONTENT_TYPE': 'text/plain',
'HTTP_SOMETHING_ELSE': 'somevalue',
'HTTP_X_OBJECT_META_UNICODE_\xff_BU\xc3\x9fE': '\xe2\x98\xb9'})
self.assertEqual(proxy['content-length'], '20')
self.assertEqual(proxy['content-type'], 'text/plain')
self.assertEqual(proxy['something-else'], 'somevalue')
'Content-Length', 'Content-Type']),
self.assertEqual(list(iter(proxy)), proxy.keys())
self.assertEqual(3, len(proxy))
self.assertEqual(4, len(proxy))
def test_ignored_keys(self):
# Constructor doesn't normalize keys
......@@ -58,6 +63,8 @@ class TestHeaderEnvironProxy(unittest.TestCase):
self.assertEqual(0, len(proxy))
self.assertRaises(KeyError, proxy.__getitem__, key)
self.assertNotIn(key, proxy)
self.assertIn(key, proxy.environ)
self.assertIs(environ, proxy.environ)
proxy['Content-Type'] = 'text/plain'
self.assertEqual(['Content-Type'], list(iter(proxy)))
......@@ -77,6 +84,8 @@ class TestHeaderEnvironProxy(unittest.TestCase):
del proxy['Something-Else']
self.assertEqual(proxy.environ, {})
self.assertEqual(0, len(proxy))
with self.assertRaises(KeyError):
del proxy['Content-Length']
def test_contains(self):
environ = {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment