Fix the incompatible issue in response header
Some changes were made to fix fernet padding for python3 [1], fernet payload is decoded to str after encryption when creating a fernet token. But it will be unicode string on python27 and this is not compatible with `mod_wsgi`. `mod_wsgi` needs the value in the response headers is binary(str) type on python2, and unicode(str) type on python3. This patch does this translation accordingly to make keystone works with `mod_wsgi`. [1] https://review.openstack.org/#/c/231711/ Closes-Bug: #1528981 Change-Id: I0217ac10d20c51a9c17bed566f326eb6db6ed949
This commit is contained in:
parent
a422291b03
commit
5b445469b6
@ -743,6 +743,36 @@ def render_response(body=None, status=None, headers=None, method=None):
|
|||||||
headers.append(('Content-Type', 'application/json'))
|
headers.append(('Content-Type', 'application/json'))
|
||||||
status = status or (200, 'OK')
|
status = status or (200, 'OK')
|
||||||
|
|
||||||
|
# NOTE(davechen): `mod_wsgi` follows the standards from pep-3333 and
|
||||||
|
# requires the value in response header to be binary type(str) on python2,
|
||||||
|
# unicode based string(str) on python3, or else keystone will not work
|
||||||
|
# under apache with `mod_wsgi`.
|
||||||
|
# keystone needs to check the data type of each header and convert the
|
||||||
|
# type if needed.
|
||||||
|
# see bug:
|
||||||
|
# https://bugs.launchpad.net/keystone/+bug/1528981
|
||||||
|
# see pep-3333:
|
||||||
|
# https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types
|
||||||
|
# see source from mod_wsgi:
|
||||||
|
# https://github.com/GrahamDumpleton/mod_wsgi(methods:
|
||||||
|
# wsgi_convert_headers_to_bytes(...), wsgi_convert_string_to_bytes(...)
|
||||||
|
# and wsgi_validate_header_value(...)).
|
||||||
|
def _convert_to_str(headers):
|
||||||
|
str_headers = []
|
||||||
|
for header in headers:
|
||||||
|
str_header = []
|
||||||
|
for value in header:
|
||||||
|
if not isinstance(value, str):
|
||||||
|
str_header.append(str(value))
|
||||||
|
else:
|
||||||
|
str_header.append(value)
|
||||||
|
# convert the list to the immutable tuple to build the headers.
|
||||||
|
# header's key/value will be guaranteed to be str type.
|
||||||
|
str_headers.append(tuple(str_header))
|
||||||
|
return str_headers
|
||||||
|
|
||||||
|
headers = _convert_to_str(headers)
|
||||||
|
|
||||||
resp = webob.Response(body=body,
|
resp = webob.Response(body=body,
|
||||||
status='%s %s' % status,
|
status='%s %s' % status,
|
||||||
headerlist=headers)
|
headerlist=headers)
|
||||||
|
@ -170,6 +170,18 @@ class ApplicationTest(BaseWSGITest):
|
|||||||
self.assertEqual('Some-Value', resp.headers.get('Custom-Header'))
|
self.assertEqual('Some-Value', resp.headers.get('Custom-Header'))
|
||||||
self.assertEqual('X-Auth-Token', resp.headers.get('Vary'))
|
self.assertEqual('X-Auth-Token', resp.headers.get('Vary'))
|
||||||
|
|
||||||
|
def test_render_response_non_str_headers_converted(self):
|
||||||
|
resp = wsgi.render_response(
|
||||||
|
headers=[('Byte-Header', 'Byte-Value'),
|
||||||
|
(u'Unicode-Header', u'Unicode-Value')])
|
||||||
|
# assert that all headers are identified.
|
||||||
|
self.assertThat(resp.headers, matchers.HasLength(4))
|
||||||
|
self.assertEqual('Unicode-Value', resp.headers.get('Unicode-Header'))
|
||||||
|
# assert that unicode value is converted, the expected type is str
|
||||||
|
# on both python2 and python3.
|
||||||
|
self.assertEqual(str,
|
||||||
|
type(resp.headers.get('Unicode-Header')))
|
||||||
|
|
||||||
def test_render_response_no_body(self):
|
def test_render_response_no_body(self):
|
||||||
resp = wsgi.render_response()
|
resp = wsgi.render_response()
|
||||||
self.assertEqual('204 No Content', resp.status)
|
self.assertEqual('204 No Content', resp.status)
|
||||||
|
Loading…
Reference in New Issue
Block a user