- 
                Notifications
    You must be signed in to change notification settings 
- Fork 129
Open
Description
The scope["state"] is sometimes shared between requests, leading to odd behaviour.
import httpx  # type: ignore
import trio
from trio.testing import wait_all_tasks_blocked
import hypercorn.trio
from hypercorn.config import Config
async def app(scope, receive, send):
    assert scope["type"] == "http"
    await send(
        {
            "type": "http.response.start",
            "status": 200,
            "headers": [[b"content-type", b"text/plain"]],
        }
    )
    await send({"type": "http.response.body", "body": scope["state"].get("key", b"")})
    scope["state"]["key"] = b"one"
async def main():
    config = Config()
    config.bind = ["0.0.0.0:1234"]
    config.accesslog = "-"  # Log to stdout/err
    config.errorlog = "-"
    async with trio.open_nursery() as nursery:
        shutdown = trio.Event()
        async def serve() -> None:
            await hypercorn.trio.serve(app, config, shutdown_trigger=shutdown.wait)
        nursery.start_soon(serve)
        await wait_all_tasks_blocked()
        client = httpx.AsyncClient()
        result = await client.get("http://0.0.0.0:1234/")
        assert result.content == b""
        result = await client.get("http://0.0.0.0:1234/")
        assert result.content == b""
        shutdown.set()
trio.run(main)The root cause of this is that hypercorn copies the server state once per connection instead of per request:
| ConnectionState(self.state.copy()), | 
According to the spec, scope["state"] should be
A copy of the namespace passed into the lifespan corresponding to this request
Uvicorn had a similar issue a while ago: Kludex/uvicorn#1902.
Metadata
Metadata
Assignees
Labels
No labels