Skip to content

Commit 35ffbab

Browse files
quaesitor-scientiamRichard Wheelerclaude
authored
net.http: add server-side HTTP/2 (ALPN + h2 frame demux) (#27382)
* net.http: add server-side HTTP/2 (ALPN + h2 frame demux) Build on TLS termination (#27373) to let net.http.Server speak HTTP/2. - New `enable_http2` field on Server. When set on a TLS listener, the listener advertises ALPN `h2, http/1.1`. After the handshake, the TLS worker checks `negotiated_alpn()`: if `h2`, it dispatches to the new HTTP/2 driver; otherwise the existing HTTP/1.1 path is unchanged. - New h2_server.v (H2ServerConn): reads the client preface, exchanges SETTINGS (advertising SETTINGS_MAX_CONCURRENT_STREAMS=1 so requests serialize), and runs the frame loop. HEADERS+CONTINUATION are assembled and HPACK-decoded into a net.http.Request; DATA frames populate the body and replenish flow control; SETTINGS / PING / WINDOW_UPDATE / GOAWAY / RST_STREAM / PRIORITY are serviced inline. When the request stream closes, the existing Handler.handle(Request) Response interface is invoked unchanged; the Response is HPACK-encoded into HEADERS + DATA(END_STREAM) and sent back. - Hop-by-hop response headers are dropped (RFC 7540 Section 8.1.2.2). The request body is capped at 8 MiB with RST_STREAM(REFUSED_STREAM) on overflow. - The Handler contract is untouched: req.url is the request-target (the :path pseudo-header) and Host comes from :authority, so existing HTTP/1.1 handlers run with no changes on the new transport. Tests: h2_server_test.v drives the server through an in-memory blocking pipe with the existing HTTP/2 client (GET, POST with a body, non-200 status, all round-trip). server_tls_test.v adds a TLS + ALPN end-to-end test asserting http.fetch(enable_http2: true) negotiates h2 against the same listener that still serves HTTP/1.1 to non-h2 clients. Full vlib/net/http suite is green on both backends; passes under -W -cstrict -cc clang. This is opt-in and additive: with enable_http2 unset (or for non-TLS servers), behaviour is exactly as before. Stream multiplexing with a background reader is a planned follow-up (this driver serializes requests). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * net.http: server-side h2 send flow control + gate Windows ALPN test Address two findings from review of the server-side HTTP/2 PR: - Server response DATA now respects the HTTP/2 send flow-control windows (RFC 7540 Section 6.9). send_body bounds each DATA frame by min(connection, stream) window, decrements both after sending, and waits for WINDOW_UPDATE (servicing SETTINGS / PING / WINDOW_UPDATE, and a RST_STREAM for the stream being written) when a window is exhausted. apply_settings now also adjusts every active stream's send window by the delta when the peer changes SETTINGS_INITIAL_WINDOW_SIZE (Section 6.9.2). Previously a client that lowered its initial window could be sent more DATA than permitted and reset the stream with FLOW_CONTROL_ERROR. - Gate test_server_tls_h2_negotiation so it skips on the default Windows configuration: the SChannel client does not advertise ALPN, so it cannot negotiate HTTP/2 and the version assertion would fail. The path stays covered with `-d no_vschannel` (mbedtls client), matching how the rest of the suite treats the SChannel limitation. Adds test_h2_server_respects_send_window: a raw client advertises SETTINGS_INITIAL_WINDOW_SIZE=10, and the test asserts the server's first DATA frame is <= 10 bytes and that the full 100-byte body is delivered after a WINDOW_UPDATE. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Richard Wheeler <quaesitor.scientiam@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent e381c3e commit 35ffbab

5 files changed

Lines changed: 915 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)