summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaJH <wogur981208@gmail.com>2025-08-20 22:54:46 +0900
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-08-21 16:48:54 +0200
commitf2a6c0477fd95518ffb4fcea8e655a9062874bd2 (patch)
tree5ba9079021190354ee5352c60949602e5246d116
parented7c1a56400d64f109f30df3ce697984cdad7c75 (diff)
Fixed #36399 -- Added support for multiple Cookie headers in HTTP/2 for ASGIRequest.
Signed-off-by: SaJH <wogur981208@gmail.com>
-rw-r--r--django/core/handlers/asgi.py6
-rw-r--r--docs/releases/6.0.txt3
-rw-r--r--tests/asgi/tests.py31
3 files changed, 38 insertions, 2 deletions
diff --git a/django/core/handlers/asgi.py b/django/core/handlers/asgi.py
index beace7597c..b4056ca042 100644
--- a/django/core/handlers/asgi.py
+++ b/django/core/handlers/asgi.py
@@ -94,7 +94,11 @@ class ASGIRequest(HttpRequest):
# HTTP/2 say only ASCII chars are allowed in headers, but decode
# latin1 just in case.
value = value.decode("latin1")
- if corrected_name in self.META:
+ if corrected_name == "HTTP_COOKIE":
+ value = value.rstrip("; ")
+ if "HTTP_COOKIE" in self.META:
+ value = self.META[corrected_name] + "; " + value
+ elif corrected_name in self.META:
value = self.META[corrected_name] + "," + value
self.META[corrected_name] = value
# Pull out request encoding, if provided.
diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt
index 3e250706ec..e54b9788ce 100644
--- a/docs/releases/6.0.txt
+++ b/docs/releases/6.0.txt
@@ -333,7 +333,8 @@ Pagination
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~
-* ...
+* Multiple ``Cookie`` headers are now supported for HTTP/2 requests when
+ running with ASGI.
Security
~~~~~~~~
diff --git a/tests/asgi/tests.py b/tests/asgi/tests.py
index d3cc09cc50..bb1020dd47 100644
--- a/tests/asgi/tests.py
+++ b/tests/asgi/tests.py
@@ -732,3 +732,34 @@ class ASGITest(SimpleTestCase):
await handler.read_body(receive_rolled)
# The second write should have rolled over to disk.
self.assertTrue(any(t != loop_thread for t in called_threads))
+
+ def test_multiple_cookie_headers_http2(self):
+ test_cases = [
+ {
+ "label": "RFC-compliant headers (no semicolon)",
+ "headers": [
+ (b"cookie", b"a=abc"),
+ (b"cookie", b"b=def"),
+ (b"cookie", b"c=ghi"),
+ ],
+ },
+ {
+ # Some clients may send cookies with trailing semicolons.
+ "label": "Headers with trailing semicolons",
+ "headers": [
+ (b"cookie", b"a=abc;"),
+ (b"cookie", b"b=def;"),
+ (b"cookie", b"c=ghi;"),
+ ],
+ },
+ ]
+
+ for case in test_cases:
+ with self.subTest(case["label"]):
+ scope = self.async_request_factory._base_scope(
+ path="/", http_version="2.0"
+ )
+ scope["headers"] = case["headers"]
+ request = ASGIRequest(scope, None)
+ self.assertEqual(request.META["HTTP_COOKIE"], "a=abc; b=def; c=ghi")
+ self.assertEqual(request.COOKIES, {"a": "abc", "b": "def", "c": "ghi"})