The connection owns the state
A TCP read does not necessarily contain one HTTP request. It might contain half a body, or a body followed by the next request. Each connection keeps its parser, input buffer, deadline, and outgoing response alive across asynchronous operations. Unconsumed bytes stay in that buffer for the next request.
I use a strand to serialize each session's handlers across the I/O workers. One response finishes writing before the next request is dispatched on that connection. That preserves pipeline order without adding an unbounded response queue.
One connection, from bytes to response.
Beast parses the request in stages. Header and body limits bound each request; a persistent buffer keeps bytes already read for the next one.
Inspect the implementationLimits belong in the request path
Header and body limits constrain parsing. Connection admission, per-operation deadlines, and a request cap constrain how long a client can keep resources. The header is validated before the body is read; Expect: 100-continue has its own explicit step.
Static files are opened relative to a trusted directory descriptor, rejecting symlinks along the path. File identity and metadata are checked before a cache hit. The cache avoids repeated body reads; it does not bypass the document-root boundary.
What I chose to keep simple
Beast handles wire parsing and serialization. That leaves the project focused on session lifetime, routing, resource limits, and the way those pieces interact. Configured routes are immutable after startup; the file cache has both entry and logical-byte limits.
Socket I/O is asynchronous, but file reads and log writes still run synchronously inside handlers and can delay a worker. Shutdown stops network work without draining every response. TLS and HTTP/2 are outside the current implementation.
Checking the observable behavior
The socket integration tests send fragmented bodies, coalesced requests, chunked input, ambiguous framing, and slow clients. They check response ordering, HEAD behavior, deadlines, connection limits, and recovery after rejection.
The repository includes a performance measurement plan. Its historical smoke tests are too short to support a current throughput claim, so I do not use them as a benchmark here.