Skip to content

Commit

Permalink
Improve accept header handling for unknown types (#222)
Browse files Browse the repository at this point in the history
Add 406 response for if the requested content type is not supported.
Add more tests to verify correct content type negotiation.
  • Loading branch information
ashokdelphia authored and codingjoe committed May 27, 2019
1 parent c09c265 commit 194746b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
9 changes: 6 additions & 3 deletions health_check/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re
from concurrent.futures import ThreadPoolExecutor

from django.http import JsonResponse
from django.http import HttpResponse, JsonResponse
from django.views.decorators.cache import never_cache
from django.views.generic import TemplateView

Expand Down Expand Up @@ -126,8 +126,11 @@ def _run(plugin):
return self.render_to_response(context, status=status_code)
elif media.mime_type in ('application/json', 'application/*'):
return self.render_to_response_json(plugins, status_code)
else:
return self.render_to_response(context, status=status_code)
return HttpResponse(
'Not Acceptable: Supported content types: text/html, application/json',
status=406,
content_type='text/plain'
)

def render_to_response_json(self, plugins, status):
return JsonResponse(
Expand Down
31 changes: 30 additions & 1 deletion tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ def run_check(self):
plugin_dir.register(JSONSuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='application/json')
assert response['content-type'] == 'application/json'
assert response.status_code == 200

def test_success_prefer_json(self, client):
class JSONSuccessBackend(BaseHealthCheckBackend):
def run_check(self):
pass

plugin_dir.reset()
plugin_dir.register(JSONSuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='application/json; q=0.8, text/html; q=0.5')
assert response['content-type'] == 'application/json'
assert response.status_code == 200

def test_success_accept_xhtml(self, client):
class SuccessBackend(BaseHealthCheckBackend):
Expand All @@ -148,6 +160,7 @@ def run_check(self):
plugin_dir.register(SuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='application/xhtml+xml')
assert response['content-type'] == 'text/html; charset=utf-8'
assert response.status_code == 200

def test_success_unsupported_accept(self, client):
class SuccessBackend(BaseHealthCheckBackend):
Expand All @@ -157,7 +170,20 @@ def run_check(self):
plugin_dir.reset()
plugin_dir.register(SuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='application/octet-stream')
assert response['content-type'] == 'text/html; charset=utf-8'
assert response['content-type'] == 'text/plain'
assert response.status_code == 406
assert response.content == b'Not Acceptable: Supported content types: text/html, application/json'

def test_success_unsupported_and_supported_accept(self, client):
class SuccessBackend(BaseHealthCheckBackend):
def run_check(self):
pass

plugin_dir.reset()
plugin_dir.register(SuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='application/octet-stream, application/json; q=0.9')
assert response['content-type'] == 'application/json'
assert response.status_code == 200

def test_success_accept_order(self, client):
class JSONSuccessBackend(BaseHealthCheckBackend):
Expand All @@ -171,6 +197,7 @@ def run_check(self):
HTTP_ACCEPT='text/html, application/xhtml+xml, application/json; q=0.9, */*; q=0.1'
)
assert response['content-type'] == 'text/html; charset=utf-8'
assert response.status_code == 200

def test_success_accept_order__reverse(self, client):
class JSONSuccessBackend(BaseHealthCheckBackend):
Expand All @@ -181,6 +208,7 @@ def run_check(self):
plugin_dir.register(JSONSuccessBackend)
response = client.get(self.url, HTTP_ACCEPT='text/html; q=0.1, application/xhtml+xml; q=0.1, application/json')
assert response['content-type'] == 'application/json'
assert response.status_code == 200

def test_format_override(self, client):
class JSONSuccessBackend(BaseHealthCheckBackend):
Expand All @@ -191,6 +219,7 @@ def run_check(self):
plugin_dir.register(JSONSuccessBackend)
response = client.get(self.url + '?format=json', HTTP_ACCEPT='text/html')
assert response['content-type'] == 'application/json'
assert response.status_code == 200

def test_format_no_accept_header(self, client):
class JSONSuccessBackend(BaseHealthCheckBackend):
Expand Down

0 comments on commit 194746b

Please sign in to comment.