mirror of
https://github.com/sprockets/sprockets.mixins.mediatype.git
synced 2024-12-27 11:17:30 +00:00
Return 406 Not Acceptable appropriately.
If there is no default content type and nothing matches in the Accept header, previous versions would fail with an Internal Server Error because of an unhandled exception. Instead we should be returning a "406 Not Acceptable".
This commit is contained in:
parent
25ba46e960
commit
4dd46eda5b
3 changed files with 32 additions and 3 deletions
|
@ -4,6 +4,8 @@ Version History
|
|||
:compare:`Next <3.0.4...master>`
|
||||
--------------------------------
|
||||
- Add type annotations (see :ref:`type-info`)
|
||||
- Return a "406 Not Acceptable" if the :http:header:`Accept` header values cannot be matched
|
||||
and there is no default content type configured
|
||||
|
||||
:compare:`3.0.4 <3.0.3...3.0.4>` (2 Nov 2020)
|
||||
---------------------------------------------
|
||||
|
|
|
@ -391,8 +391,14 @@ class ContentMixin(web.RequestHandler):
|
|||
|
||||
"""
|
||||
settings = get_settings(self.application, force_instance=True)
|
||||
# TODO -- account for get_response_type returning None
|
||||
handler = settings[self.get_response_content_type()] # type: ignore
|
||||
response_type = self.get_response_content_type()
|
||||
if response_type is None:
|
||||
self._logger.error('failed to find a suitable response '
|
||||
'content type for request')
|
||||
self._logger.error('please set a default content type')
|
||||
raise web.HTTPError(406)
|
||||
|
||||
handler = settings[response_type]
|
||||
content_type, data_bytes = handler.to_bytes(body)
|
||||
if set_content_type:
|
||||
self.set_header('Content-Type', content_type)
|
||||
|
|
23
tests.py
23
tests.py
|
@ -61,8 +61,13 @@ def pack_bytes(payload):
|
|||
|
||||
|
||||
class SendResponseTests(testing.AsyncHTTPTestCase):
|
||||
def setUp(self):
|
||||
self.application = None
|
||||
super().setUp()
|
||||
|
||||
def get_app(self):
|
||||
return examples.make_application()
|
||||
self.application = examples.make_application()
|
||||
return self.application
|
||||
|
||||
def test_that_content_type_default_works(self):
|
||||
response = self.fetch('/',
|
||||
|
@ -129,6 +134,22 @@ class SendResponseTests(testing.AsyncHTTPTestCase):
|
|||
self.assertEqual(response.code, 200)
|
||||
self.assertEqual(response.headers['Content-Type'], 'expected/content')
|
||||
|
||||
def test_that_no_default_content_type_will_406(self):
|
||||
# NB if the Accept header is omitted, then a default of `*/*` will
|
||||
# be used which results in a match against any registered handler.
|
||||
# Using an accept header forces the "no match" case.
|
||||
settings = content.get_settings(self.application, force_instance=True)
|
||||
settings.default_content_type = None
|
||||
settings.default_encoding = None
|
||||
response = self.fetch('/',
|
||||
method='POST',
|
||||
body='{}',
|
||||
headers={
|
||||
'Accept': 'application/xml',
|
||||
'Content-Type': 'application/json',
|
||||
})
|
||||
self.assertEqual(response.code, 406)
|
||||
|
||||
|
||||
class GetRequestBodyTests(testing.AsyncHTTPTestCase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in a new issue