Struct quinn::RecvStream

source ·
pub struct RecvStream { /* private fields */ }
Expand description

A stream that can only be used to receive data

stop(0) is implicitly called on drop unless:

  • A variant of ReadError has been yielded by a read call
  • stop() was called explicitly

Closing a stream

When a stream is expected to be closed gracefully the sender should call SendStream::finish. However there is no guarantee the connected RecvStream will receive the “finished” notification in the same QUIC frame as the last frame which carried data.

Even if the application layer logic already knows it read all the data because it does its own framing, it should still read until it reaches the end of the RecvStream. Otherwise it risks inadvertently calling RecvStream::stop if it drops the stream. And calling RecvStream::stop could result in the connected SendStream::finish call failing with a WriteError::Stopped error.

For example if exactly 10 bytes are to be read, you still need to explicitly read the end of the stream:

// In the sending task
send_stream.write(&b"0123456789"[..]).await?;
send_stream.finish().await?;

// In the receiving task
let mut buf = [0u8; 10];
let data = recv_stream.read_exact(&mut buf).await?;
if recv_stream.read_to_end(0).await.is_err() {
    // Discard unexpected data and notify the peer to stop sending it
    let _ = recv_stream.stop(0u8.into());
}

An alternative approach, used in HTTP/3, is to specify a particular error code used with stop that indicates graceful receiver-initiated stream shutdown, rather than a true error condition.

RecvStream::read_chunk could be used instead which does not take ownership and allows using an explit call to RecvStream::stop with a custom error code.

Implementations§

source§

impl RecvStream

source

pub async fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>, ReadError>

Read data contiguously from the stream.

Yields the number of bytes read into buf on success, or None if the stream was finished.

source

pub async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError>

Read an exact number of bytes contiguously from the stream.

See read() for details.

source

pub async fn read_chunk( &mut self, max_length: usize, ordered: bool ) -> Result<Option<Chunk>, ReadError>

Read the next segment of data

Yields None if the stream was finished. Otherwise, yields a segment of data and its offset in the stream. If ordered is true, the chunk’s offset will be immediately after the last data yielded by read() or read_chunk(). If ordered is false, segments may be received in any order, and the Chunk’s offset field can be used to determine ordering in the caller. Unordered reads are less prone to head-of-line blocking within a stream, but require the application to manage reassembling the original data.

Slightly more efficient than read due to not copying. Chunk boundaries do not correspond to peer writes, and hence cannot be used as framing.

source

pub async fn read_chunks( &mut self, bufs: &mut [Bytes] ) -> Result<Option<usize>, ReadError>

Read the next segments of data

Fills bufs with the segments of data beginning immediately after the last data yielded by read or read_chunk, or None if the stream was finished.

Slightly more efficient than read due to not copying. Chunk boundaries do not correspond to peer writes, and hence cannot be used as framing.

source

pub async fn read_to_end( &mut self, size_limit: usize ) -> Result<Vec<u8>, ReadToEndError>

Convenience method to read all remaining data into a buffer

Fails with ReadToEndError::TooLong on reading more than size_limit bytes, discarding all data read. Uses unordered reads to be more efficient than using AsyncRead would allow. size_limit should be set to limit worst-case memory use.

If unordered reads have already been made, the resulting buffer may have gaps containing arbitrary data.

source

pub fn stop(&mut self, error_code: VarInt) -> Result<(), UnknownStream>

Stop accepting data

Discards unread data and notifies the peer to stop transmitting. Once stopped, further attempts to operate on a stream will yield UnknownStream errors.

source

pub fn is_0rtt(&self) -> bool

Check if this stream has been opened during 0-RTT.

In which case any non-idempotent request should be considered dangerous at the application level. Because read data is subject to replay attacks.

source

pub fn id(&self) -> StreamId

Get the identity of this stream

Trait Implementations§

source§

impl AsyncRead for RecvStream

source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8] ) -> Poll<Result<usize>>

Attempt to read from the AsyncRead into buf. Read more
source§

fn poll_read_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>] ) -> Poll<Result<usize, Error>>

Attempt to read from the AsyncRead into bufs using vectored IO operations. Read more
source§

impl AsyncRead for RecvStream

source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_> ) -> Poll<Result<()>>

Attempts to read from the AsyncRead into buf. Read more
source§

impl Debug for RecvStream

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for RecvStream

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for Rwhere R: AsyncRead + ?Sized,

§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self>where Self: Unpin,

Reads some bytes from the byte stream. Read more
§

fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>] ) -> ReadVectoredFuture<'a, Self>where Self: Unpin,

Like [read()][AsyncReadExt::read()], except it reads into a slice of buffers. Read more
§

fn read_to_end<'a>( &'a mut self, buf: &'a mut Vec<u8, Global> ) -> ReadToEndFuture<'a, Self>where Self: Unpin,

Reads the entire contents and appends them to a Vec. Read more
§

fn read_to_string<'a>( &'a mut self, buf: &'a mut String ) -> ReadToStringFuture<'a, Self>where Self: Unpin,

Reads the entire contents and appends them to a String. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self>where Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn take(self, limit: u64) -> Take<Self>where Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
§

fn bytes(self) -> Bytes<Self>where Self: Sized,

Converts this AsyncRead into a [Stream] of bytes. Read more
§

fn chain<R>(self, next: R) -> Chain<Self, R>where R: AsyncRead, Self: Sized,

Creates an adapter which will chain this stream with another. Read more
§

fn boxed_reader<'a>(self) -> Pin<Box<dyn AsyncRead + Send + 'a, Global>>where Self: Sized + Send + 'a,

Boxes the reader and changes its type to dyn AsyncRead + Send + 'a. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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.

source§

impl<T> Instrument for T

source§

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

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

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 Twhere 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> ReadExt for Twhere T: AsyncRead + ?Sized,

source§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self>where Self: Unpin,

Reads some bytes from the byte stream. Read more
source§

fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>] ) -> ReadVectoredFuture<'a, Self>where Self: Unpin,

Like read, except that it reads into a slice of buffers. Read more
source§

fn read_to_end<'a>( &'a mut self, buf: &'a mut Vec<u8, Global> ) -> ReadToEndFuture<'a, Self>where Self: Unpin,

Reads all bytes from the byte stream. Read more
source§

fn read_to_string<'a>( &'a mut self, buf: &'a mut String ) -> ReadToStringFuture<'a, Self>where Self: Unpin,

Reads all bytes from the byte stream and appends them into a string. Read more
source§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self>where Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
source§

fn take(self, limit: u64) -> Take<Self>where Self: Sized,

Creates an adaptor which will read at most limit bytes from it. Read more
source§

fn by_ref(&mut self) -> &mut Selfwhere Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
source§

fn bytes(self) -> Bytes<Self>where Self: Sized,

Transforms this Read instance to a Stream over its bytes. Read more
source§

fn chain<R>(self, next: R) -> Chain<Self, R>where R: AsyncRead, Self: Sized,

Creates an adaptor which will chain this stream with another. Read more
source§

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

§

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 Twhere U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

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
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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