Skip to content

fix: announce Connection: close from the ASGI worker - #3726

Open
dylanpulver wants to merge 1 commit into
benoitc:masterfrom
dylanpulver:fix/asgi-announce-connection-close
Open

fix: announce Connection: close from the ASGI worker#3726
dylanpulver wants to merge 1 commit into
benoitc:masterfrom
dylanpulver:fix/asgi-announce-connection-close

Conversation

@dylanpulver

Copy link
Copy Markdown

The ASGI worker decides not to reuse a connection and then closes it without sending a Connection header. RFC 9112 §9.6 requires a server that will not reuse a connection to say so, and the sync WSGI worker already does, in Response.default_headers().

Measured against that sibling, one server each, raw socket:

case WSGI ASGI before after
client sent Connection: close announces closes silently announces
--keep-alive 0 announces closes silently announces
keep-alive default stays open stays open stays open

A client seeing an HTTP/1.1 response with no Connection header treats it as persistent (§9.3) and reuses a socket the server already closed. Also reached by worker shutdown and by a uWSGI response delimited by EOF.

_send_response_start() and the keepalive return of _handle_http_request() now read one predicate, _will_close(), so the announced framing cannot drift from the framing used. An app-supplied Connection header is left alone.

Verification, same env each run:

  • full suite 2044 passed / 535 skipped, before and after, identical
  • mutant A (revert protocol.py, keep tests) → 8/8 new tests fail, 0 pre-existing
  • mutant B (close=request.should_close()) passes all 2044 — it covers only the client-requested case; live it still closes unannounced under --keep-alive 0. Hence the shared predicate rather than a second derivation.

pylint 3.3.2 10.00/10 and pycodestyle clean.

The ASGI worker decides not to reuse a connection (client sent
Connection: close, --keep-alive 0, worker shutting down, or a uWSGI
response delimited by EOF) and then closes it without ever sending a
Connection header. RFC 9112 section 9.6 requires a server that will not
reuse a connection to say so, and the sync WSGI worker already does it
in Response.default_headers().

Extract the keepalive decision into _will_close() so the header emitted
by _send_response_start() and the reuse decision returned by
_handle_http_request() come from one predicate and cannot drift. An
app-supplied Connection header is left alone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant