1 #![doc(html_root_url = "https://docs.rs/http-body/0.4.6")]
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 
16 mod collect;
17 mod empty;
18 mod full;
19 mod limited;
20 mod next;
21 mod size_hint;
22 
23 pub mod combinators;
24 
25 pub use self::collect::Collected;
26 pub use self::empty::Empty;
27 pub use self::full::Full;
28 pub use self::limited::{LengthLimitError, Limited};
29 pub use self::next::{Data, Trailers};
30 pub use self::size_hint::SizeHint;
31 
32 use self::combinators::{BoxBody, MapData, MapErr, UnsyncBoxBody};
33 use bytes::{Buf, Bytes};
34 use http::HeaderMap;
35 use std::convert::Infallible;
36 use std::ops;
37 use std::pin::Pin;
38 use std::task::{Context, Poll};
39 
40 /// Trait representing a streaming body of a Request or Response.
41 ///
42 /// Data is streamed via the `poll_data` function, which asynchronously yields `T: Buf` values. The
43 /// `size_hint` function provides insight into the total number of bytes that will be streamed.
44 ///
45 /// The `poll_trailers` function returns an optional set of trailers used to finalize the request /
46 /// response exchange. This is mostly used when using the HTTP/2.0 protocol.
47 ///
48 pub trait Body {
49     /// Values yielded by the `Body`.
50     type Data: Buf;
51 
52     /// The error type this `Body` might generate.
53     type Error;
54 
55     /// Attempt to pull out the next data buffer of this stream.
poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>56     fn poll_data(
57         self: Pin<&mut Self>,
58         cx: &mut Context<'_>,
59     ) -> Poll<Option<Result<Self::Data, Self::Error>>>;
60 
61     /// Poll for an optional **single** `HeaderMap` of trailers.
62     ///
63     /// This function should only be called once `poll_data` returns `None`.
poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>64     fn poll_trailers(
65         self: Pin<&mut Self>,
66         cx: &mut Context<'_>,
67     ) -> Poll<Result<Option<HeaderMap>, Self::Error>>;
68 
69     /// Returns `true` when the end of stream has been reached.
70     ///
71     /// An end of stream means that both `poll_data` and `poll_trailers` will
72     /// return `None`.
73     ///
74     /// A return value of `false` **does not** guarantee that a value will be
75     /// returned from `poll_stream` or `poll_trailers`.
is_end_stream(&self) -> bool76     fn is_end_stream(&self) -> bool {
77         false
78     }
79 
80     /// Returns the bounds on the remaining length of the stream.
81     ///
82     /// When the **exact** remaining length of the stream is known, the upper bound will be set and
83     /// will equal the lower bound.
size_hint(&self) -> SizeHint84     fn size_hint(&self) -> SizeHint {
85         SizeHint::default()
86     }
87 
88     /// Returns future that resolves to next data chunk, if any.
data(&mut self) -> Data<'_, Self> where Self: Unpin + Sized,89     fn data(&mut self) -> Data<'_, Self>
90     where
91         Self: Unpin + Sized,
92     {
93         Data(self)
94     }
95 
96     /// Returns future that resolves to trailers, if any.
trailers(&mut self) -> Trailers<'_, Self> where Self: Unpin + Sized,97     fn trailers(&mut self) -> Trailers<'_, Self>
98     where
99         Self: Unpin + Sized,
100     {
101         Trailers(self)
102     }
103 
104     /// Maps this body's data value to a different value.
map_data<F, B>(self, f: F) -> MapData<Self, F> where Self: Sized, F: FnMut(Self::Data) -> B, B: Buf,105     fn map_data<F, B>(self, f: F) -> MapData<Self, F>
106     where
107         Self: Sized,
108         F: FnMut(Self::Data) -> B,
109         B: Buf,
110     {
111         MapData::new(self, f)
112     }
113 
114     /// Maps this body's error value to a different value.
map_err<F, E>(self, f: F) -> MapErr<Self, F> where Self: Sized, F: FnMut(Self::Error) -> E,115     fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
116     where
117         Self: Sized,
118         F: FnMut(Self::Error) -> E,
119     {
120         MapErr::new(self, f)
121     }
122 
123     /// Turn this body into [`Collected`] body which will collect all the DATA frames
124     /// and trailers.
collect(self) -> crate::collect::Collect<Self> where Self: Sized,125     fn collect(self) -> crate::collect::Collect<Self>
126     where
127         Self: Sized,
128     {
129         collect::Collect::new(self)
130     }
131 
132     /// Turn this body into a boxed trait object.
boxed(self) -> BoxBody<Self::Data, Self::Error> where Self: Sized + Send + Sync + 'static,133     fn boxed(self) -> BoxBody<Self::Data, Self::Error>
134     where
135         Self: Sized + Send + Sync + 'static,
136     {
137         BoxBody::new(self)
138     }
139 
140     /// Turn this body into a boxed trait object that is !Sync.
boxed_unsync(self) -> UnsyncBoxBody<Self::Data, Self::Error> where Self: Sized + Send + 'static,141     fn boxed_unsync(self) -> UnsyncBoxBody<Self::Data, Self::Error>
142     where
143         Self: Sized + Send + 'static,
144     {
145         UnsyncBoxBody::new(self)
146     }
147 }
148 
149 impl<T: Body + Unpin + ?Sized> Body for &mut T {
150     type Data = T::Data;
151     type Error = T::Error;
152 
poll_data( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>153     fn poll_data(
154         mut self: Pin<&mut Self>,
155         cx: &mut Context<'_>,
156     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
157         Pin::new(&mut **self).poll_data(cx)
158     }
159 
poll_trailers( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>160     fn poll_trailers(
161         mut self: Pin<&mut Self>,
162         cx: &mut Context<'_>,
163     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
164         Pin::new(&mut **self).poll_trailers(cx)
165     }
166 
is_end_stream(&self) -> bool167     fn is_end_stream(&self) -> bool {
168         Pin::new(&**self).is_end_stream()
169     }
170 
size_hint(&self) -> SizeHint171     fn size_hint(&self) -> SizeHint {
172         Pin::new(&**self).size_hint()
173     }
174 }
175 
176 impl<P> Body for Pin<P>
177 where
178     P: Unpin + ops::DerefMut,
179     P::Target: Body,
180 {
181     type Data = <<P as ops::Deref>::Target as Body>::Data;
182     type Error = <<P as ops::Deref>::Target as Body>::Error;
183 
poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>184     fn poll_data(
185         self: Pin<&mut Self>,
186         cx: &mut Context<'_>,
187     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
188         Pin::get_mut(self).as_mut().poll_data(cx)
189     }
190 
poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>191     fn poll_trailers(
192         self: Pin<&mut Self>,
193         cx: &mut Context<'_>,
194     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
195         Pin::get_mut(self).as_mut().poll_trailers(cx)
196     }
197 
is_end_stream(&self) -> bool198     fn is_end_stream(&self) -> bool {
199         self.as_ref().is_end_stream()
200     }
201 
size_hint(&self) -> SizeHint202     fn size_hint(&self) -> SizeHint {
203         self.as_ref().size_hint()
204     }
205 }
206 
207 impl<T: Body + Unpin + ?Sized> Body for Box<T> {
208     type Data = T::Data;
209     type Error = T::Error;
210 
poll_data( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>211     fn poll_data(
212         mut self: Pin<&mut Self>,
213         cx: &mut Context<'_>,
214     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
215         Pin::new(&mut **self).poll_data(cx)
216     }
217 
poll_trailers( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>218     fn poll_trailers(
219         mut self: Pin<&mut Self>,
220         cx: &mut Context<'_>,
221     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
222         Pin::new(&mut **self).poll_trailers(cx)
223     }
224 
is_end_stream(&self) -> bool225     fn is_end_stream(&self) -> bool {
226         self.as_ref().is_end_stream()
227     }
228 
size_hint(&self) -> SizeHint229     fn size_hint(&self) -> SizeHint {
230         self.as_ref().size_hint()
231     }
232 }
233 
234 impl<B: Body> Body for http::Request<B> {
235     type Data = B::Data;
236     type Error = B::Error;
237 
poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>238     fn poll_data(
239         self: Pin<&mut Self>,
240         cx: &mut Context<'_>,
241     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
242         unsafe {
243             self.map_unchecked_mut(http::Request::body_mut)
244                 .poll_data(cx)
245         }
246     }
247 
poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>248     fn poll_trailers(
249         self: Pin<&mut Self>,
250         cx: &mut Context<'_>,
251     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
252         unsafe {
253             self.map_unchecked_mut(http::Request::body_mut)
254                 .poll_trailers(cx)
255         }
256     }
257 
is_end_stream(&self) -> bool258     fn is_end_stream(&self) -> bool {
259         self.body().is_end_stream()
260     }
261 
size_hint(&self) -> SizeHint262     fn size_hint(&self) -> SizeHint {
263         self.body().size_hint()
264     }
265 }
266 
267 impl<B: Body> Body for http::Response<B> {
268     type Data = B::Data;
269     type Error = B::Error;
270 
poll_data( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>271     fn poll_data(
272         self: Pin<&mut Self>,
273         cx: &mut Context<'_>,
274     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
275         unsafe {
276             self.map_unchecked_mut(http::Response::body_mut)
277                 .poll_data(cx)
278         }
279     }
280 
poll_trailers( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>281     fn poll_trailers(
282         self: Pin<&mut Self>,
283         cx: &mut Context<'_>,
284     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
285         unsafe {
286             self.map_unchecked_mut(http::Response::body_mut)
287                 .poll_trailers(cx)
288         }
289     }
290 
is_end_stream(&self) -> bool291     fn is_end_stream(&self) -> bool {
292         self.body().is_end_stream()
293     }
294 
size_hint(&self) -> SizeHint295     fn size_hint(&self) -> SizeHint {
296         self.body().size_hint()
297     }
298 }
299 
300 impl Body for String {
301     type Data = Bytes;
302     type Error = Infallible;
303 
poll_data( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>304     fn poll_data(
305         mut self: Pin<&mut Self>,
306         _cx: &mut Context<'_>,
307     ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
308         if !self.is_empty() {
309             let s = std::mem::take(&mut *self);
310             Poll::Ready(Some(Ok(s.into_bytes().into())))
311         } else {
312             Poll::Ready(None)
313         }
314     }
315 
poll_trailers( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>316     fn poll_trailers(
317         self: Pin<&mut Self>,
318         _cx: &mut Context<'_>,
319     ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
320         Poll::Ready(Ok(None))
321     }
322 
is_end_stream(&self) -> bool323     fn is_end_stream(&self) -> bool {
324         self.is_empty()
325     }
326 
size_hint(&self) -> SizeHint327     fn size_hint(&self) -> SizeHint {
328         SizeHint::with_exact(self.len() as u64)
329     }
330 }
331 
332 #[cfg(test)]
_assert_bounds()333 fn _assert_bounds() {
334     fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
335 }
336