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/// A type-erased, boxed HTTP request body.
9///
10/// `Incoming` is the concrete body type placed inside every
11/// [`Request`](http::Request) passed to the user-supplied handler. It wraps
12/// any [`Body`] implementation behind a single, heap-allocated trait object,
13/// keeping the handler signature simple regardless of the underlying transport
14/// or encoding (content-length, chunked, etc.).
15///
16/// Data frames are yielded as [`bytes::Bytes`] chunks. Trailer frames (like
17/// HTTP/1.1 chunked trailers) are forwarded transparently. The stream ends when
18/// [`Body::poll_frame`] returns `Poll::Ready(None)`.
19pub struct Incoming {
20    inner: Pin<Box<dyn Body<Data = bytes::Bytes, Error = std::io::Error> + Send + Sync>>,
21}
22
23impl Incoming {
24    #[inline]
25    pub(crate) fn new(
26        inner: impl Body<Data = bytes::Bytes, Error = std::io::Error> + Send + Sync + 'static,
27    ) -> Self {
28        Self {
29            inner: Box::pin(inner),
30        }
31    }
32}
33
34impl Body for Incoming {
35    type Data = bytes::Bytes;
36    type Error = std::io::Error;
37
38    #[inline]
39    fn poll_frame(
40        mut self: Pin<&mut Self>,
41        cx: &mut Context<'_>,
42    ) -> Poll<Option<Result<http_body::Frame<Self::Data>, Self::Error>>> {
43        self.inner.as_mut().poll_frame(cx)
44    }
45
46    #[inline]
47    fn is_end_stream(&self) -> bool {
48        self.inner.is_end_stream()
49    }
50
51    #[inline]
52    fn size_hint(&self) -> http_body::SizeHint {
53        self.inner.size_hint()
54    }
55}