[HTTP]ServerThe server: bind in init (so port works before start, including after an ephemeral ':0'), accept in a background Task, one Task per connection running the keep-alive loop. Termination is the caller's: stop cancels the accept loop (in-flight connections keep running), join drains them, close releases the port.
One frame of a chunked body (pure): hex size, CRLF, data, CRLF. The caller must not frame empty data — a zero-size chunk is the terminator.
Lowercase hex digits of a non-negative Integer (chunk-size lines).
RFC-1123 date (e.g. 'Sun, 06 Nov 1994 08:49:37 GMT') for a UTC DateTime.
A whole non-streaming response as one buffer: head + materialized body.
Serialize a response head (status line + headers + framing + blank line) — a pure function apart from the Date header, unit-testable without a socket. streaming selects Transfer-Encoding: chunked over Content-Length framing of the materialized body (nil = empty). connection is the Connection header value to emit, or nil for none (the HTTP/1.1 keep-alive default needs no header). Caller-set Date / Content-Length / Connection headers always win over ours.
Release the listening socket / bound port.
Connection-task registry size (finished tasks are swept on each accept, so a long-lived server stays bounded by its concurrency, not its history).
A bare status-only response for transport-level errors.
Internal: apply the limit defaults and bind the listener — the port is held from construction on, before start.
Wait for the in-flight connection tasks to finish.
The bound local port (e.g. after an ephemeral ':0' bind).
Read one request head through the blank line, enforcing maxHeadBytes -> [HTTP]HeadTooLarge (431). Returns the raw head bytes; empty or partial at EOF parses to a quiet close or a 400 upstream.
Over maxConnections: tell the peer we are saturated, then close.
Write resp; returns whether the write succeeded (a false means the peer is gone and the caller should close — there is nobody left to tell). A Generator body streams as chunked transfer-encoding, one frame per (non-empty) yield — this is what makes SSE work; anything else goes out as one buffer framed by Content-Length. suppress (HEAD) sends the entity headers but no body bytes.
One connection: run request/response exchanges until one of them decides to close (Connection: close, HTTP/1.0 default, an error path, EOF, or the idle timeout), then release the socket.
One request/response exchange. Returns true to keep the connection open for the next request, false to close. Error responses on this transport level (400/408/413/431/500) always close.
Begin accepting in the background and return immediately. The accept loop runs as its own Task so stop can cancel it — including a parked accept.
Stop accepting: cancel the accept loop, which aborts its parked accept. In-flight connection tasks keep running — drain them with join.