Commit 36918b2
committed
fix(http): don't reset shared req/resp while async response is in flight (#424)
HttpHandler::Reset() reuses the same HttpRequest/HttpResponse objects. On a
keep-alive connection, if a new request arrives while an async handler on a
worker thread is still producing/sending the previous response, FeedRecvData
called Reset() unconditionally -- racing the worker's use of resp/writer and
risking a crash (reported in #424; also reachable via HTTP pipelining or a
malicious peer).
Guard it: when a new request arrives and the handler isn't back at WANT_RECV,
only Reset() if the response has already been handed off
(writer->end == SEND_END). If the async response is still in flight, reject
the early/pipelined data (ERR_REQUEST) so the connection is closed instead of
corrupting the in-use objects.
The completion signal is the writer's end state, not HttpHandler::state: an
async writer writes straight to the socket and never advances the handler's
send-state machine, so HttpHandler::state stays HANDLE_CONTINUE.
Verified: sync and async keep-alive connection reuse both work (single
connection, no spurious close); the pipeline-during-async case is rejected
without crashing and the server keeps serving; make check passes (~658k
keep-alive reqs OK). Alternative to #814 that keeps req/resp reuse instead of
reallocating per request.1 parent 1965221 commit 36918b2
1 file changed
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
777 | 777 | | |
778 | 778 | | |
779 | 779 | | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
780 | 792 | | |
781 | 793 | | |
782 | 794 | | |
| |||
0 commit comments