noq/
recv_stream.rs

1use std::{
2    future::{Future, poll_fn},
3    io,
4    pin::Pin,
5    task::{Context, Poll, ready},
6};
7
8use bytes::Bytes;
9use proto::{Chunk, Chunks, ClosedStream, ConnectionError, ReadableError, StreamId};
10use thiserror::Error;
11use tokio::io::ReadBuf;
12
13use crate::{VarInt, connection::ConnectionRef};
14
15/// A stream that can only be used to receive data
16///
17/// `stop(0)` is implicitly called on drop unless:
18/// - A variant of [`ReadError`] has been yielded by a read call
19/// - [`stop()`] was called explicitly
20///
21/// # Cancellation
22///
23/// A `read` method is said to be *cancel-safe* when dropping its future before the future becomes
24/// ready cannot lead to loss of stream data. This is true of methods which succeed immediately when
25/// any progress is made, and is not true of methods which might need to perform multiple reads
26/// internally before succeeding. Each `read` method documents whether it is cancel-safe.
27///
28/// # Common issues
29///
30/// ## Data never received on a locally-opened stream
31///
32/// Peers are not notified of streams until they or a later-numbered stream are used to send
33/// data. If a bidirectional stream is locally opened but never used to send, then the peer may
34/// never see it. Application protocols should always arrange for the endpoint which will first
35/// transmit on a stream to be the endpoint responsible for opening it.
36///
37/// ## Data never received on a remotely-opened stream
38///
39/// Verify that the stream you are receiving is the same one that the server is sending on, e.g. by
40/// logging the [`id`] of each. Streams are always accepted in the same order as they are created,
41/// i.e. ascending order by [`StreamId`]. For example, even if a sender first transmits on
42/// bidirectional stream 1, the first stream yielded by [`Connection::accept_bi`] on the receiver
43/// will be bidirectional stream 0.
44///
45/// [`ReadError`]: crate::ReadError
46/// [`stop()`]: RecvStream::stop
47/// [`SendStream::finish`]: crate::SendStream::finish
48/// [`WriteError::Stopped`]: crate::WriteError::Stopped
49/// [`id`]: RecvStream::id
50/// [`Connection::accept_bi`]: crate::Connection::accept_bi
51#[derive(Debug)]
52pub struct RecvStream {
53    conn: ConnectionRef,
54    stream: StreamId,
55    is_0rtt: bool,
56    all_data_read: bool,
57    reset: Option<VarInt>,
58}
59
60impl RecvStream {
61    pub(crate) fn new(conn: ConnectionRef, stream: StreamId, is_0rtt: bool) -> Self {
62        Self {
63            conn,
64            stream,
65            is_0rtt,
66            all_data_read: false,
67            reset: None,
68        }
69    }
70
71    /// Read data contiguously from the stream.
72    ///
73    /// Yields the number of bytes read into `buf` on success, or `None` if the stream was finished.
74    ///
75    /// This operation is cancel-safe.
76    pub async fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>, ReadError> {
77        Read {
78            stream: self,
79            buf: ReadBuf::new(buf),
80        }
81        .await
82    }
83
84    /// Read an exact number of bytes contiguously from the stream.
85    ///
86    /// See [`read()`] for details. This operation is *not* cancel-safe.
87    ///
88    /// [`read()`]: RecvStream::read
89    pub async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError> {
90        ReadExact {
91            stream: self,
92            buf: ReadBuf::new(buf),
93        }
94        .await
95    }
96
97    /// Attempts to read from the stream into the provided buffer
98    ///
99    /// On success, returns `Poll::Ready(Ok(num_bytes_read))` and places data into `buf`. If this
100    /// returns zero bytes read (and `buf` has a non-zero length), that indicates that the remote
101    /// side has [`finish`]ed the stream and the local side has already read all bytes.
102    ///
103    /// If no data is available for reading, this returns `Poll::Pending` and arranges for the
104    /// current task (via `cx.waker()`) to be notified when the stream becomes readable or is
105    /// closed.
106    ///
107    /// [`finish`]: crate::SendStream::finish
108    pub fn poll_read(
109        &mut self,
110        cx: &mut Context<'_>,
111        buf: &mut [u8],
112    ) -> Poll<Result<usize, ReadError>> {
113        let mut buf = ReadBuf::new(buf);
114        ready!(self.poll_read_buf(cx, &mut buf))?;
115        Poll::Ready(Ok(buf.filled().len()))
116    }
117
118    /// Attempts to read from the stream into the provided buffer, which may be uninitialized
119    ///
120    /// On success, returns `Poll::Ready(Ok(()))` and places data into the unfilled portion of
121    /// `buf`. If this does not write any bytes to `buf` (and `buf.remaining()` is non-zero), that
122    /// indicates that the remote side has [`finish`]ed the stream and the local side has already
123    /// read all bytes.
124    ///
125    /// If no data is available for reading, this returns `Poll::Pending` and arranges for the
126    /// current task (via `cx.waker()`) to be notified when the stream becomes readable or is
127    /// closed.
128    ///
129    /// [`finish`]: crate::SendStream::finish
130    pub(crate) fn poll_read_buf(
131        &mut self,
132        cx: &mut Context<'_>,
133        buf: &mut ReadBuf<'_>,
134    ) -> Poll<Result<(), ReadError>> {
135        if buf.remaining() == 0 {
136            return Poll::Ready(Ok(()));
137        }
138
139        self.poll_read_generic(cx, true, |chunks| {
140            let mut read = false;
141            loop {
142                if buf.remaining() == 0 {
143                    // We know `read` is `true` because `buf.remaining()` was not 0 before
144                    return ReadStatus::Readable(());
145                }
146
147                match chunks.next(buf.remaining()) {
148                    Ok(Some(chunk)) => {
149                        buf.put_slice(&chunk.bytes);
150                        read = true;
151                    }
152                    res => return (if read { Some(()) } else { None }, res.err()).into(),
153                }
154            }
155        })
156        .map(|res| res.map(|_| ()))
157    }
158
159    /// Reads the next segment of data as zero-copy [`Bytes`].
160    ///
161    /// Yields `None` if the stream was finished. Otherwise, yields the next segment of data. The
162    /// chunk's offset will be immediately after the last data yielded by [`RecvStream::read`] or
163    /// [`RecvStream::read_chunk`]; use [`bytes_read()`](Self::bytes_read) to query that offset
164    /// explicitly.
165    ///
166    /// For unordered reads, convert the stream into an unordered stream using
167    /// [`Self::into_unordered`].
168    ///
169    /// Slightly more efficient than [`RecvStream::read`] due to not copying. Chunk boundaries do
170    /// not correspond to peer writes, and hence cannot be used as framing.
171    ///
172    /// This operation is cancel-safe.
173    pub async fn read_chunk(&mut self, max_length: usize) -> Result<Option<Bytes>, ReadError> {
174        Ok(ReadChunk {
175            stream: self,
176            max_length,
177            ordered: true,
178        }
179        .await?
180        .map(|chunk| chunk.bytes))
181    }
182
183    /// Attempts to read a chunk from the stream.
184    ///
185    /// On success, returns `Poll::Ready(Ok(Some(chunk)))`. If `Poll::Ready(Ok(None))`
186    /// is returned, it implies that EOF has been reached.
187    ///
188    /// If no data is available for reading, the method returns `Poll::Pending`
189    /// and arranges for the current task (via cx.waker()) to receive a notification
190    /// when the stream becomes readable or is closed.
191    fn poll_read_chunk(
192        &mut self,
193        cx: &mut Context<'_>,
194        max_length: usize,
195        ordered: bool,
196    ) -> Poll<Result<Option<Chunk>, ReadError>> {
197        self.poll_read_generic(cx, ordered, |chunks| match chunks.next(max_length) {
198            Ok(Some(chunk)) => ReadStatus::Readable(chunk),
199            res => (None, res.err()).into(),
200        })
201    }
202
203    fn is_ordered(&self) -> Result<bool, ReadError> {
204        let mut conn = self.conn.lock_without_waking("RecvStream::is_ordered");
205        if self.is_0rtt {
206            conn.check_0rtt().map_err(|()| ReadError::ZeroRttRejected)?;
207        }
208        conn.inner
209            .recv_stream(self.stream)
210            .is_ordered()
211            .map_err(|_| ReadError::ClosedStream)
212    }
213
214    /// Reads the next segments of data.
215    ///
216    /// Fills `bufs` with the segments of data beginning immediately after the last data yielded
217    /// by [`read`](Self::read), [`read_chunk`](Self::read_chunk), or
218    /// [`read_many_chunks`](Self::read_many_chunks), or `None` if the stream was finished.
219    ///
220    /// Slightly more efficient than [`read`](Self::read) due to not copying. Chunk boundaries do
221    /// not correspond to peer writes, and hence cannot be used as framing.
222    ///
223    /// This operation is cancel-safe.
224    pub async fn read_many_chunks(
225        &mut self,
226        bufs: &mut [Bytes],
227    ) -> Result<Option<usize>, ReadError> {
228        ReadChunks { stream: self, bufs }.await
229    }
230
231    /// Foundation of [`Self::read_many_chunks`]
232    fn poll_read_chunks(
233        &mut self,
234        cx: &mut Context<'_>,
235        bufs: &mut [Bytes],
236    ) -> Poll<Result<Option<usize>, ReadError>> {
237        if bufs.is_empty() {
238            return Poll::Ready(Ok(Some(0)));
239        }
240
241        self.poll_read_generic(cx, true, |chunks| {
242            let mut read = 0;
243            loop {
244                if read >= bufs.len() {
245                    // We know `read > 0` because `bufs` cannot be empty here
246                    return ReadStatus::Readable(read);
247                }
248
249                match chunks.next(usize::MAX) {
250                    Ok(Some(chunk)) => {
251                        bufs[read] = chunk.bytes;
252                        read += 1;
253                    }
254                    res => return (if read == 0 { None } else { Some(read) }, res.err()).into(),
255                }
256            }
257        })
258    }
259
260    /// Convenience method to read all remaining data into a buffer
261    ///
262    /// Fails with [`ReadToEndError::TooLong`] on reading more than `size_limit` bytes, discarding
263    /// all data read. Uses unordered reads to be more efficient than using `AsyncRead` would
264    /// allow. `size_limit` should be set to limit worst-case memory use.
265    ///
266    /// This operation is *not* cancel-safe. If cancelled after it has begun reading, further read
267    /// operations on the stream return [`ReadError::ClosedStream`].
268    ///
269    /// [`ReadToEndError::TooLong`]: crate::ReadToEndError::TooLong
270    pub async fn read_to_end(&mut self, size_limit: usize) -> Result<Vec<u8>, ReadToEndError> {
271        if !self.is_ordered()? {
272            return Err(ReadError::ClosedStream.into());
273        }
274        ReadToEnd {
275            stream: self,
276            size_limit,
277            read: Vec::new(),
278            start: u64::MAX,
279            end: 0,
280        }
281        .await
282    }
283
284    /// Stop accepting data
285    ///
286    /// Discards unread data and notifies the peer to stop transmitting. Once stopped, further
287    /// attempts to operate on a stream will yield `ClosedStream` errors.
288    pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream> {
289        let mut conn = self.conn.lock_and_wake("RecvStream::stop");
290        if self.is_0rtt && conn.check_0rtt().is_err() {
291            conn.skip_waking();
292            return Ok(());
293        }
294        conn.inner.recv_stream(self.stream).stop(error_code)?;
295        self.all_data_read = true;
296        // Clean up shared state that might be left over from a cancelled read
297        // operation, so `drop` doesn't have to
298        conn.blocked_readers.remove(&self.stream);
299        Ok(())
300    }
301
302    /// Check if this stream predates completion of the handshake on an incoming connection.
303    ///
304    /// True only if the stream was accepted before the handshake completed, which is only possible
305    /// if you successfully called [`Connecting::into_0rtt`](crate::Connecting::into_0rtt) and the
306    /// client chose to send 0-RTT data.
307    ///
308    /// Under those conditions, depending on cryptographic layer configuration, 0-RTT application
309    /// data may be a replay attack. To guard against this, applications should not execute
310    /// non-idempotent operations until
311    /// [`Connection::authenticated`](crate::Connection::authenticated) succeeds.
312    pub fn is_0rtt(&self) -> bool {
313        self.is_0rtt
314    }
315
316    /// Get the identity of this stream
317    pub fn id(&self) -> StreamId {
318        self.stream
319    }
320
321    /// Returns the number of bytes read from this stream.
322    ///
323    /// This is the offset of the next byte to be read, i.e. the length of the contiguous
324    /// prefix of the stream consumed by the application.
325    pub fn bytes_read(&self) -> Result<u64, ClosedStream> {
326        let mut conn = self.conn.lock_without_waking("RecvStream::bytes_read");
327        conn.inner.recv_stream(self.stream).bytes_read()
328    }
329
330    /// Completes when the stream has been reset by the peer or otherwise closed
331    ///
332    /// Yields `Some` with the reset error code when the stream is reset by the peer. Yields `None`
333    /// when the stream was previously [`stop()`](Self::stop)ed, or when the stream was
334    /// [`finish()`](crate::SendStream::finish)ed by the peer and all data has been received, after
335    /// which it is no longer meaningful for the stream to be reset.
336    ///
337    /// This operation is cancel-safe.
338    pub async fn received_reset(&mut self) -> Result<Option<VarInt>, ResetError> {
339        poll_fn(|cx| {
340            let mut conn = self.conn.lock_without_waking("RecvStream::reset");
341            if self.is_0rtt && conn.check_0rtt().is_err() {
342                return Poll::Ready(Err(ResetError::ZeroRttRejected));
343            }
344
345            if let Some(code) = self.reset {
346                return Poll::Ready(Ok(Some(code)));
347            }
348
349            match conn.inner.recv_stream(self.stream).received_reset() {
350                Err(_) => Poll::Ready(Ok(None)),
351                Ok(Some(error_code)) => {
352                    // Stream state has just now been freed, so the connection may need to issue new
353                    // stream ID flow control credit
354                    conn.wake();
355                    Poll::Ready(Ok(Some(error_code)))
356                }
357                Ok(None) => {
358                    if let Some(e) = &conn.error {
359                        return Poll::Ready(Err(e.clone().into()));
360                    }
361                    // Resets always notify readers, since a reset is an immediate read error. We
362                    // could introduce a dedicated channel to reduce the risk of spurious wakeups,
363                    // but that increased complexity is probably not justified, as an application
364                    // that is expecting a reset is not likely to receive large amounts of data.
365                    conn.blocked_readers.insert(self.stream, cx.waker().clone());
366                    Poll::Pending
367                }
368            }
369        })
370        .await
371    }
372
373    /// Handle common logic related to reading out of a receive stream
374    ///
375    /// This takes an `FnMut` closure that takes care of the actual reading process, matching
376    /// the detailed read semantics for the calling function with a particular return type.
377    /// The closure can read from the passed `&mut Chunks` and has to return the status after
378    /// reading: the amount of data read, and the status after the final read call.
379    fn poll_read_generic<T, U>(
380        &mut self,
381        cx: &mut Context<'_>,
382        ordered: bool,
383        mut read_fn: T,
384    ) -> Poll<Result<Option<U>, ReadError>>
385    where
386        T: FnMut(&mut Chunks<'_>) -> ReadStatus<U>,
387    {
388        use proto::ReadError::*;
389        if self.all_data_read {
390            return Poll::Ready(Ok(None));
391        }
392
393        let mut conn = self.conn.lock_without_waking("RecvStream::poll_read");
394        if self.is_0rtt {
395            conn.check_0rtt().map_err(|()| ReadError::ZeroRttRejected)?;
396        }
397
398        // If we stored an error during a previous call, return it now. This can happen if a
399        // `read_fn` both wants to return data and also returns an error in its final stream status.
400        let status = match self.reset {
401            Some(code) => ReadStatus::Failed(None, Reset(code)),
402            None => {
403                let mut recv = conn.inner.recv_stream(self.stream);
404                let mut chunks = recv.read(ordered).map_err(|e| match e {
405                    ReadableError::ClosedStream => ReadError::ClosedStream,
406                    ReadableError::IllegalOrderedRead => ReadError::ClosedStream,
407                })?;
408                let status = read_fn(&mut chunks);
409                if chunks.finalize().should_transmit() {
410                    conn.wake();
411                }
412                status
413            }
414        };
415
416        match status {
417            ReadStatus::Readable(read) => Poll::Ready(Ok(Some(read))),
418            ReadStatus::Finished(read) => {
419                self.all_data_read = true;
420                Poll::Ready(Ok(read))
421            }
422            ReadStatus::Failed(read, Blocked) => match read {
423                Some(val) => Poll::Ready(Ok(Some(val))),
424                None => {
425                    if let Some(ref x) = conn.error {
426                        return Poll::Ready(Err(ReadError::ConnectionLost(x.clone())));
427                    }
428                    conn.blocked_readers.insert(self.stream, cx.waker().clone());
429                    Poll::Pending
430                }
431            },
432            ReadStatus::Failed(read, Reset(error_code)) => match read {
433                None => {
434                    self.all_data_read = true;
435                    self.reset = Some(error_code);
436                    Poll::Ready(Err(ReadError::Reset(error_code)))
437                }
438                done => {
439                    self.reset = Some(error_code);
440                    Poll::Ready(Ok(done))
441                }
442            },
443        }
444    }
445
446    /// Converts this stream into an unordered stream.
447    pub fn into_unordered(self) -> UnorderedRecvStream {
448        UnorderedRecvStream { inner: self }
449    }
450}
451
452/// A stream that can be used to receive data out-of-order.
453///
454/// Obtained by converting a [`RecvStream`] via [`RecvStream::into_unordered`].
455///
456/// This variant of `RecvStream` allows reading chunks of data *exclusively*
457/// out of order. Once you have done an unordered read, ordered reads are no
458/// longer possible since data may have been consumed out of order.
459///
460/// The stream state related fns like [`Self::id`], [`Self::is_0rtt`], [`Self::stop`], and
461/// [`Self::received_reset`] behave exactly as on [`RecvStream`].
462#[derive(Debug)]
463pub struct UnorderedRecvStream {
464    inner: RecvStream,
465}
466
467impl UnorderedRecvStream {
468    /// Reads the next segment of data.
469    ///
470    /// Yields `None` if the stream was finished. Otherwise, yields a segment of data and its
471    /// offset in the stream. Segments may be received in any order, and the `Chunk`'s `offset`
472    /// field can be used to determine ordering in the caller. Unordered reads are less prone
473    /// to head-of-line blocking within a stream, but require the application to manage
474    /// reassembling the original data.
475    ///
476    /// This operation is cancel-safe.
477    pub async fn read_chunk(&mut self, max_length: usize) -> Result<Option<Chunk>, ReadError> {
478        ReadChunk {
479            stream: &mut self.inner,
480            max_length,
481            ordered: false,
482        }
483        .await
484    }
485
486    /// Get the identity of this stream
487    pub fn id(&self) -> StreamId {
488        self.inner.id()
489    }
490
491    /// Check if this stream has been opened during 0-RTT.
492    ///
493    /// In which case any non-idempotent request should be considered dangerous at the application
494    /// level. Because read data is subject to replay attacks.
495    pub fn is_0rtt(&self) -> bool {
496        self.inner.is_0rtt()
497    }
498
499    /// Stop accepting data
500    ///
501    /// Discards unread data and notifies the peer to stop transmitting. Once stopped, further
502    /// attempts to operate on a stream will yield `ClosedStream` errors.
503    pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream> {
504        self.inner.stop(error_code)
505    }
506
507    /// Completes when the stream has been reset by the peer or otherwise closed
508    ///
509    /// Yields `Some` with the reset error code when the stream is reset by the peer. Yields `None`
510    /// when the stream was previously [`stop()`](Self::stop)ed, or when the stream was
511    /// [`finish()`](crate::SendStream::finish)ed by the peer and all data has been received, after
512    /// which it is no longer meaningful for the stream to be reset.
513    ///
514    /// This operation is cancel-safe.
515    pub async fn received_reset(&mut self) -> Result<Option<VarInt>, ResetError> {
516        self.inner.received_reset().await
517    }
518}
519
520enum ReadStatus<T> {
521    Readable(T),
522    Finished(Option<T>),
523    Failed(Option<T>, proto::ReadError),
524}
525
526impl<T> From<(Option<T>, Option<proto::ReadError>)> for ReadStatus<T> {
527    fn from(status: (Option<T>, Option<proto::ReadError>)) -> Self {
528        match status {
529            (read, None) => Self::Finished(read),
530            (read, Some(e)) => Self::Failed(read, e),
531        }
532    }
533}
534
535/// Future produced by [`RecvStream::read_to_end()`].
536///
537/// [`RecvStream::read_to_end()`]: crate::RecvStream::read_to_end
538struct ReadToEnd<'a> {
539    stream: &'a mut RecvStream,
540    read: Vec<(Bytes, u64)>,
541    start: u64,
542    end: u64,
543    size_limit: usize,
544}
545
546impl Future for ReadToEnd<'_> {
547    type Output = Result<Vec<u8>, ReadToEndError>;
548    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
549        loop {
550            match ready!(self.stream.poll_read_chunk(cx, usize::MAX, false))? {
551                Some(chunk) => {
552                    self.start = self.start.min(chunk.offset);
553                    let end = chunk.bytes.len() as u64 + chunk.offset;
554                    if (end - self.start) > self.size_limit as u64 {
555                        return Poll::Ready(Err(ReadToEndError::TooLong));
556                    }
557                    self.end = self.end.max(end);
558                    self.read.push((chunk.bytes, chunk.offset));
559                }
560                None => {
561                    if self.end == 0 {
562                        // Never received anything
563                        return Poll::Ready(Ok(Vec::new()));
564                    }
565                    let start = self.start;
566                    let mut buffer = vec![0; (self.end - start) as usize];
567                    for (data, offset) in self.read.drain(..) {
568                        let offset = (offset - start) as usize;
569                        buffer[offset..offset + data.len()].copy_from_slice(&data);
570                    }
571                    return Poll::Ready(Ok(buffer));
572                }
573            }
574        }
575    }
576}
577
578/// Errors from [`RecvStream::read_to_end`]
579#[derive(Debug, Error, Clone, PartialEq, Eq)]
580pub enum ReadToEndError {
581    /// An error occurred during reading
582    #[error("read error: {0}")]
583    Read(#[from] ReadError),
584    /// The stream is larger than the user-supplied limit
585    #[error("stream too long")]
586    TooLong,
587}
588
589#[cfg(feature = "futures-io")]
590impl futures_io::AsyncRead for RecvStream {
591    fn poll_read(
592        self: Pin<&mut Self>,
593        cx: &mut Context<'_>,
594        buf: &mut [u8],
595    ) -> Poll<io::Result<usize>> {
596        let mut buf = ReadBuf::new(buf);
597        ready!(Self::poll_read_buf(self.get_mut(), cx, &mut buf))?;
598        Poll::Ready(Ok(buf.filled().len()))
599    }
600}
601
602impl tokio::io::AsyncRead for RecvStream {
603    fn poll_read(
604        self: Pin<&mut Self>,
605        cx: &mut Context<'_>,
606        buf: &mut ReadBuf<'_>,
607    ) -> Poll<io::Result<()>> {
608        ready!(Self::poll_read_buf(self.get_mut(), cx, buf))?;
609        Poll::Ready(Ok(()))
610    }
611}
612
613impl Drop for RecvStream {
614    fn drop(&mut self) {
615        if self.all_data_read {
616            debug_assert!(
617                !self
618                    .conn
619                    .lock_without_waking("RecvStream:drop")
620                    .blocked_readers
621                    .contains_key(&self.stream),
622                "Stream {} should not have a blocked reader when all data read is true",
623                self.stream
624            );
625            return;
626        }
627        let mut conn = self.conn.lock_and_wake("RecvStream::drop");
628
629        // clean up any previously registered wakers
630        conn.blocked_readers.remove(&self.stream);
631
632        if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) {
633            conn.skip_waking();
634            return;
635        }
636
637        // Ignore ClosedStream errors
638        let _ = conn.inner.recv_stream(self.stream).stop(0u32.into());
639    }
640}
641
642/// Errors that arise from reading from a stream.
643#[derive(Debug, Error, Clone, PartialEq, Eq)]
644pub enum ReadError {
645    /// The peer abandoned transmitting data on this stream
646    ///
647    /// Carries an application-defined error code.
648    #[error("stream reset by peer: error {0}")]
649    Reset(VarInt),
650    /// The connection was lost
651    #[error("connection lost")]
652    ConnectionLost(#[from] ConnectionError),
653    /// The stream has already been stopped, finished, or reset
654    #[error("closed stream")]
655    ClosedStream,
656    /// This was a 0-RTT stream and the server rejected it
657    ///
658    /// Can only occur on clients for 0-RTT streams, which can be opened using
659    /// [`Connecting::into_0rtt()`].
660    ///
661    /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt()
662    #[error("0-RTT rejected")]
663    ZeroRttRejected,
664}
665
666impl From<ResetError> for ReadError {
667    fn from(e: ResetError) -> Self {
668        match e {
669            ResetError::ConnectionLost(e) => Self::ConnectionLost(e),
670            ResetError::ZeroRttRejected => Self::ZeroRttRejected,
671        }
672    }
673}
674
675impl From<ReadError> for io::Error {
676    fn from(x: ReadError) -> Self {
677        use ReadError::*;
678        let kind = match x {
679            Reset { .. } | ZeroRttRejected => io::ErrorKind::ConnectionReset,
680            ConnectionLost(_) | ClosedStream => io::ErrorKind::NotConnected,
681        };
682        Self::new(kind, x)
683    }
684}
685
686/// Errors that arise while waiting for a stream to be reset
687#[derive(Debug, Error, Clone, PartialEq, Eq)]
688pub enum ResetError {
689    /// The connection was lost
690    #[error("connection lost")]
691    ConnectionLost(#[from] ConnectionError),
692    /// This was a 0-RTT stream and the server rejected it
693    ///
694    /// Can only occur on clients for 0-RTT streams, which can be opened using
695    /// [`Connecting::into_0rtt()`].
696    ///
697    /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt()
698    #[error("0-RTT rejected")]
699    ZeroRttRejected,
700}
701
702impl From<ResetError> for io::Error {
703    fn from(x: ResetError) -> Self {
704        use ResetError::*;
705        let kind = match x {
706            ZeroRttRejected => io::ErrorKind::ConnectionReset,
707            ConnectionLost(_) => io::ErrorKind::NotConnected,
708        };
709        Self::new(kind, x)
710    }
711}
712
713/// Future produced by [`RecvStream::read()`].
714///
715/// [`RecvStream::read()`]: crate::RecvStream::read
716struct Read<'a> {
717    stream: &'a mut RecvStream,
718    buf: ReadBuf<'a>,
719}
720
721impl Future for Read<'_> {
722    type Output = Result<Option<usize>, ReadError>;
723
724    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
725        let this = self.get_mut();
726        ready!(this.stream.poll_read_buf(cx, &mut this.buf))?;
727        match this.buf.filled().len() {
728            0 if this.buf.capacity() != 0 => Poll::Ready(Ok(None)),
729            n => Poll::Ready(Ok(Some(n))),
730        }
731    }
732}
733
734/// Future produced by [`RecvStream::read_exact()`].
735///
736/// [`RecvStream::read_exact()`]: crate::RecvStream::read_exact
737struct ReadExact<'a> {
738    stream: &'a mut RecvStream,
739    buf: ReadBuf<'a>,
740}
741
742impl Future for ReadExact<'_> {
743    type Output = Result<(), ReadExactError>;
744    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
745        let this = self.get_mut();
746        let mut remaining = this.buf.remaining();
747        while remaining > 0 {
748            ready!(this.stream.poll_read_buf(cx, &mut this.buf))?;
749            let new = this.buf.remaining();
750            if new == remaining {
751                return Poll::Ready(Err(ReadExactError::FinishedEarly(this.buf.filled().len())));
752            }
753            remaining = new;
754        }
755        Poll::Ready(Ok(()))
756    }
757}
758
759/// Errors that arise from reading from a stream.
760#[derive(Debug, Error, Clone, PartialEq, Eq)]
761pub enum ReadExactError {
762    /// The stream finished before all bytes were read
763    #[error("stream finished early ({0} bytes read)")]
764    FinishedEarly(usize),
765    /// A read error occurred
766    #[error(transparent)]
767    ReadError(#[from] ReadError),
768}
769
770/// Future produced by [`RecvStream::read_chunk()`] or [`UnorderedRecvStream::read_chunk()`].
771///
772/// [`RecvStream::read_chunk()`]: crate::RecvStream::read_chunk
773/// [`UnorderedRecvStream::read_chunk()`]: crate::UnorderedRecvStream::read_chunk
774struct ReadChunk<'a> {
775    stream: &'a mut RecvStream,
776    max_length: usize,
777    ordered: bool,
778}
779
780impl Future for ReadChunk<'_> {
781    type Output = Result<Option<Chunk>, ReadError>;
782    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
783        let (max_length, ordered) = (self.max_length, self.ordered);
784        self.stream.poll_read_chunk(cx, max_length, ordered)
785    }
786}
787
788/// Future produced by [`RecvStream::read_many_chunks()`].
789///
790/// [`RecvStream::read_many_chunks()`]: crate::RecvStream::read_many_chunks
791struct ReadChunks<'a> {
792    stream: &'a mut RecvStream,
793    bufs: &'a mut [Bytes],
794}
795
796impl Future for ReadChunks<'_> {
797    type Output = Result<Option<usize>, ReadError>;
798    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
799        let this = self.get_mut();
800        this.stream.poll_read_chunks(cx, this.bufs)
801    }
802}