summaryrefslogtreecommitdiff
path: root/nova/api/openstack/wsgi.py
diff options
context:
space:
mode:
authorMarkus Zoeller <mzoeller@de.ibm.com>2017-04-04 17:23:09 +0200
committerMarkus Zoeller <mzoeller@de.ibm.com>2017-04-04 17:26:16 +0200
commit7db528379ac8bd9a1f2101a73f78f882884825da (patch)
treed93c109102f741d4dcf92a7bfb57ec0020d812a0 /nova/api/openstack/wsgi.py
parent13e51e29a4d733715dd7ea8641008cedf4ad0f78 (diff)
downloadnova-7db528379ac8bd9a1f2101a73f78f882884825da.tar.gz
API: accept None as content-length in HTTP requests
The API defines PUT and POST as HTTP methods which need a request body. It is allowed, that this request body might be of zero length. What was missing is, that the "content-length" of the request also might be None. The tempest test cases of servers.test_server_tags.ServerTagsTestJSON revealed that a PUT with a non-existing body raises a BadRequest exception because of the missing "content-length". [tempest.lib.common.rest_client] Request - Headers: {'Content-Type': 'application/json', 'Accept': 'application/json', 'X-OpenStack-Nova-API-Version': '2.26', 'X-Auth-Token': '<omitted>'} Body: None Response - Headers: {'status': '400', u'content-length': '66', u'server': 'Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_wsgi/3.4 Python/2.7.5', u'date': 'Mon, 03 Apr 2017 10:15:12 GMT', u'x-openstack-nova-api-version': '2.26', u'x-compute-request-id': 'req-1f8726fc-df20-4592-a214-cff3fa73c8e6', u'content-type': 'application/json; charset=UTF-8', content-location': 'https://ctrl:8774/v2.1/servers/<uuid>/tags/mytag', u'vary': 'OpenStack-API-Version,X-OpenStack-Nova-API-Version', u'openstack-api-version': 'compute 2.26', u'connection': 'close'} Body: {"badRequest": {"message": "Malformed request body", "code": 400} } For some reason this, this seems to only occur on centos7 test nodes, but not on ubuntu xenial nodes. The root cause is still unclear to me. I suspect the underlying "webob.Request" object which is used in Nova's API, but I don't have proof for that. This change checks for "content-length is None". The logic to determine the request content was part of a very long method which is hard to test. That's why I extracted the code paths to a new method. That made the unit test much easier. Change I3236648f79f44d2758bb7ab0d64d58b0143f6bdb alters the tempest test cases which revealed the missing handling of "content-length is None". Change-Id: Id0b0ab5050a4ec15ab2a0d0dd67fcefe4b1ecb39 Closes-Bug: #1679223
Diffstat (limited to 'nova/api/openstack/wsgi.py')
-rw-r--r--nova/api/openstack/wsgi.py18
1 files changed, 11 insertions, 7 deletions
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 1144400c34..73d37655c6 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -625,13 +625,7 @@ class Resource(wsgi.Application):
# Now, deserialize the request body...
try:
- contents = {}
- if self._should_have_body(request):
- # allow empty body with PUT and POST
- if request.content_length == 0:
- contents = {'body': None}
- else:
- contents = self.deserialize(body)
+ contents = self._get_request_content(body, request)
except exception.MalformedRequestBody:
msg = _("Malformed request body")
return Fault(webob.exc.HTTPBadRequest(explanation=msg))
@@ -699,6 +693,16 @@ class Resource(wsgi.Application):
return response
+ def _get_request_content(self, body, request):
+ contents = {}
+ if self._should_have_body(request):
+ # allow empty body with PUT and POST
+ if request.content_length == 0 or request.content_length is None:
+ contents = {'body': None}
+ else:
+ contents = self.deserialize(body)
+ return contents
+
def get_method(self, request, action, content_type, body):
meth, extensions = self._get_method(request,
action,