Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion django/http/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
_charset_from_content_type_re = _lazy_re_compile(
r";\s*charset=(?P<charset>[^\s;]+)", re.I
)
_control_chars_re = _lazy_re_compile(r"[\x00-\x1f\x7f-\x9f]")


class ResponseHeaders(CaseInsensitiveMapping):
Expand Down Expand Up @@ -142,7 +143,7 @@ def __init__(

if not 100 <= self.status_code <= 599:
raise ValueError("HTTP status code must be an integer from 100 to 599.")
self._reason_phrase = reason
self.reason_phrase = reason

@property
def reason_phrase(self):
Expand All @@ -154,6 +155,8 @@ def reason_phrase(self):

@reason_phrase.setter
def reason_phrase(self, value):
if value and _control_chars_re.search(value):
raise BadHeaderError("reason_phrase can't contain control characters.")
self._reason_phrase = value

@property
Expand Down
16 changes: 15 additions & 1 deletion tests/responses/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.conf import settings
from django.core.cache import cache
from django.http import HttpResponse
from django.http import BadHeaderError, HttpResponse
from django.http.response import HttpResponseBase
from django.test import SimpleTestCase

Expand Down Expand Up @@ -103,6 +103,20 @@ def test_reason_phrase(self):
self.assertEqual(resp.status_code, 419)
self.assertEqual(resp.reason_phrase, reason)

def test_invalid_reason_phrase(self):
msg = "reason_phrase can't contain control characters."
invalid_reasons = [
"OK\r\nX-Injected-header: yes",
"OK\x00",
"OK\x1f",
"OK\x7f",
"OK\x9f",
]
for reason in invalid_reasons:
with self.subTest(reason=reason):
with self.assertRaisesMessage(BadHeaderError, msg):
HttpResponse(reason=reason)

def test_charset_detection(self):
"""HttpResponse should parse charset from content_type."""
response = HttpResponse("ok")
Expand Down
Loading