py3: Fix header_to_environ_key
When doing things for the sake of WSGI, .upper(), .title() etc. should only be used on bytes. Change-Id: I130ba5014b7eff458d87ab29eb42fe45607c9a12
This commit is contained in:
parent
dca658103a
commit
06e4533c2e
@ -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':
|
||||
return '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:
|
||||
keys.append('Content-Length')
|
||||
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'
|
||||
self.assertEqual(
|
||||
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_LENGTH': '20',
|
||||
'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')
|
||||
self.assertEqual(set(['Something-Else',
|
||||
'X-Object-Meta-Unicode-\xff-Bu\xc3\x9fE',
|
||||
'Content-Length', 'Content-Type']),
|
||||
set(proxy.keys()))
|
||||
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 = {}
|
||||
|
Loading…
Reference in New Issue
Block a user