From 93803a1b5f4a08eb064b4cc8b3834ff323be4065 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Tue, 8 Mar 2022 17:03:04 +0100 Subject: [PATCH] Fixed #33567 -- Avoided setting default text/html content type on responses. --- django/views/csrf.py | 2 +- django/views/debug.py | 6 +++--- django/views/defaults.py | 7 +------ tests/csrf_tests/tests.py | 1 + tests/httpwrappers/tests.py | 3 +-- tests/responses/test_fileresponse.py | 6 ++++-- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/django/views/csrf.py b/django/views/csrf.py index 2d9616784d..53ca2cb823 100644 --- a/django/views/csrf.py +++ b/django/views/csrf.py @@ -157,4 +157,4 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME): else: # Raise if a developer-specified template doesn't exist. raise - return HttpResponseForbidden(t.render(c), content_type="text/html") + return HttpResponseForbidden(t.render(c)) diff --git a/django/views/debug.py b/django/views/debug.py index e30fd65095..ea06224bf6 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -64,7 +64,7 @@ def technical_500_response(request, exc_type, exc_value, tb, status_code=500): reporter = get_exception_reporter_class(request)(request, exc_type, exc_value, tb) if request.accepts("text/html"): html = reporter.get_traceback_html() - return HttpResponse(html, status=status_code, content_type="text/html") + return HttpResponse(html, status=status_code) else: text = reporter.get_traceback_text() return HttpResponse( @@ -597,7 +597,7 @@ def technical_404_response(request, exception): "raising_view_name": get_caller(request), } ) - return HttpResponseNotFound(t.render(c), content_type="text/html") + return HttpResponseNotFound(t.render(c)) def default_urlconf(request): @@ -610,4 +610,4 @@ def default_urlconf(request): } ) - return HttpResponse(t.render(c), content_type="text/html") + return HttpResponse(t.render(c)) diff --git a/django/views/defaults.py b/django/views/defaults.py index d5f6708788..f10b75d471 100644 --- a/django/views/defaults.py +++ b/django/views/defaults.py @@ -62,7 +62,6 @@ def page_not_found(request, exception, template_name=ERROR_404_TEMPLATE_NAME): try: template = loader.get_template(template_name) body = template.render(context, request) - content_type = None # Django will use 'text/html'. except TemplateDoesNotExist: if template_name != ERROR_404_TEMPLATE_NAME: # Reraise if it's a missing custom template. @@ -77,8 +76,7 @@ def page_not_found(request, exception, template_name=ERROR_404_TEMPLATE_NAME): }, ) body = template.render(Context(context)) - content_type = "text/html" - return HttpResponseNotFound(body, content_type=content_type) + return HttpResponseNotFound(body) @requires_csrf_token @@ -97,7 +95,6 @@ def server_error(request, template_name=ERROR_500_TEMPLATE_NAME): raise return HttpResponseServerError( ERROR_PAGE_TEMPLATE % {"title": "Server Error (500)", "details": ""}, - content_type="text/html", ) return HttpResponseServerError(template.render()) @@ -118,7 +115,6 @@ def bad_request(request, exception, template_name=ERROR_400_TEMPLATE_NAME): raise return HttpResponseBadRequest( ERROR_PAGE_TEMPLATE % {"title": "Bad Request (400)", "details": ""}, - content_type="text/html", ) # No exception content is passed to the template, to not disclose any # sensitive information. @@ -147,7 +143,6 @@ def permission_denied(request, exception, template_name=ERROR_403_TEMPLATE_NAME) raise return HttpResponseForbidden( ERROR_PAGE_TEMPLATE % {"title": "403 Forbidden", "details": ""}, - content_type="text/html", ) return HttpResponseForbidden( template.render(request=request, context={"exception": str(exception)}) diff --git a/tests/csrf_tests/tests.py b/tests/csrf_tests/tests.py index 834a92eecf..6db67c9190 100644 --- a/tests/csrf_tests/tests.py +++ b/tests/csrf_tests/tests.py @@ -375,6 +375,7 @@ class CsrfViewMiddlewareTestMixin(CsrfFunctionTestMixin): with self.assertLogs("django.security.csrf", "WARNING") as cm: resp = mw.process_view(req, post_form_view, (), {}) self.assertEqual(403, resp.status_code) + self.assertEqual(resp["Content-Type"], "text/html; charset=utf-8") self.assertEqual(cm.records[0].getMessage(), "Forbidden (%s): " % expected) def test_csrf_cookie_bad_or_missing_token(self): diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index 7ee20f9ce9..6ab0cc52cb 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -539,7 +539,6 @@ class HttpResponseSubclassesTests(SimpleTestCase): response = HttpResponseRedirect( "/redirected/", content="The resource has temporarily moved", - content_type="text/html", ) self.assertContains( response, "The resource has temporarily moved", status_code=302 @@ -592,7 +591,7 @@ class HttpResponseSubclassesTests(SimpleTestCase): self.assertEqual(response.status_code, 405) # Standard HttpResponse init args can be used response = HttpResponseNotAllowed( - ["GET"], content="Only the GET method is allowed", content_type="text/html" + ["GET"], content="Only the GET method is allowed" ) self.assertContains(response, "Only the GET method is allowed", status_code=405) diff --git a/tests/responses/test_fileresponse.py b/tests/responses/test_fileresponse.py index ebb7876be2..af90b1170d 100644 --- a/tests/responses/test_fileresponse.py +++ b/tests/responses/test_fileresponse.py @@ -101,8 +101,10 @@ class FileResponseTests(SimpleTestCase): self.assertEqual(response.headers["Content-Type"], "video/webm") def test_content_type_buffer_explicit_default(self): - response = FileResponse(io.BytesIO(b"binary content"), content_type="text/html") - self.assertEqual(response.headers["Content-Type"], "text/html") + response = FileResponse( + io.BytesIO(b"binary content"), content_type="text/html; charset=utf-8" + ) + self.assertEqual(response.headers["Content-Type"], "text/html; charset=utf-8") def test_content_type_buffer_named(self): test_tuples = (