[Django] #36399: Missing cookies when using ASGI and HTTP/2

40 views
Skip to first unread message

Django

unread,
May 15, 2025, 10:45:04 AM5/15/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
------------------------------+-----------------------------------------
Reporter: Ingmar Stein | Type: Bug
Status: new | Component: HTTP handling
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------+-----------------------------------------
I originally created the report here: https://forum.djangoproject.com/t
/missing-cookies-when-using-asgi-and-http-2/40946

https://github.com/paperless-ngx/paperless-ngx/issues/9935 describes the
issue in more detail. In a nutshell: when serving a Django app using ASGI
and HTTP/2, cookies may get dropped. In case this hits the `csrftoken`
cookie, it might explain the various "CSRF verification failed" topics in
this forum category.

I had a brief look at the coke and it looks like the
[[https://github.com/django/django/blob/main/django/core/handlers/asgi.py#L97-L98|ASGI
module]] joins multiple values for the same header using commas but
[[https://github.com/django/django/blob/main/django/http/cookie.py#L12|`parse_cookie`]]
splits by semicolon.

Same same issue has also hit other ASGI frameworks:
https://github.com/encode/starlette/discussions/2916

@carltongibson created this minimal repro:

{{{#!python
from django.conf import settings
from django.core.handlers.asgi import ASGIRequest

settings.configure(DEBUG=True)

scope = {
"type": "http",
"asgi": {
"version": "3.0",
"spec_version": "2.3",
},
"http_version": "2.0",
"method": "GET",
"scheme": "http",
"path": "/",
"raw_path": b"/",
"query_string": b"",
"root_path": "",
"headers": [
(b"cookie", b"a=abc;"),
(b"cookie", b"b=def;"),
(b"cookie", b"c=ghi;")
],
"client": ("127.0.0.1", 10000),
"server": ("127.0.0.1", 8000),
"extensions": {}
}

request = ASGIRequest(scope, None)

print(request.COOKIES) # Prints: {'a': 'abc', ',b': 'def', ',c': 'ghi'}
assert request.COOKIES == {'a': 'abc', 'b': 'def', 'c': 'ghi'}
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36399>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 15, 2025, 10:51:12 AM5/15/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+------------------------------------
Reporter: Ingmar Stein | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Sarah Boyce):

* cc: Carlton Gibson (added)
* stage: Unreviewed => Accepted

Comment:

Thank you, replicated
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:1>

Django

unread,
May 15, 2025, 10:52:02 AM5/15/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+------------------------------------
Reporter: Ingmar Stein | Owner: (none)
Type: New feature | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Carlton Gibson):

* cc: Carlton Gibson (removed)
* easy: 0 => 1
* type: Bug => New feature

Comment:

Yes, I confirm this.

`ASGIRequest` will need to special case the cookie header in a similar way
to how it handles content-length &co before entering the _generic headers_
loop.
Multiple cookie values need to be joined with semicolons — which are
already present terminating the value — not commas.

Looks like HTTP/1 didn't allow multiple Cookie headers, and they had to be
automatically grouped by the client, where HTTP/2 does allow this.

Since this has never been supported I'll mark it a new feature: it
probably merits a line in the release notes.
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:2>

Django

unread,
May 15, 2025, 10:52:14 AM5/15/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+------------------------------------
Reporter: Ingmar Stein | Owner: (none)
Type: New feature | Status: new
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Carlton Gibson):

* cc: Carlton Gibson (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:3>

Django

unread,
May 15, 2025, 1:17:19 PM5/15/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by JaeHyuckSa):

* owner: (none) => JaeHyuckSa
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:4>

Django

unread,
May 16, 2025, 8:06:49 AM5/16/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by JaeHyuckSa):

* has_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:5>

Django

unread,
May 16, 2025, 8:15:19 AM5/16/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Carlton Gibson):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:6>

Django

unread,
May 16, 2025, 9:08:24 AM5/16/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by JaeHyuckSa):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:7>

Django

unread,
May 16, 2025, 9:15:05 AM5/16/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:8>

Django

unread,
May 16, 2025, 9:47:45 AM5/16/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Ingmar Stein):

This is a fantastic turnaround time! Well done and thank you :)
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:9>

Django

unread,
May 19, 2025, 2:20:06 AM5/19/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Ingmar Stein):

Would you consider cherry-picking this into the 5.x branch as well?
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:10>

Django

unread,
May 19, 2025, 3:57:35 AM5/19/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Carlton Gibson):

This doesn't qualify for a backport but you can easily do yourself by
adjusting your `asgi.py` file.

Something like...


{{{
# asgi.py

import os

# Restore when removing ASGIRequest backport.
# from django.core.asgi import get_asgi_application

# Imports for Backport
import django
from django.core.handlers.asgi import ASGIHandler

# https://code.djangoproject.com/ticket/36399
assert django.VERSION < (6,0), "Remove ASGIRequest backport."

# Inline ASGIRequest here.
# You can copy/paste the whole class or just override __init__. Up to you.

# Subclass ASGIHandler to use your request class.
class BackportASGIHandler(ASGIHandler):
request_class = # Your backported request class.

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_app.settings")

# Restore when removing ASGIRequest backport.
# application = get_asgi_application()

django.setup(set_prefix=False)

application = BackportASGIHandler()

}}}

That's just a sketch. Adjust to your needs.
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:11>

Django

unread,
May 19, 2025, 4:33:12 AM5/19/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Sarah Boyce):

* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:12>

Django

unread,
Jul 17, 2025, 1:57:43 AM7/17/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Ahmed Ibrahim):

* cc: Ahmed Ibrahim (added)

Comment:

any news?
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:13>

Django

unread,
Jul 17, 2025, 2:05:15 AM7/17/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Carlton Gibson):

@Ahmed, please don’t spam the issue tracker. If there were updates they
would already be visible here.
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:14>

Django

unread,
Aug 18, 2025, 9:30:12 AM8/18/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Carlton Gibson):

* needs_better_patch: 1 => 0

Comment:

Author just updated the PR. Unchecking PNI to get it another review.
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:15>

Django

unread,
Aug 18, 2025, 9:32:07 AM8/18/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by JaeHyuckSa):

Replying to [comment:15 Carlton Gibson]:
> Author just updated the PR. Unchecking PNI to get it another review.

I was about to update the ticket, but saw it was already resolved — I’m
honestly amazed at your speed!
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:16>

Django

unread,
Aug 20, 2025, 4:01:04 AM8/20/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Sarah Boyce):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:17>

Django

unread,
Aug 20, 2025, 10:01:57 AM8/20/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------+--------------------------------------
Reporter: Ingmar Stein | Owner: JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by JaeHyuckSa):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:18>

Django

unread,
Aug 20, 2025, 10:53:50 AM8/20/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: assigned
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:19>

Django

unread,
Aug 21, 2025, 10:49:04 AM8/21/25
to django-...@googlegroups.com
#36399: Missing cookies when using ASGI and HTTP/2
-------------------------------------+-------------------------------------
Reporter: Ingmar Stein | Owner:
| JaeHyuckSa
Type: New feature | Status: closed
Component: HTTP handling | Version: 5.2
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce <42296566+sarahboyce@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"f2a6c0477fd95518ffb4fcea8e655a9062874bd2" f2a6c04]:
{{{#!CommitTicketReference repository=""
revision="f2a6c0477fd95518ffb4fcea8e655a9062874bd2"
Fixed #36399 -- Added support for multiple Cookie headers in HTTP/2 for
ASGIRequest.

Signed-off-by: SaJH <wogur...@gmail.com>
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36399#comment:20>
Reply all
Reply to author
Forward
0 new messages