# flare.http.streaming_serialize

> A module of flare_mlake's API.

Streaming response serializer.

Renders a ``StreamingResponse[B: Body]`` to wire bytes per
RFC 7230 §3 (status line + headers) + RFC 7230 §4.1 (chunked
transfer-coding) when ``B.content_length()`` is unknown, or
plain Content-Length framing when it's known.

The reactor's view-aware write loop (a focused follow-up) calls
this serializer per writable edge to pull-and-write one chunk
at a time. Callers that don't need the streaming benefit
(every existing handler that returns a ``Response``)
keep the buffer-then-send path through the existing
``_serialize_response`` in ``flare/http/_server_reactor_impl``.

Why a standalone serializer rather than a parallel reactor:

C3's experience showed that adding a parallel reactor entry
parametric over a trait-method-with-origin is currently slow to
specialise in Mojo. The streaming serializer here is a plain
function — no parametric trait dispatch, no per-handler
specialization explosion — so it compiles fast and is easy to
test independently. The reactor adoption that calls this
serializer is a small follow-up commit (~30 lines of glue) that
the user can review separately once Mojo's specialization
slowness is resolved or the team commits to the slower compile
times.

Wire-framing semantics:

- ``body.content_length()`` returns ``Some(n)``:
  - Header line: ``Content-Length: n\r\n``.
  - Body bytes: emit each chunk inline until ``next_chunk``
    returns None. Total emitted bytes equal n by contract.

- ``body.content_length()`` returns ``None``:
  - Header line: ``Transfer-Encoding: chunked\r\n``.
  - Body bytes: per chunk, emit ``hex_length\r\n`` + chunk +
    ``\r\n``. Final terminator: ``0\r\n\r\n``.

The serializer is cancel-aware: if ``cancel.cancelled()`` flips
between chunks, the write loop emits the final chunked
terminator and returns — the connection closes cleanly without
breaking the framing contract. Callers that need to abort
mid-chunk should close the underlying socket; the framing
guarantee covers cooperative cancel only.

## Functions

### `serialize_streaming_response`

```mojo
def serialize_streaming_response[B: Body](var resp: StreamingResponse[B], cancel: Cancel, keep_alive: Bool = True) -> List[UInt8]
```

Render ``resp`` to wire bytes — status line + headers + body (Content-Length or chunked framing).

Args:

- `resp`: Streaming response with a ``Body`` impl.
            Ownership transferred; the body is consumed
            chunk by chunk.
- `cancel`: Per-request cancel token. The body's
            ``next_chunk(cancel)`` polls this; flipping
            it mid-stream stops chunk emission cleanly
            (chunked framing's terminator is still
            written so the framing contract holds).
- `keep_alive`: When ``True``, the response carries
            ``Connection: keep-alive``; when ``False``,
            ``Connection: close``. The reactor sets this
            based on the request's connection
            disposition.

Raises: Error: Any error from ``body.next_chunk`` propagates.
