async fn pipe_data_framed(
recv: PeekedRecv,
send: SendStream,
side: ProxySide,
key: StreamKey,
requests: Receiver<StreamCommand>,
ctx: &ForwardCtx,
) -> Result<(), ProxyError>Expand description
Forward a unidirectional data stream through the object framer.
Every byte written to the destination comes out of
ObjectFramer::poll, so a forwarded stream on which no action was
taken is byte-identical to the received one — the framer only decides
where the boundaries are. The cost is latency: an object is not
forwarded until it is buffered whole, or until the framer gives up on
it and streams it through.
§The draft this frames with
Taken once, at the top, from the session’s shared cell and waited
for — see SessionDraft::resolved. Once, because the draft decides
where an object ends: a stream framed half under one draft and half under
another would report object boundaries that were never on the wire.
Waited for, because on drafts 07 to 14 the ALPN names no draft and the
answer arrives on the control stream, in a task this one was spawned
alongside — so reading the cell without waiting is a race the session
loses whenever the two tasks are polled in the other order, and losing it
means framing every object on this stream against the configured guess.
A wrong draft is not a fidelity failure — the framer latches a bypass and forwards the rest of the stream byte for byte — but it is a silent failure of everything built on the framing: no object reaches a hook, no shaping class claims one, and the session reports success.