ASGI resp.stream is iterated until completion despite client disconnect
- Dominant language
- Python
- Stars
- 9.8k
- Forks
- 1k
- Avg merge
- 5d 13h
- Merged PRs (30d)
- 7
Description
At the time of writing, setting [`resp.stream`](https://falcon.readthedocs.io/en/stable/api/request_and_response_asgi.html#falcon.asgi.Response.stream) to an async generator results in it being iterated by the framework until completion (or, obviously, until an exception is raised) regardless whether the client has already disconnected. The SSE code path already has a mechanism to poll and detect the `http.disconnect` ASGI message.
This issue intersects with #1808, however this one proposes that the framework should detect the disconnect event and stop iteration itself, as it is done for the SSE case. Maybe both cases could be generalized that setting `resp.sse` would simply set the `Content-Type` and `resp.stream`, and further streaming would use the same logic?
If implemented, this behaviour would probably interfere with "true" full-duplex HTTP streaming, i.e., where the request's body is being streamed to the server, while the server is streaming response simultaneously. I've tried skimming through [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616), however it is not crystal clear whether this is allowed or not. The RFC just states it's forbidden for the client to continue streaming if it has received an error response.
Some people claim it is possible, see, e.g., [Does HTTP 1.1 Support Full Duplex Communication?](https://blog.schroederspace.com/tumbleweed-technology/does-http-1-1-support-full-duplex-communication) Obviously, not all clients and servers supports this. For instance, the popular Uvicorn [states](https://www.uvicorn.org/server-behavior/#response-completion) that:
> Once a response has been sent, Uvicorn will no longer buffer any remaining request body. Any later calls to `receive` will return an `http.disconnect` message.
However, theoretically other ASGI servers might still choose to support this scenario... Is it maybe possible to detect this somehow (that `receive()` is still returning data after `send()` and buffer a couple of messages :thinking:)?
https://github.com/falconry/falcon/issues/1956 might also be loosely related.
Contributor guide
Assessment
This issue has not been assessed yet.