# flare.http3.response_writer

> A module of flare_mlake's API.

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

Symmetric to :mod:`flare.http3.request_reader`. Builds the bytes
the H3 server reactor hands to the QUIC stream abstraction for a
response on a request stream.

A complete H3 response is at most three concatenated wire
fragments:

  HEADERS frame (status pseudo-header + application headers,
                 QPACK-encoded)
  DATA frame    (zero or more, body bytes)
  HEADERS frame (optional trailers, QPACK-encoded)

The writer doesn't own the bytes -- it returns owned ``List[
UInt8]`` outputs that the caller stitches into one or more QUIC
stream sends. The reactor wrapper drives flow control, MTU
splits, and FIN; this module is purely the codec.

Public surface:

* :func:`encode_response_headers` -- build the HEADERS frame
  bytes for the initial response. Always emits ``:status`` first
  per RFC 9114 §4.3, then the supplied application headers
  verbatim. Lowercases header names on the way through to keep
  the output H3-conformant.
* :func:`encode_response_data` -- wrap a payload chunk in a
  DATA frame. The reactor calls this once per body chunk to
  preserve back-pressure.
* :func:`encode_response_trailers` -- build the trailing
  HEADERS frame.

Sans-I/O contract: the writer holds zero state; every entry
point is a pure function over its inputs. The reactor wrapper
keeps the per-stream cursor + FIN bit.

References:
- RFC 9114 §4 (HTTP Message Exchanges) + §7 (Frames).
- RFC 9204 (QPACK).

## Functions

### `encode_response_headers`

```mojo
def encode_response_headers(status: Int, headers: List[HpackHeader], mut out: List[UInt8])
```

Append the HEADERS-frame bytes for an HTTP/3 response to ``out``.

Emits ``:status`` as the first field per RFC 9114 §4.3.2,
then the supplied application headers (all names lowercased).
The caller MUST NOT include ``:status`` in ``headers`` --
the reader rejects field sections that emit pseudo-headers
after a regular header (RFC 9114 §4.3 invariant), and this
writer skips application-pseudoheader emission entirely.

The caller owns the buffer and may reuse the same
``List[UInt8]`` across HEADERS + DATA + trailers so the
underlying allocation amortises across the response. The
encoder appends only; it never reads from or truncates the
existing contents.

### `encode_response_head`

```mojo
def encode_response_head(status: Int, headers: HeaderMap, mut out: List[UInt8])
```

:func:`encode_response_headers` straight from a handler's :class:`HeaderMap`: the field lines go into one buffer with no per-header copy (a name is lowercased only when it has upper-case bytes), and connection-specific fields, which handlers written for HTTP/1.1 set, are dropped (RFC 9114 sec 4.2).

### `encode_response_data`

```mojo
def encode_response_data(payload: Span[UInt8], mut out: List[UInt8])
```

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

The H3 server reactor calls this once per body chunk so
flow-control back-pressure on the QUIC stream applies per
chunk; emitting the entire body in one DATA frame is legal
but loses the granularity. Empty payloads are legal and
encode as a 2-byte frame (type=0x00 + length=0x00).

The caller owns the buffer and may reuse the same
``List[UInt8]`` across HEADERS + DATA + trailers so the
underlying allocation amortises across the response.

### `encode_response_trailers`

```mojo
def encode_response_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 reactor sends
this frame followed by FIN to close the response side of the
request stream.

The caller owns the buffer and may reuse the same
``List[UInt8]`` across HEADERS + DATA + trailers so the
underlying allocation amortises across the response.
