http_body/
lib.rs

1#![doc(html_root_url = "https://docs.rs/http-body/0.4.4")]
2#![deny(
3    missing_debug_implementations,
4    missing_docs,
5    unreachable_pub,
6    broken_intra_doc_links
7)]
8#![cfg_attr(test, deny(warnings))]
9
10//! Asynchronous HTTP request or response body.
11//!
12//! See [`Body`] for more details.
13//!
14//! [`Body`]: trait.Body.html
15
16mod empty;
17mod full;
18mod next;
19mod size_hint;
20
21pub mod combinators;
22
23pub use self::empty::Empty;
24pub use self::full::Full;
25pub use self::next::{Data, Trailers};
26pub use self::size_hint::SizeHint;
27
28use self::combinators::{BoxBody, MapData, MapErr, UnsyncBoxBody};
29use bytes::Buf;
30use http::HeaderMap;
31use std::ops;
32use std::pin::Pin;
33use std::task::{Context, Poll};
34
35/// Trait representing a streaming body of a Request or Response.
36///
37/// Data is streamed via the `poll_data` function, which asynchronously yields `T: Buf` values. The
38/// `size_hint` function provides insight into the total number of bytes that will be streamed.
39///
40/// The `poll_trailers` function returns an optional set of trailers used to finalize the request /
41/// response exchange. This is mostly used when using the HTTP/2.0 protocol.
42///
43pub trait Body {
44    /// Values yielded by the `Body`.
45    type Data: Buf;
46
47    /// The error type this `Body` might generate.
48    type Error;
49
50    /// Attempt to pull out the next data buffer of this stream.
51    fn poll_data(
52        self: Pin<&mut Self>,
53        cx: &mut Context<'_>,
54    ) -> Poll<Option<Result<Self::Data, Self::Error>>>;
55
56    /// Poll for an optional **single** `HeaderMap` of trailers.
57    ///
58    /// This function should only be called once `poll_data` returns `None`.
59    fn poll_trailers(
60        self: Pin<&mut Self>,
61        cx: &mut Context<'_>,
62    ) -> Poll<Result<Option<HeaderMap>, Self::Error>>;
63
64    /// Returns `true` when the end of stream has been reached.
65    ///
66    /// An end of stream means that both `poll_data` and `poll_trailers` will
67    /// return `None`.
68    ///
69    /// A return value of `false` **does not** guarantee that a value will be
70    /// returned from `poll_stream` or `poll_trailers`.
71    fn is_end_stream(&self) -> bool {
72        false
73    }
74
75    /// Returns the bounds on the remaining length of the stream.
76    ///
77    /// When the **exact** remaining length of the stream is known, the upper bound will be set and
78    /// will equal the lower bound.
79    fn size_hint(&self) -> SizeHint {
80        SizeHint::default()
81    }
82
83    /// Returns future that resolves to next data chunk, if any.
84    fn data(&mut self) -> Data<'_, Self>
85    where
86        Self: Unpin + Sized,
87    {
88        Data(self)
89    }
90
91    /// Returns future that resolves to trailers, if any.
92    fn trailers(&mut self) -> Trailers<'_, Self>
93    where
94        Self: Unpin + Sized,
95    {
96        Trailers(self)
97    }
98
99    /// Maps this body's data value to a different value.
100    fn map_data<F, B>(self, f: F) -> MapData<Self, F>
101    where
102        Self: Sized,
103        F: FnMut(Self::Data) -> B,
104        B: Buf,
105    {
106        MapData::new(self, f)
107    }
108
109    /// Maps this body's error value to a different value.
110    fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
111    where
112        Self: Sized,
113        F: FnMut(Self::Error) -> E,
114    {
115        MapErr::new(self, f)
116    }
117
118    /// Turn this body into a boxed trait object.
119    fn boxed(self) -> BoxBody<Self::Data, Self::Error>
120    where
121        Self: Sized + Send + Sync + 'static,
122    {
123        BoxBody::new(self)
124    }
125
126    /// Turn this body into a boxed trait object that is !Sync.
127    fn boxed_unsync(self) -> UnsyncBoxBody<Self::Data, Self::Error>
128    where
129        Self: Sized + Send + 'static,
130    {
131        UnsyncBoxBody::new(self)
132    }
133}
134
135impl<T: Body + Unpin + ?Sized> Body for &mut T {
136    type Data = T::Data;
137    type Error = T::Error;
138
139    fn poll_data(
140        mut self: Pin<&mut Self>,
141        cx: &mut Context<'_>,
142    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
143        Pin::new(&mut **self).poll_data(cx)
144    }
145
146    fn poll_trailers(
147        mut self: Pin<&mut Self>,
148        cx: &mut Context<'_>,
149    ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
150        Pin::new(&mut **self).poll_trailers(cx)
151    }
152
153    fn is_end_stream(&self) -> bool {
154        Pin::new(&**self).is_end_stream()
155    }
156
157    fn size_hint(&self) -> SizeHint {
158        Pin::new(&**self).size_hint()
159    }
160}
161
162impl<P> Body for Pin<P>
163where
164    P: Unpin + ops::DerefMut,
165    P::Target: Body,
166{
167    type Data = <<P as ops::Deref>::Target as Body>::Data;
168    type Error = <<P as ops::Deref>::Target as Body>::Error;
169
170    fn poll_data(
171        self: Pin<&mut Self>,
172        cx: &mut Context<'_>,
173    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
174        Pin::get_mut(self).as_mut().poll_data(cx)
175    }
176
177    fn poll_trailers(
178        self: Pin<&mut Self>,
179        cx: &mut Context<'_>,
180    ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
181        Pin::get_mut(self).as_mut().poll_trailers(cx)
182    }
183
184    fn is_end_stream(&self) -> bool {
185        self.as_ref().is_end_stream()
186    }
187
188    fn size_hint(&self) -> SizeHint {
189        self.as_ref().size_hint()
190    }
191}
192
193impl<T: Body + Unpin + ?Sized> Body for Box<T> {
194    type Data = T::Data;
195    type Error = T::Error;
196
197    fn poll_data(
198        mut self: Pin<&mut Self>,
199        cx: &mut Context<'_>,
200    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
201        Pin::new(&mut **self).poll_data(cx)
202    }
203
204    fn poll_trailers(
205        mut self: Pin<&mut Self>,
206        cx: &mut Context<'_>,
207    ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
208        Pin::new(&mut **self).poll_trailers(cx)
209    }
210
211    fn is_end_stream(&self) -> bool {
212        self.as_ref().is_end_stream()
213    }
214
215    fn size_hint(&self) -> SizeHint {
216        self.as_ref().size_hint()
217    }
218}
219
220impl<B: Body> Body for http::Request<B> {
221    type Data = B::Data;
222    type Error = B::Error;
223
224    fn poll_data(
225        self: Pin<&mut Self>,
226        cx: &mut Context<'_>,
227    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
228        unsafe {
229            self.map_unchecked_mut(http::Request::body_mut)
230                .poll_data(cx)
231        }
232    }
233
234    fn poll_trailers(
235        self: Pin<&mut Self>,
236        cx: &mut Context<'_>,
237    ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
238        unsafe {
239            self.map_unchecked_mut(http::Request::body_mut)
240                .poll_trailers(cx)
241        }
242    }
243
244    fn is_end_stream(&self) -> bool {
245        self.body().is_end_stream()
246    }
247
248    fn size_hint(&self) -> SizeHint {
249        self.body().size_hint()
250    }
251}
252
253impl<B: Body> Body for http::Response<B> {
254    type Data = B::Data;
255    type Error = B::Error;
256
257    fn poll_data(
258        self: Pin<&mut Self>,
259        cx: &mut Context<'_>,
260    ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
261        unsafe {
262            self.map_unchecked_mut(http::Response::body_mut)
263                .poll_data(cx)
264        }
265    }
266
267    fn poll_trailers(
268        self: Pin<&mut Self>,
269        cx: &mut Context<'_>,
270    ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
271        unsafe {
272            self.map_unchecked_mut(http::Response::body_mut)
273                .poll_trailers(cx)
274        }
275    }
276
277    fn is_end_stream(&self) -> bool {
278        self.body().is_end_stream()
279    }
280
281    fn size_hint(&self) -> SizeHint {
282        self.body().size_hint()
283    }
284}
285
286#[cfg(test)]
287fn _assert_bounds() {
288    fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
289}