Summary#
Implement the HTTP/2 protocol (RFC 7540/9113): binary framing layer, multiplexed streams, flow control, and integration with the existing HTTP client.
Background#
HTTP/1.1 uses one request per TCP connection (or pipelining, which is rarely used). HTTP/2 multiplexes many requests over a single TCP connection using binary frames and streams, with per-stream and connection-level flow control. This reduces latency for pages that load many resources.
Acceptance Criteria#
- Frame parser/serializer: 9-byte frame header + payload for all frame types:
- DATA, HEADERS, PRIORITY, RST_STREAM, SETTINGS, PUSH_PROMISE, PING, GOAWAY, WINDOW_UPDATE, CONTINUATION
- Connection preface: send
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n+ SETTINGS frame - Stream state machine: idle → open → half-closed → closed (RFC 7540 §5.1)
- Stream multiplexing: concurrent requests on a single TCP/TLS connection, each on its own stream ID
- Flow control: per-stream and connection-level WINDOW_UPDATE tracking (RFC 7540 §6.9)
- Default window size: 65535 bytes
- Send WINDOW_UPDATE frames to keep data flowing
- SETTINGS negotiation: exchange and acknowledge SETTINGS frames at connection start
- Key settings: HEADER_TABLE_SIZE, MAX_CONCURRENT_STREAMS, INITIAL_WINDOW_SIZE, MAX_FRAME_SIZE
- HEADERS frame: encode request headers via HPACK, handle CONTINUATION frames for large header blocks
- DATA frame: send/receive response bodies with flow control
- Error handling: RST_STREAM for stream errors, GOAWAY for connection errors
- ALPN negotiation: advertise
h2during TLS handshake to negotiate HTTP/2 - Integration with HttpClient: transparent upgrade — if server supports h2, use HTTP/2; else fall back to HTTP/1.1
- Add module at
crates/net/src/http2/ - Tests for frame encoding/decoding, stream state transitions, flow control edge cases
Implementation Notes#
- HTTP/2 only works over TLS in practice (h2c is rare) — integrate with the existing TLS handshake by adding ALPN extension
- Stream IDs: client-initiated streams use odd IDs (1, 3, 5, ...), server push uses even
- The connection manages a
HashMap<StreamId, Stream>for active streams - Priority/weight handling can be minimal (just store, don't optimize scheduling by it)
- PUSH_PROMISE can be ignored for now (server push is deprecated in practice)
- HPACK encoder/decoder from the previous issue is used for HEADERS frames
- Consider a
Http2Connectionstruct that wraps a TLS stream and manages all streams
Dependencies#
- Requires: HPACK header compression issue
- Requires: TLS ALPN support (may need a small addition to the TLS handshake)
Phase#
Phase 15: Performance