Skip to main content

vibeio_http/
incoming.rs

1use std::{
2    pin::Pin,
3    task::{Context, Poll},
4};
5
6use http_body::Body;
7
8#[cfg(feature = "h2")]
9use crate::H2Body;
10#[cfg(feature = "h1")]
11use crate::Http1Body;
12
13/// An incoming HTTP request body.
14///
15/// `Incoming` is the concrete body type placed inside every
16/// [`Request`](http::Request) passed to the user-supplied handler.
17///
18/// Data frames are yielded as [`bytes::Bytes`] chunks. Trailer frames (like
19/// HTTP/1.1 chunked trailers) are forwarded transparently. The stream ends when
20/// [`Body::poll_frame`] returns `Poll::Ready(None)`.
21#[allow(private_interfaces)]
22pub enum Incoming {
23    #[cfg(feature = "h1")]
24    H1(Http1Body),
25    #[cfg(feature = "h2")]
26    H2(H2Body),
27    #[cfg(feature = "h3")]
28    Boxed(Pin<Box<dyn Body<Data = bytes::Bytes, Error = std::io::Error> + Send + Sync>>),
29}
30
31impl Body for Incoming {
32    type Data = bytes::Bytes;
33    type Error = std::io::Error;
34
35    #[inline]
36    fn poll_frame(
37        self: Pin<&mut Self>,
38        cx: &mut Context<'_>,
39    ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {
40        match self.get_mut() {
41            #[cfg(feature = "h1")]
42            Self::H1(ref mut inner) => Pin::new(inner).poll_frame(cx),
43            #[cfg(feature = "h2")]
44            Self::H2(ref mut inner) => Pin::new(inner).poll_frame(cx),
45            #[cfg(feature = "h3")]
46            Self::Boxed(inner) => inner.as_mut().poll_frame(cx),
47        }
48    }
49
50    #[inline]
51    fn is_end_stream(&self) -> bool {
52        match self {
53            #[cfg(feature = "h1")]
54            Self::H1(inner) => inner.is_end_stream(),
55            #[cfg(feature = "h2")]
56            Self::H2(inner) => inner.is_end_stream(),
57            #[cfg(feature = "h3")]
58            Self::Boxed(inner) => inner.is_end_stream(),
59        }
60    }
61
62    #[inline]
63    fn size_hint(&self) -> http_body::SizeHint {
64        match self {
65            #[cfg(feature = "h1")]
66            Self::H1(inner) => inner.size_hint(),
67            #[cfg(feature = "h2")]
68            Self::H2(inner) => inner.size_hint(),
69            #[cfg(feature = "h3")]
70            Self::Boxed(inner) => inner.size_hint(),
71        }
72    }
73}