flare_mlake · API · http3

flare.http3.request_writer

HTTP/3 request-stream writer -- sans-I/O byte emitter.

The client-side mirror of :mod:flare.http3.response_writer. Builds the bytes an HTTP/3 client hands to the QUIC stream layer for a request on a client-initiated bidirectional stream, plus the preambles for the client's unidirectional control + QPACK streams.

A complete H3 request is at most three concatenated wire fragments on the request (bidi) stream:

HEADERS frame (:method / :scheme / :authority / :path pseudo-headers + application headers, QPACK-encoded) DATA frame (zero or more, request body) HEADERS frame (optional trailers, QPACK-encoded)

Before any request, the client opens three unidirectional streams (RFC 9114 §6.2): the control stream (type 0x00, carrying SETTINGS first) and the QPACK encoder / decoder streams (types 0x02 / 0x03, empty in the static-only table mode flare uses). The preamble encoders here emit the leading stream-type varint + initial frame so the caller can ship them as the first bytes of each uni-stream.

Public surface:

  • :func:encode_request_headers -- the initial HEADERS frame with the four request pseudo-headers in canonical order (RFC 9114 §4.3.1) followed by the application headers (lowercased).
  • :func:encode_request_data -- wrap a body chunk in a DATA frame.
  • :func:encode_request_trailers -- the trailing HEADERS frame.
  • :func:encode_client_control_stream -- the control-stream type byte + the client's SETTINGS frame (the mandatory first frame, RFC 9114 §6.2.1).
  • :func:encode_qpack_encoder_stream / :func:encode_qpack_decoder_stream -- the single stream-type byte for each QPACK uni-stream.

Sans-I/O contract: every entry point is a pure function over its inputs; the QUIC client driver owns the per-stream cursor + FIN.

References:

  • RFC 9114 §4 (HTTP Message Exchanges) + §6.2 (uni-streams) + §7.
  • RFC 9204 (QPACK) -- static-table field-section encoder.

Functions

encode_request_headers

def encode_request_headers(method: String, scheme: String, authority: String, path: String, headers: List[HpackHeader], mut out: List[UInt8], protocol: String = "")

Append the HEADERS-frame bytes for an HTTP/3 request to out. A non-empty protocol adds :protocol (an extended CONNECT, RFC 9220).

Emits the four request pseudo-headers :method / :scheme / :authority / :path in canonical order (RFC 9114 §4.3.1) before the supplied application headers (all names lowercased). The caller MUST NOT include any pseudo-header in headers -- the writer rejects a name starting with : there, mirroring :func:flare.http3.response_writer.encode_response_headers.

authority may be empty for the CONNECT-less origin case where a Host header is used instead, but for normal requests it carries the host[:port] the request targets.

encode_request_data

def encode_request_data(payload: Span[UInt8], mut out: List[UInt8])

Append an HTTP/3 DATA frame wrapping payload to out.

The client calls this once per body chunk. Empty payloads are legal and encode as a 2-byte frame (type=0x00 + length=0x00).

encode_request_trailers

def encode_request_trailers(trailers: List[HpackHeader], mut out: List[UInt8])

Append the trailing HEADERS-frame bytes to out.

Trailers MUST NOT include pseudo-headers; the writer rejects any field whose name starts with :. The driver sends this frame followed by FIN to close the request side of the stream.

encode_client_control_stream

def encode_client_control_stream(max_field_section_size: UInt64, mut out: List[UInt8])

Append the client's control unidirectional stream preamble to out: the stream-type varint (0x00) followed by the SETTINGS frame that MUST be the first frame (RFC 9114 §6.2.1).

flare runs QPACK in static-table-only mode, so the QPACK capacity + blocked-streams settings are advertised as 0, telling the server not to use the dynamic table against us. The caller writes the returned bytes as the very first bytes of a fresh client-initiated unidirectional stream.

encode_qpack_encoder_stream

def encode_qpack_encoder_stream(mut out: List[UInt8])

Append the QPACK encoder unidirectional stream type byte (0x02, RFC 9204 §4.2). No further bytes follow in static-only mode (no dynamic-table instructions are ever sent).

encode_qpack_decoder_stream

def encode_qpack_decoder_stream(mut out: List[UInt8])

Append the QPACK decoder unidirectional stream type byte (0x03, RFC 9204 §4.2). No further bytes follow in static-only mode.

Aliases

comptime H3_UNI_STREAM_CONTROL = UInt64(0)
comptime H3_UNI_STREAM_QPACK_ENCODER = UInt64(2)
comptime H3_UNI_STREAM_QPACK_DECODER = UInt64(3)