Skip to main content

Stream

Struct Stream 

Source
pub struct Stream { /* private fields */ }
Expand description

A bidirectional request stream.

Implementations§

Source§

impl Stream

Source

pub fn id(&self) -> u64

The QUIC stream id.

The Quarter Stream ID of RFC 9297 is this value divided by four.

Source

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.

Source

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.

Source

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.

Source

pub fn stop_receiving(&mut self, code: Code)

Asks the peer to stop sending on this stream.

Source

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.

Source

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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more