Py3: Ensure wsgi headers are not bytes type

In Python 3, running the Masakari API as a wsgi application was
resulting in "TypeError: expected unicode object, value of type
bytes found". It looks like headerlist should not include bytes
type objects so let's ensure they are str objects for Python 3.

Change-Id: Ica030c540970474cd2511ffe0ba653d7bb057849
Partial-Bug: #1815657
This commit is contained in:
Corey Bryant 2019-02-13 15:04:33 -05:00 committed by shilpa
parent c6a79ff315
commit 041af276d7
2 changed files with 36 additions and 16 deletions

View File

@ -306,15 +306,25 @@ class ResponseObject(object):
body = serializer.serialize(self.obj)
response = webob.Response(body=body)
if response.headers.get('Content-Length'):
# NOTE: we need to encode 'Content-Length' header,
# since webob.Response auto sets it if "body" attr is presented.
# https://github.com/Pylons/webob/blob/1.5.0b0/webob/response.py#L147
response.headers['Content-Length'] = utils.utf8(
response.headers['Content-Length'])
if six.PY3:
response.headers['Content-Length'] = (str(
response.headers['Content-Length']))
else:
# NOTE: we need to encode 'Content-Length' header, since
# webob.Response auto sets it if "body" attr is presented.
# github.com/Pylons/webob/blob/1.5.0b0/webob/response.py#L147
response.headers['Content-Length'] = utils.utf8(
response.headers['Content-Length'])
response.status_int = self.code
for hdr, value in self._headers.items():
response.headers[hdr] = utils.utf8(value)
response.headers['Content-Type'] = utils.utf8(content_type)
if six.PY3:
response.headers[hdr] = str(value)
else:
response.headers[hdr] = utils.utf8(value)
if six.PY3:
response.headers['Content-Type'] = str(content_type)
else:
response.headers['Content-Type'] = utils.utf8(content_type)
return response
@property
@ -689,8 +699,11 @@ class Resource(wsgi.Application):
if hasattr(response, 'headers'):
for hdr, val in list(response.headers.items()):
# Headers must be utf-8 strings
response.headers[hdr] = utils.utf8(val)
if six.PY3:
response.headers[hdr] = str(val)
else:
# Headers must be utf-8 strings
response.headers[hdr] = utils.utf8(val)
if not request.api_version_request.is_null():
response.headers[API_VERSION_REQUEST_HEADER] = \

View File

@ -16,6 +16,7 @@
import inspect
import mock
import six
from six.moves import http_client as http
import testscenarios
import webob
@ -872,7 +873,7 @@ class ResourceTest(MicroversionedTest):
except wsgi.Fault as fault:
self.assertEqual(http.BAD_REQUEST, fault.status_int)
def test_resource_headers_are_utf8(self):
def test_resource_headers_py2_are_utf8(self):
resp = webob.Response(status_int=http.ACCEPTED)
resp.headers['x-header1'] = 1
resp.headers['x-header2'] = u'header2'
@ -885,12 +886,18 @@ class ResourceTest(MicroversionedTest):
req = webob.Request.blank('/tests')
app = fakes.TestRouter(Controller())
response = req.get_response(app)
for val in response.headers.values():
# All headers must be utf8
self.assertThat(val, matchers.EncodedByUTF8())
self.assertEqual(b'1', response.headers['x-header1'])
self.assertEqual(b'header2', response.headers['x-header2'])
self.assertEqual(b'header3', response.headers['x-header3'])
if six.PY2:
for val in response.headers.values():
# All headers must be utf8
self.assertThat(val, matchers.EncodedByUTF8())
self.assertEqual(b'1', response.headers['x-header1'])
self.assertEqual(b'header2', response.headers['x-header2'])
self.assertEqual(b'header3', response.headers['x-header3'])
else:
self.assertEqual('1', response.headers['x-header1'])
self.assertEqual(u'header2', response.headers['x-header2'])
self.assertEqual(u'header3', response.headers['x-header3'])
def test_resource_valid_utf8_body(self):
class Controller(object):