[placement] prevent a KeyError in webob.dec.wsgify

If a PUT, POST or PATCH is sent without a content-type header,
webob.dec.wsgify will raise a KeyError. Avoid this by checking for
the content-type header before reaching any wsgify calls. As noted
in the TODO within this is not the most elegant solution, but
prevents an inadvertent 500 and returns a reasonable 400.

Change-Id: I6e7dffb5dc5f0cdc78a57e8df3ae9952c55163ae
Closes-Bug: #1623517
This commit is contained in:
Chris Dent 2016-09-14 15:18:30 +01:00 committed by Matt Riedemann
parent daf4cc6b24
commit 281a78e0af
3 changed files with 24 additions and 1 deletions

View File

@ -35,7 +35,7 @@ from nova.api.openstack.placement.handlers import root
from nova.api.openstack.placement.handlers import usage
from nova.api.openstack.placement import util
from nova import exception
from nova.i18n import _LE
from nova.i18n import _, _LE
LOG = logging.getLogger(__name__)
@ -154,6 +154,21 @@ class PlacementHandler(object):
raise webob.exc.HTTPForbidden(
'admin required',
json_formatter=util.json_error_formatter)
# Check that an incoming write-oriented request method has
# the required content-type header. If not raise a 400. If
# this doesn't happen here then webob.dec.wsgify (elsewhere
# in the stack) will raise an uncaught KeyError. Since that
# is such a generic exception we cannot merely catch it
# here, we need to avoid it ever happening.
# TODO(cdent): Move this and the auth checking above into
# middleware. It shouldn't be here. This is for dispatch not
# validation or authorization.
request_method = environ['REQUEST_METHOD'].upper()
if request_method in ('POST', 'PUT', 'PATCH'):
if 'CONTENT_TYPE' not in environ:
raise webob.exc.HTTPBadRequest(
_('content-type header required'),
json_formatter=util.json_error_formatter)
try:
return dispatch(environ, start_response, self._map)
# Trap the small number of nova exceptions that aren't

View File

@ -73,6 +73,11 @@ tests:
data: I want a resource provider please
status: 415
- name: post resource provider missing content-type
POST: /resource_providers
data: I want a resource provider please
status: 400
- name: post resource provider schema mismatch
POST: /resource_providers
request_headers:

View File

@ -73,7 +73,10 @@ tests:
- "invalid version string: 1.2.3"
- name: error in application produces microversion headers
desc: we do not want xml
POST: /
request_headers:
content-type: application/xml
status: 405
response_headers:
openstack-api-version: placement 1.0