falconry / falconry/falcon

ASGI resp.stream is iterated until completion despite client disconnect

Open
#2,015 5 comments 0 reactions 1 assignee Claimed by @vytas7 View on GitHub
enhancement in progress needs contributor needs-decision proposal
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.