Separate cookie headers are not parsed into Request.cookies under HTTP/2
#2916
-
|
I've noticed this issue when debugging a FastAPI application running under Granian, however this does seem to be a problem on the Starlette/FastAPI side. See emmett-framework/granian#539 for the original issue. According to the HTTP/2 and ASGI specs, under HTTP/2 the client is allowed to send multiple cookie headers on a request, and ASGI should include these separate headers in the headers passed to the application; see https://asgi.readthedocs.io/en/latest/specs/www.html#http. Google Chrome, when sending requests over HTTP/2, always seems to send cookies using multiple cookie headers, which is how I discovered this issue. Currently, when trying to access Example import asyncio
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route
from starlette.types import Message, Receive, Scope, Send
def index(request: Request):
print("SCOPE:", request.scope)
print("COOKIES:", request.cookies)
return JSONResponse({"cookies": request.cookies})
app = Starlette(
debug=True,
routes=[Route('/', index)]
)
scope: 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": {}
}
async def send(event: Message):
print("SEND:", event)
async def receive() -> Message:
print("RECEIVE")
return {}
asyncio.run(app(scope, receive, send))Expected Output (All three cookies are parsed out): Actual Output (Only the first cookie is available): Relevant code is here in @property
def cookies(self) -> dict[str, str]:
if not hasattr(self, "_cookies"):
cookies: dict[str, str] = {}
cookie_header = self.headers.get("cookie")
if cookie_header:
cookies = cookie_parser(cookie_header)
self._cookies = cookies
return self._cookiesUnder HTTP/2 we could use |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
|
Also facing this issue. doesnt follow RFC 7540 spec |
Beta Was this translation helpful? Give feedback.
-
|
This was solved. |
Beta Was this translation helpful? Give feedback.
This was solved.