Problem
Responder instances are reused across requests on a persistent HTTP connection, but their request-scoped response state is not fully refreshed:
Responder.reset() checks the old self.chunkable value instead of the supplied chunkable argument.
Server.serviceReqs() derives chunkability only when creating a responder, not when reusing one.
Responder.reset() does not clear evented, so a prior text/event-stream response leaves stale response classification behind.
The chunkability defect occurs on ordinary responder reuse; it does not require a prior SSE response. Because reset() is called without a chunkable argument, the existing boolean can be replaced with None on the first reuse.
Production impact
If the next HTTP/1.1 response does not provide Content-Length, HIO no longer adds Transfer-Encoding: chunked. The response is then only close-delimited even though HIO can keep the persistent connection open and admit another request.
A client or intermediary may consequently:
- wait indefinitely for the response boundary;
- time out after receiving the visible body bytes;
- buffer a response whose completion it cannot determine; or
- interpret subsequent response bytes as part of the prior response body.
Applications that always provide Content-Length mask the defect, but HIO cannot require every WSGI response to do so.
The stale evented flag is a secondary state-correctness problem. Current server code does not otherwise consume that flag, so clearing it is primarily preventative hardening for subsequent response and lifecycle handling. It is not the source of the framing failure above.
Expected behavior
For every parsed request, Server.serviceReqs() should derive chunkability from that request's HTTP version and pass it to both responder creation and responder reuse. Responder.reset() should apply the supplied value and clear event-stream state.
A reused responder handling an HTTP/1.1 response without Content-Length must therefore emit Transfer-Encoding: chunked, regardless of the prior response type.
Regression
Use one persistent connection and an existing responder whose prior HTTP/1.1 response was text/event-stream. Admit the next HTTP/1.1 request through Server.serviceReqs() and verify that:
- the same responder is reset with
chunkable = True;
- stale
evented state is cleared; and
- a subsequent response without
Content-Length emits Transfer-Encoding: chunked.
Proposed scope
- Correct the
chunkable argument check in Responder.reset().
- Reset
evented for the next response.
- Pass the current request's derived chunkability through the responder-reuse path.
- Add the focused responder-reuse regression above.
This issue intentionally excludes producer-abort cleanup, parser EOF semantics, transport draining, and TLS shutdown. It is a generic HIO bug and is independently upstreamable.
Problem
Responderinstances are reused across requests on a persistent HTTP connection, but their request-scoped response state is not fully refreshed:Responder.reset()checks the oldself.chunkablevalue instead of the suppliedchunkableargument.Server.serviceReqs()derives chunkability only when creating a responder, not when reusing one.Responder.reset()does not clearevented, so a priortext/event-streamresponse leaves stale response classification behind.The chunkability defect occurs on ordinary responder reuse; it does not require a prior SSE response. Because
reset()is called without achunkableargument, the existing boolean can be replaced withNoneon the first reuse.Production impact
If the next HTTP/1.1 response does not provide
Content-Length, HIO no longer addsTransfer-Encoding: chunked. The response is then only close-delimited even though HIO can keep the persistent connection open and admit another request.A client or intermediary may consequently:
Applications that always provide
Content-Lengthmask the defect, but HIO cannot require every WSGI response to do so.The stale
eventedflag is a secondary state-correctness problem. Current server code does not otherwise consume that flag, so clearing it is primarily preventative hardening for subsequent response and lifecycle handling. It is not the source of the framing failure above.Expected behavior
For every parsed request,
Server.serviceReqs()should derive chunkability from that request's HTTP version and pass it to both responder creation and responder reuse.Responder.reset()should apply the supplied value and clear event-stream state.A reused responder handling an HTTP/1.1 response without
Content-Lengthmust therefore emitTransfer-Encoding: chunked, regardless of the prior response type.Regression
Use one persistent connection and an existing responder whose prior HTTP/1.1 response was
text/event-stream. Admit the next HTTP/1.1 request throughServer.serviceReqs()and verify that:chunkable = True;eventedstate is cleared; andContent-LengthemitsTransfer-Encoding: chunked.Proposed scope
chunkableargument check inResponder.reset().eventedfor the next response.This issue intentionally excludes producer-abort cleanup, parser EOF semantics, transport draining, and TLS shutdown. It is a generic HIO bug and is independently upstreamable.