rest: return 415 when content-type is invalid

When the body of a POST request cannot be decoded because
the content-type is not supported by any rest controller.

The server should return 415, not 500.

Related bug: #1419110

Change-Id: I8f8df4ab4062181e8d511e437a8486182c262ff8
This commit is contained in:
Mehdi Abaakouk 2015-08-03 18:28:23 +02:00
parent 03f0c0b4d6
commit 078cd72365
3 changed files with 16 additions and 2 deletions

View File

@ -233,7 +233,8 @@ def args_from_body(funcdef, body, mimetype):
elif mimetype in restxml.accept_content_types:
dataformat = restxml
else:
raise ValueError("Unknown mimetype: %s" % mimetype)
raise ClientSideError("Unknown mimetype: %s" % mimetype,
status_code=415)
try:
kw = dataformat.parse(

View File

@ -203,6 +203,7 @@ class WSRoot(object):
infos = wsme.api.format_exception(sys.exc_info(), self._debug)
if isinstance(e, ClientSideError):
request.client_errorcount += 1
request.client_last_status_code = e.code
else:
request.server_errorcount += 1
return protocol.encode_error(context, infos)
@ -266,6 +267,7 @@ class WSRoot(object):
request.calls = []
request.client_errorcount = 0
request.client_last_status_code = None
request.server_errorcount = 0
try:
@ -290,7 +292,9 @@ class WSRoot(object):
if hasattr(protocol, 'get_response_status'):
res.status = protocol.get_response_status(request)
else:
if request.client_errorcount:
if request.client_errorcount == 1:
res.status = request.client_last_status_code
elif request.client_errorcount:
res.status = 400
elif request.server_errorcount:
res.status = 500

View File

@ -250,6 +250,15 @@ class TestRestJson(wsme.tests.protocol.RestOnlyProtocolTestCase):
print(r)
assert json.loads(r.text) == 2
def test_invalid_content_type_body(self):
r = self.app.post('/argtypes/setint.json', '{"value": 2}',
headers={"Content-Type": "application/invalid"},
expect_errors=True)
print(r)
assert r.status_int == 415
assert json.loads(r.text)['faultstring'] == \
"Unknown mimetype: application/invalid"
def test_invalid_json_body(self):
r = self.app.post('/argtypes/setint.json', '{"value": 2',
headers={"Content-Type": "application/json"},