[placement] ensure that allow headers are native strings
mod-wsgi checks that response header values are what's described as "native strings". This means whatever `str` is in either python 2 or 3, but never `unicode`. When they are not mod-wsgi will 500. For the most part this is taken care of by webob, but in the case of the 405 handling, the webob response is not being fully massaged. mod-wsgi is doing this because it supposed to. Python WSGI server gateways have different expectations of headers depending on whether the Python is 2 or 3. See https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types In addition to the unit test, the gabbi tests are now using a version of wsgi-intercept that will raise a TypeError when the application response headers are not using the correct form. This check needs to be done in wsgi-intercept rather than the gabbi tests because both wsgi-intercept and the http client makes requests transform the headers for their own purposes. This fix ensures that instead of a 500 the correct 405 response happens. Closes-Bug: #1626496 Depends-On: I3b8aabda929fe39b60e645abb6fabb9769554829 Change-Id: Ifa436e11e79adc2e159b4c5e7d3623d9a792b5f7
This commit is contained in:
parent
de82d98333
commit
5fdb9226d2
|
@ -107,7 +107,11 @@ def handle_405(environ, start_response):
|
|||
_methods = util.wsgi_path_item(environ, '_methods')
|
||||
headers = {}
|
||||
if _methods:
|
||||
headers['allow'] = _methods
|
||||
# Ensure allow header is a python 2 or 3 native string (thus
|
||||
# not unicode in python 2 but stay a string in python 3)
|
||||
# In the process done by Routes to save the allowed methods
|
||||
# to its routing table they become unicode in py2.
|
||||
headers['allow'] = str(_methods)
|
||||
raise webob.exc.HTTPMethodNotAllowed(
|
||||
_('The method specified is not allowed for this resource.'),
|
||||
headers=headers, json_formatter=util.json_error_formatter)
|
||||
|
|
|
@ -12,10 +12,15 @@
|
|||
|
||||
import os
|
||||
|
||||
import wsgi_intercept
|
||||
|
||||
from gabbi import driver
|
||||
|
||||
from nova.tests.functional.api.openstack.placement import fixtures
|
||||
|
||||
# Check that wsgi application response headers are always
|
||||
# native str.
|
||||
wsgi_intercept.STRICT_RESPONSE_HEADERS = True
|
||||
TESTS_DIR = 'gabbits'
|
||||
|
||||
|
||||
|
|
|
@ -92,12 +92,24 @@ class MapperTest(test.NoDBTestCase):
|
|||
action = self.mapper.match(environ=environ)['action']
|
||||
self.assertEqual('hello', action)
|
||||
|
||||
def test_405(self):
|
||||
def test_405_methods(self):
|
||||
environ = _environ(path='/hello', method='POST')
|
||||
result = self.mapper.match(environ=environ)
|
||||
self.assertEqual(handler.handle_405, result['action'])
|
||||
self.assertEqual('GET', result['_methods'])
|
||||
|
||||
def test_405_headers(self):
|
||||
environ = _environ(path='/hello', method='POST')
|
||||
error = self.assertRaises(webob.exc.HTTPMethodNotAllowed,
|
||||
handler.dispatch,
|
||||
environ, start_response,
|
||||
self.mapper)
|
||||
allow_header = error.headers['allow']
|
||||
self.assertEqual('GET', allow_header)
|
||||
# PEP 3333 requires that headers be whatever the native str
|
||||
# is in that version of Python. Never unicode.
|
||||
self.assertEqual(str, type(allow_header))
|
||||
|
||||
|
||||
class PlacementLoggingTest(test.NoDBTestCase):
|
||||
|
||||
|
|
|
@ -33,4 +33,4 @@ oslo.vmware>=2.11.0 # Apache-2.0
|
|||
reno>=1.8.0 # Apache2
|
||||
|
||||
# placement functional tests
|
||||
wsgi-intercept>=0.6.1 # MIT License
|
||||
wsgi-intercept>=1.4.1 # MIT License
|
||||
|
|
Loading…
Reference in New Issue