diff options
| author | SaJH <wogur981208@gmail.com> | 2025-08-20 22:54:46 +0900 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-08-21 16:48:54 +0200 |
| commit | f2a6c0477fd95518ffb4fcea8e655a9062874bd2 (patch) | |
| tree | 5ba9079021190354ee5352c60949602e5246d116 | |
| parent | ed7c1a56400d64f109f30df3ce697984cdad7c75 (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.py | 6 | ||||
| -rw-r--r-- | docs/releases/6.0.txt | 3 | ||||
| -rw-r--r-- | tests/asgi/tests.py | 31 |
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"}) |
