1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#![doc(html_root_url = "https://docs.rs/http-body/0.1.0")]
#![deny(missing_debug_implementations, missing_docs, unreachable_pub)]
#![cfg_attr(test, deny(warnings))]
//! Asynchronous HTTP request or response body.
//!
//! See [`Body`] for more details.
//!
//! [`Body`]: trait.Body.html
extern crate bytes;
extern crate futures;
extern crate http;
extern crate tokio_buf;
use bytes::Buf;
use futures::{Async, Poll};
use http::HeaderMap;
use tokio_buf::{BufStream, SizeHint};
/// Trait representing a streaming body of a Request or Response.
///
/// Data is streamed via the `poll_data` function, which asynchronously yields `T: Buf` values. The
/// `size_hint` function provides insight into the total number of bytes that will be streamed.
///
/// The `poll_trailers` function returns an optional set of trailers used to finalize the request /
/// response exchange. This is mostly used when using the HTTP/2.0 protocol.
///
/// # Relation with [`BufStream`].
///
/// The `Body` trait is a superset of the `BufStream` trait. However, `BufStream` is not considered
/// a super trait of `Body`. Instead, a `T: Body` can be thought of as containing a `BufStream` as
/// well as the HTTP trailers.
///
/// There exists is a blanket implementation of `Body` for `T: BufStream`. In other words, any type
/// that implements `BufStream` also implements `Body` yielding no trailers.
///
/// [`BufStream`]: https://docs.rs/tokio-buf/0.1.1/tokio_buf/trait.BufStream.html
///
pub trait Body {
/// Values yielded by the `Body`.
type Data: Buf;
/// The error type this `BufStream` might generate.
type Error;
/// Attempt to pull out the next data buffer of this stream.
fn poll_data(&mut self) -> Poll<Option<Self::Data>, Self::Error>;
/// Returns the bounds on the remaining length of the stream.
///
/// When the **exact** remaining length of the stream is known, the upper bound will be set and
/// will equal the lower bound.
fn size_hint(&self) -> SizeHint {
SizeHint::default()
}
/// Poll for an optional **single** `HeaderMap` of trailers.
///
/// This function should only be called once `poll_data` returns `None`.
fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, Self::Error>;
/// Returns `true` when the end of stream has been reached.
///
/// An end of stream means that both `poll_data` and `poll_trailers` will
/// return `None`.
///
/// A return value of `false` **does not** guarantee that a value will be
/// returned from `poll_stream` or `poll_trailers`.
fn is_end_stream(&self) -> bool {
false
}
}
impl<T: BufStream> Body for T {
type Data = T::Item;
type Error = T::Error;
fn poll_data(&mut self) -> Poll<Option<Self::Data>, Self::Error> {
BufStream::poll_buf(self)
}
fn size_hint(&self) -> SizeHint {
BufStream::size_hint(self)
}
fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, Self::Error> {
Ok(Async::Ready(None))
}
fn is_end_stream(&self) -> bool {
let size_hint = self.size_hint();
size_hint
.upper()
.map(|upper| upper == 0 && upper == size_hint.lower())
.unwrap_or(false)
}
}