Skip to content

Commit 03c6723

Browse files
quaesitor-scientiamRichard Wheelerclaude
authored
net.http: add synchronous HTTP/2 client connection (H2Conn) (#27361)
* net.http: add synchronous HTTP/2 client connection (H2Conn) Build on the ALPN (#27343), HPACK (#27353), and frame-codec (#27356) PRs to add a minimal, synchronous, single-stream HTTP/2 client. Additive only: new files in the http module, no change to existing code paths. Nothing wires it into http.fetch yet (that ALPN shim is a follow-up), so there is no user-visible behaviour change. - H2Transport interface — the byte transport the connection runs over. Its read/write signatures match net.ssl.SSLConn, so an ALPN-negotiated `h2` TLS socket satisfies it directly; tests use an in-memory mock, so the connection is exercised without a socket. - Connection preface + SETTINGS handshake (sent lazily on the first request). - H2Conn.do(req): HPACK-encodes the request headers, sends HEADERS (plus DATA for a body, chunked to the peer's max frame size and bounded by the connection flow-control window), then reads frames until the stream closes. - Inline servicing of connection-level frames: SETTINGS (apply + ACK), PING (echo ACK), WINDOW_UPDATE (grow the send window), GOAWAY (fail). Receive-side flow control is replenished with a WINDOW_UPDATE per DATA frame. - CONTINUATION reassembly for response header blocks; RST_STREAM on the request stream is surfaced as an error. Hermetic tests over the mock transport cover: a basic GET, a multi-DATA response, a POST with a body, GOAWAY, RST_STREAM, CONTINUATION-split response headers, and PING ACK. Passes under -W -cstrict -cc clang; the full vlib/net/http suite is green. Not included here, by design (follow-ups): stream multiplexing with a background reader thread, connection pooling, wiring into http.fetch via ALPN, and the server side. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * net.http: HTTP/2 client header splitting and per-stream flow control Address two send-path correctness gaps in H2Conn: - Split request header blocks larger than the peer's SETTINGS_MAX_FRAME_SIZE into a HEADERS frame followed by CONTINUATION frames (RFC 7540 Section 4.3), via send_header_block. Previously a large header set (e.g. big Cookie or Authorization) was sent as one oversized HEADERS frame that a compliant peer would reject. - Track the per-stream send window in addition to the connection window (RFC 7540 Section 6.9). DATA is now bounded by min(connection, stream) window, stream-level WINDOW_UPDATE credits the active stream, and a change to SETTINGS_INITIAL_WINDOW_SIZE retroactively adjusts the stream window by the delta (Section 6.9.2). Previously only the connection window was tracked, so a peer lowering the initial window or granting stream-level updates could be overrun or could stall the client. Adds tests for a request whose header block spans HEADERS + CONTINUATION, and for a body larger than the initial window that resumes after the peer grows both windows (no DATA frame exceeding the max frame size). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Richard Wheeler <quaesitor.scientiam@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e78b731 commit 03c6723

2 files changed

Lines changed: 812 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)