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'
|
# 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
|
# on the wire get translated to u'\u00ff' on py3, which gets upper()ed to
|
||||||
# u'\u0178', which is nonsense in a WSGI string.
|
# u'\u0178', which is nonsense in a WSGI string.
|
||||||
real_header = wsgi_to_str(header_name)
|
# Note that we have to only get as far as bytes because something like
|
||||||
header_name = 'HTTP_' + str_to_wsgi(real_header.upper()).replace('-', '_')
|
# 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_LENGTH':
|
||||||
return 'CONTENT_LENGTH'
|
return 'CONTENT_LENGTH'
|
||||||
if header_name == 'HTTP_CONTENT_TYPE':
|
if header_name == 'HTTP_CONTENT_TYPE':
|
||||||
@ -257,7 +261,8 @@ class HeaderEnvironProxy(MutableMapping):
|
|||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
# See the to/from WSGI comment in header_to_environ_key
|
# See the to/from WSGI comment in header_to_environ_key
|
||||||
keys = [str_to_wsgi(wsgi_to_str(key[5:]).replace('_', '-').title())
|
keys = [
|
||||||
|
bytes_to_wsgi(wsgi_to_bytes(key[5:]).replace(b'_', b'-').title())
|
||||||
for key in self.environ if key.startswith('HTTP_')]
|
for key in self.environ if key.startswith('HTTP_')]
|
||||||
if 'CONTENT_LENGTH' in self.environ:
|
if 'CONTENT_LENGTH' in self.environ:
|
||||||
keys.append('Content-Length')
|
keys.append('Content-Length')
|
||||||
|
@ -32,21 +32,26 @@ class TestHeaderEnvironProxy(unittest.TestCase):
|
|||||||
def test_proxy(self):
|
def test_proxy(self):
|
||||||
environ = {}
|
environ = {}
|
||||||
proxy = swift.common.swob.HeaderEnvironProxy(environ)
|
proxy = swift.common.swob.HeaderEnvironProxy(environ)
|
||||||
|
self.assertIs(environ, proxy.environ)
|
||||||
proxy['Content-Length'] = 20
|
proxy['Content-Length'] = 20
|
||||||
proxy['Content-Type'] = 'text/plain'
|
proxy['Content-Type'] = 'text/plain'
|
||||||
proxy['Something-Else'] = 'somevalue'
|
proxy['Something-Else'] = 'somevalue'
|
||||||
self.assertEqual(
|
# NB: WSGI strings
|
||||||
proxy.environ, {'CONTENT_LENGTH': '20',
|
proxy['X-Object-Meta-Unicode-\xff-Bu\xc3\x9fe'] = '\xe2\x98\xb9'
|
||||||
|
self.assertEqual(proxy.environ, {
|
||||||
|
'CONTENT_LENGTH': '20',
|
||||||
'CONTENT_TYPE': 'text/plain',
|
'CONTENT_TYPE': 'text/plain',
|
||||||
'HTTP_SOMETHING_ELSE': 'somevalue'})
|
'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-length'], '20')
|
||||||
self.assertEqual(proxy['content-type'], 'text/plain')
|
self.assertEqual(proxy['content-type'], 'text/plain')
|
||||||
self.assertEqual(proxy['something-else'], 'somevalue')
|
self.assertEqual(proxy['something-else'], 'somevalue')
|
||||||
self.assertEqual(set(['Something-Else',
|
self.assertEqual(set(['Something-Else',
|
||||||
|
'X-Object-Meta-Unicode-\xff-Bu\xc3\x9fE',
|
||||||
'Content-Length', 'Content-Type']),
|
'Content-Length', 'Content-Type']),
|
||||||
set(proxy.keys()))
|
set(proxy.keys()))
|
||||||
self.assertEqual(list(iter(proxy)), proxy.keys())
|
self.assertEqual(list(iter(proxy)), proxy.keys())
|
||||||
self.assertEqual(3, len(proxy))
|
self.assertEqual(4, len(proxy))
|
||||||
|
|
||||||
def test_ignored_keys(self):
|
def test_ignored_keys(self):
|
||||||
# Constructor doesn't normalize keys
|
# Constructor doesn't normalize keys
|
||||||
@ -58,6 +63,8 @@ class TestHeaderEnvironProxy(unittest.TestCase):
|
|||||||
self.assertEqual(0, len(proxy))
|
self.assertEqual(0, len(proxy))
|
||||||
self.assertRaises(KeyError, proxy.__getitem__, key)
|
self.assertRaises(KeyError, proxy.__getitem__, key)
|
||||||
self.assertNotIn(key, proxy)
|
self.assertNotIn(key, proxy)
|
||||||
|
self.assertIn(key, proxy.environ)
|
||||||
|
self.assertIs(environ, proxy.environ)
|
||||||
|
|
||||||
proxy['Content-Type'] = 'text/plain'
|
proxy['Content-Type'] = 'text/plain'
|
||||||
self.assertEqual(['Content-Type'], list(iter(proxy)))
|
self.assertEqual(['Content-Type'], list(iter(proxy)))
|
||||||
@ -77,6 +84,8 @@ class TestHeaderEnvironProxy(unittest.TestCase):
|
|||||||
del proxy['Something-Else']
|
del proxy['Something-Else']
|
||||||
self.assertEqual(proxy.environ, {})
|
self.assertEqual(proxy.environ, {})
|
||||||
self.assertEqual(0, len(proxy))
|
self.assertEqual(0, len(proxy))
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
del proxy['Content-Length']
|
||||||
|
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
environ = {}
|
environ = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user