pub struct Stream { /* private fields */ }Expand description
A bidirectional request stream.
Implementations§
Source§impl Stream
impl Stream
Sourcepub fn id(&self) -> u64
pub fn id(&self) -> u64
The QUIC stream id.
The Quarter Stream ID of RFC 9297 is this value divided by four.
Sourcepub fn datagrams(&mut self) -> Option<DatagramReceiver>
pub fn datagrams(&mut self) -> Option<DatagramReceiver>
Claims this stream’s inbound HTTP Datagrams (RFC 9297 §2.1).
Every datagram on the connection names a request stream by Quarter Stream ID, which is that stream’s id divided by four; this is how the one stream that wants them says so. Until it is called nothing routes to this stream and it costs nothing, which is what keeps a TCP tunnel – which has no use for a datagram – out of the routing table entirely.
None if they have already been claimed. Only the first caller can be
the session, because the DatagramReceiver deregisters the stream when
it is dropped and a second one would take the first’s entry with it.
Called before the response, not after: RFC 9298 §5 lets a client start sending payloads before its request is answered, and a claim made here means those land in the session’s queue rather than being dropped as belonging to no one.
Sourcepub async fn respond_within(
&mut self,
status: Status,
fields: Fields,
) -> Result<(), RespondError>
pub async fn respond_within( &mut self, status: Status, fields: Fields, ) -> Result<(), RespondError>
Sends a response with fields, bounded by the connection’s idle
timeout.
§The deadline
The write is the one step in answering a request that depends on the peer: a client that grants no flow-control window never takes the fifty-odd bytes of a 407, and without a deadline the task waits for that window until the connection ends. Every such request leaves a task holding the whole decoded request behind it, and the count of authentication failures that is meant to cost a guesser a handshake is recorded around one of these calls (review H1/H2).
The bound is the connection’s own idle timeout, read from the
connection rather than passed in: it is the same value crate::quic
put in this connection’s transport parameters, and quinn’s idle timer is
no backstop while the peer’s stack answers our keep-alive PINGs.
The lapsed answer is abandoned with a reset rather than left to a FIN that cannot be sent either: the request will not be answered, which is exactly what RFC 9114 §8.1 gives H3_REQUEST_CANCELLED for. “The request or its response (including pushed response) is cancelled.” Only the stream ends; the connection carries on serving everything else on it.
Sourcepub fn finish(&mut self) -> Result<(), StreamError>
pub fn finish(&mut self) -> Result<(), StreamError>
Ends the sending side cleanly (a QUIC stream FIN).
Not async: [quinn::SendStream::finish] records that the stream is
over and returns, and the FIN travels with the bytes already queued.
There is nothing to wait for, and a caller that wants the peer’s
acknowledgement is asking a different question.
Sourcepub fn stop_receiving(&mut self, code: Code)
pub fn stop_receiving(&mut self, code: Code)
Asks the peer to stop sending on this stream.
Sourcepub fn reset(&mut self, code: Code)
pub fn reset(&mut self, code: Code)
Abruptly ends the sending side with an error code.
The counterpart to Stream::finish, and the only one of the two that
gets through to a peer that has stopped granting flow-control credit: a
FIN travels at the end of the bytes already queued and so waits for a
window that may never come, while a reset is a frame of its own and
leaves at once. That is what makes this the way to abandon a response
nobody is reading – and abandoning it is what ends the stream, and
returns the peer’s allowance of streams with it.
Sourcepub fn split(self) -> (Writer, Reader)
pub fn split(self) -> (Writer, Reader)
Splits the stream so each direction can be pumped independently.
This is what makes TCP half-close expressible: one direction can finish while the other keeps flowing.
Both tunnels call this immediately after answering the CONNECT with a 2xx, so this is also where “the CONNECT method has completed” happens: from here the reader applies RFC 9114 §4.4’s rule that only DATA may follow, deciding it from each frame’s header rather than after its payload.