[placement] set accept to application/json if accept not set
If an incoming request to placement does not set the accept header force it to 'application/json'. This not only ensures that error responses are in JSON but also that errors early in the middleware stack do not cause a key error (see the #1724065 bug). This fix is done by checking headers early in the middleware stack using the requestlog middleware as a convenient place to do the check. This overloads requestlog's purpose, but avoids adding yet more middleware (doing so has some small impact per request). Fixing bug 1724065 fixes a 500. Fixing bug 1674694 changes (for some requests) the content type of the bodies of 400-499 responses. This creates a bit of quandry for microversion handling. If a microversion is considered required here then it's not clear the global fix is worth doing and the 500 fix should be limited the microversion middleware. The intent all along has been that responses should strive to align with the API-WG errors guideline [1], which assumes application/json. [1] http://specs.openstack.org/openstack/api-wg/guidelines/errors.html Change-Id: Ice27c7080fc2df097cb387f7438c0aaf32b4c63d Closes-Bug: #1724065 Closes-Bug: #1674694
This commit is contained in:
@@ -36,6 +36,10 @@ class RequestLog(object):
|
||||
LOG.debug('Starting request: %s "%s %s"',
|
||||
environ['REMOTE_ADDR'], environ['REQUEST_METHOD'],
|
||||
self._get_uri(environ))
|
||||
# Set the accept header if it is not otherwise set. This
|
||||
# ensures that error responses will be in JSON.
|
||||
if not environ.get('HTTP_ACCEPT'):
|
||||
environ['HTTP_ACCEPT'] = 'application/json'
|
||||
if LOG.isEnabledFor(logging.INFO):
|
||||
return self._log_app(environ, start_response)
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Test launchpad bug https://bugs.launchpad.net/nova/+bug/1674694
|
||||
|
||||
fixtures:
|
||||
- APIFixture
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: admin
|
||||
|
||||
tests:
|
||||
|
||||
- name: 404 with application/json
|
||||
GET: /bc8d9d50-7b0d-45ef-839c-e7b5e1c4e8fd
|
||||
request_headers:
|
||||
accept: application/json
|
||||
status: 404
|
||||
response_headers:
|
||||
content-type: application/json
|
||||
response_json_paths:
|
||||
$.errors[0].status: 404
|
||||
|
||||
- name: 404 with no accept
|
||||
GET: /bc8d9d50-7b0d-45ef-839c-e7b5e1c4e8fd
|
||||
status: 404
|
||||
response_headers:
|
||||
content-type: application/json
|
||||
response_json_paths:
|
||||
$.errors[0].status: 404
|
||||
|
||||
- name: 404 with other accept
|
||||
GET: /bc8d9d50-7b0d-45ef-839c-e7b5e1c4e8fd
|
||||
status: 404
|
||||
request_headers:
|
||||
accept: text/html
|
||||
response_headers:
|
||||
content-type: /text/html/
|
||||
response_strings:
|
||||
- The resource could not be found
|
||||
@@ -0,0 +1,22 @@
|
||||
# Test launchpad bug https://bugs.launchpad.net/nova/+bug/1724065
|
||||
|
||||
fixtures:
|
||||
- APIFixture
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: user
|
||||
|
||||
tests:
|
||||
|
||||
# min version from start of placement time is 1.0
|
||||
# Without the fix, this results in a 500 with an 'HTTP_ACCEPT'
|
||||
# KeyError.
|
||||
- name: no accept header and out of range microversion
|
||||
GET: /resource_providers
|
||||
request_headers:
|
||||
openstack-api-version: placement 0.9
|
||||
status: 406
|
||||
response_strings:
|
||||
- Unacceptable version header
|
||||
|
||||
@@ -13,13 +13,13 @@ tests:
|
||||
PUT: /traits/TRAIT_X
|
||||
status: 400
|
||||
response_strings:
|
||||
- 'The trait is invalid. A valid trait must include prefix "CUSTOM_" and use following characters: "A"-"Z", "0"-"9" and "_"'
|
||||
- 'The trait is invalid. A valid trait must include prefix \"CUSTOM_\" and use following characters: \"A\"-\"Z\", \"0\"-\"9\" and \"_\"'
|
||||
|
||||
- name: create a trait with invalid characters
|
||||
PUT: /traits/CUSTOM_ABC:1
|
||||
status: 400
|
||||
response_strings:
|
||||
- 'The trait is invalid. A valid trait must include prefix "CUSTOM_" and use following characters: "A"-"Z", "0"-"9" and "_"'
|
||||
- 'The trait is invalid. A valid trait must include prefix \"CUSTOM_\" and use following characters: \"A\"-\"Z\", \"0\"-\"9\" and \"_\"'
|
||||
|
||||
- name: create a trait
|
||||
PUT: /traits/CUSTOM_TRAIT_1
|
||||
@@ -93,7 +93,7 @@ tests:
|
||||
GET: /traits?name=in_abc
|
||||
status: 400
|
||||
response_strings:
|
||||
- 'Badly formatted name parameter. Expected name query string parameter in form: ?name=[in|startswith]:[name1,name2|prefix]. Got: "in_abc"'
|
||||
- 'Badly formatted name parameter. Expected name query string parameter in form: ?name=[in|startswith]:[name1,name2|prefix]. Got: \"in_abc\"'
|
||||
|
||||
- name: list traits with name=in filter
|
||||
GET: /traits?name=in:CUSTOM_TRAIT_1,CUSTOM_TRAIT_2
|
||||
@@ -177,7 +177,7 @@ tests:
|
||||
GET: /traits?associated=xyz
|
||||
status: 400
|
||||
response_strings:
|
||||
- 'The query parameter "associated" only accepts "true" or "false"'
|
||||
- 'The query parameter \"associated\" only accepts \"true\" or \"false\"'
|
||||
|
||||
- name: set traits for resource provider without resource provider generation
|
||||
PUT: /resource_providers/$ENVIRON['RP_UUID']/traits
|
||||
|
||||
Reference in New Issue
Block a user