- http/parse.wo: bounded-read buffering to the header terminator, then
exactly Content-Length body bytes; %XX decoding ('+' = space in query
strings only, malformed escapes pass through — parsing stays total);
path/query split with decoded pairs; header names lowercased; the
three-state Parsed record (closed / malformed / request) with keep-alive
carry-over — bytes past this request belong to the next one on the
connection.
- http/serve.wo: Dispatcher interface (the router's seam), status/reason
serialization with computed Content-Length, and the blocking loop:
malformed -> 400 + close; a trapping handler -> 500 AND the loop lives;
fds closed on every path; env.stopping() honored.
- Connection policy discovered by probing, not assumed: a parked keep-alive
connection BLOCKS accept on a single-threaded server (probe: client 1
idles open, client 2 starves). Policy: serve PIPELINED requests on one
connection (carry non-empty), close when the client would idle; a proxy
reconnects. README states it.
Verified against a throwaway echo app (not committed): %20 query decode;
two pipelined requests -> two responses on one connection; DIV0 handler ->
500 and the NEXT connection served; GARBAGE -> 400; SIGTERM stops clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>