summaryrefslogtreecommitdiff
path: root/django/http
diff options
context:
space:
mode:
authorKeryn Knight <keryn@kerynknight.com>2022-02-09 16:01:03 +0000
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-03-02 20:23:39 +0100
commit51f896fe25d0593abad2b3c55fd510c46ef57f05 (patch)
tree80718fd8f7f862689b065b11db4730e318356d44 /django/http
parente0b197c63c7e11352305bc9d8a408309e67dcea6 (diff)
Refs #33546 -- Optimized ResponseHeaders._convert_to_charset() by reducing the type-checking duplication.
In the common case, where keys and values are be encoded into ascii/latin-1, defer the checking for newlines until it's been successfully coerced to a string. Co-authored-by: Nick Pope <nick@nickpope.me.uk>
Diffstat (limited to 'django/http')
-rw-r--r--django/http/response.py28
1 files changed, 19 insertions, 9 deletions
diff --git a/django/http/response.py b/django/http/response.py
index fb379f98a7..fae91b3f05 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -43,22 +43,32 @@ class ResponseHeaders(CaseInsensitiveMapping):
`charset` must be 'ascii' or 'latin-1'. If `mime_encode` is True and
`value` can't be represented in the given charset, apply MIME-encoding.
"""
- if not isinstance(value, (bytes, str)):
- value = str(value)
- if (isinstance(value, bytes) and (b"\n" in value or b"\r" in value)) or (
- isinstance(value, str) and ("\n" in value or "\r" in value)
- ):
- raise BadHeaderError(
- "Header values can't contain newlines (got %r)" % value
- )
try:
if isinstance(value, str):
# Ensure string is valid in given charset
value.encode(charset)
- else:
+ elif isinstance(value, bytes):
# Convert bytestring using given charset
value = value.decode(charset)
+ else:
+ value = str(value)
+ # Ensure string is valid in given charset.
+ value.encode(charset)
+ if "\n" in value or "\r" in value:
+ raise BadHeaderError(
+ f"Header values can't contain newlines (got {value!r})"
+ )
except UnicodeError as e:
+ # Encoding to a string of the specified charset failed, but we
+ # don't know what type that value was, or if it contains newlines,
+ # which we may need to check for before sending it to be
+ # encoded for multiple character sets.
+ if (isinstance(value, bytes) and (b"\n" in value or b"\r" in value)) or (
+ isinstance(value, str) and ("\n" in value or "\r" in value)
+ ):
+ raise BadHeaderError(
+ f"Header values can't contain newlines (got {value!r})"
+ ) from e
if mime_encode:
value = Header(value, "utf-8", maxlinelen=sys.maxsize).encode()
else: