ContentMixin: Raise 400 when body decode fails.

This commit is contained in:
Dave Shawley 2016-02-22 09:58:58 -05:00
parent ee28d54036
commit 206e43ee7d
3 changed files with 24 additions and 7 deletions

View file

@ -6,10 +6,11 @@ Version History
- Repackage from a module into a package. Distributing raw modules inside
of a namespace package is unreliable and questionably correct.
- Add :func:`sprockets.mixins.mediatype.content.add_transcoder`.
- Add :class:`sprockets.mixins.mediatype.transcoders.JSONTranscoder`
- Add :class:`sprockets.mixins.mediatype.transcoders.MsgPackTranscoder`
- Add :class:`sprockets.mixins.mediatype.transcoders.BinaryWrapper`
- Add :class:`sprockets.mixins.mediatype.transcoders.JSONTranscoder`.
- Add :class:`sprockets.mixins.mediatype.transcoders.MsgPackTranscoder`.
- Add :class:`sprockets.mixins.mediatype.transcoders.BinaryWrapper`.
- Normalize registered MIME types.
- Raise a 400 status when content body decoding fails.
`1.0.4`_ (14 Sep 2015)
----------------------

View file

@ -236,6 +236,7 @@ class ContentMixin(object):
super(ContentMixin, self).initialize()
self._request_body = None
self._best_response_match = None
self._logger = getattr(self, 'logger', logger)
def get_response_content_type(self):
"""Figure out what content type will be used in the response."""
@ -260,8 +261,11 @@ class ContentMixin(object):
"""
Fetch (and cache) the request body as a dictionary.
:raise web.HTTPError: if the content type cannot be decoded.
The status code is set to 415 Unsupported Media Type
:raise web.HTTPError:
- if the content type cannot be matched, then the status code
is set to 415 Unsupported Media Type.
- if decoding the content body fails, then the status code is
set to 400 Bad Syntax.
"""
if self._request_body is None:
@ -273,12 +277,16 @@ class ContentMixin(object):
content_type_header.content_subtype])
try:
handler = settings[content_type]
self._request_body = handler.from_bytes(self.request.body)
except KeyError:
raise web.HTTPError(415, 'cannot decode body of type %s',
content_type)
try:
self._request_body = handler.from_bytes(self.request.body)
except Exception:
self._logger.exception('failed to decode request body')
raise web.HTTPError(400, 'failed to decode request')
return self._request_body
def send_response(self, body, set_content_type=True):

View file

@ -121,6 +121,14 @@ class GetRequestBodyTests(testing.AsyncHTTPTestCase):
self.assertEqual(response.code, 200)
self.assertEqual(json.loads(response.body.decode('utf-8')), body)
def test_that_invalid_data_returns_400(self):
response = self.fetch(
'/', method='POST', headers={'Content-Type': 'application/json'},
body=('<?xml version="1.0"?><methodCall><methodName>echo'
'</methodName><params><param><value><str>Hi</str></value>'
'</param></params></methodCall>').encode('utf-8'))
self.assertEqual(response.code, 400)
class JSONTranscoderTests(unittest.TestCase):