| @@ -1,20 +1,14 @@ | ||||
| use std::borrow::Cow; | ||||
| #[cfg(feature = "stream")] | ||||
| use std::error::Error as StdError; | ||||
| use std::fmt; | ||||
|  | ||||
| use bytes::Bytes; | ||||
| use futures_channel::mpsc; | ||||
| use futures_channel::oneshot; | ||||
| use futures_core::Stream; // for mpsc::Receiver | ||||
| #[cfg(feature = "stream")] | ||||
| use futures_util::TryStreamExt; | ||||
| use http::HeaderMap; | ||||
| use http_body::{Body as HttpBody, SizeHint}; | ||||
|  | ||||
| use super::DecodedLength; | ||||
| #[cfg(feature = "stream")] | ||||
| use crate::common::sync_wrapper::SyncWrapper; | ||||
| use crate::common::Future; | ||||
| #[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))] | ||||
| use crate::common::Never; | ||||
| @@ -56,12 +50,6 @@ enum Kind { | ||||
|     }, | ||||
|     #[cfg(feature = "ffi")] | ||||
|     Ffi(crate::ffi::UserBody), | ||||
|     #[cfg(feature = "stream")] | ||||
|     Wrapped( | ||||
|         SyncWrapper< | ||||
|             Pin<Box<dyn Stream<Item = Result<Bytes, Box<dyn StdError + Send + Sync>>> + Send>>, | ||||
|         >, | ||||
|     ), | ||||
| } | ||||
|  | ||||
| struct Extra { | ||||
| @@ -164,39 +152,6 @@ impl Body { | ||||
|         (tx, rx) | ||||
|     } | ||||
|  | ||||
|     /// Wrap a futures `Stream` in a box inside `Body`. | ||||
|     /// | ||||
|     /// # Example | ||||
|     /// | ||||
|     /// ``` | ||||
|     /// # use hyper::Body; | ||||
|     /// let chunks: Vec<Result<_, std::io::Error>> = vec![ | ||||
|     ///     Ok("hello"), | ||||
|     ///     Ok(" "), | ||||
|     ///     Ok("world"), | ||||
|     /// ]; | ||||
|     /// | ||||
|     /// let stream = futures_util::stream::iter(chunks); | ||||
|     /// | ||||
|     /// let body = Body::wrap_stream(stream); | ||||
|     /// ``` | ||||
|     /// | ||||
|     /// # Optional | ||||
|     /// | ||||
|     /// This function requires enabling the `stream` feature in your | ||||
|     /// `Cargo.toml`. | ||||
|     #[cfg(feature = "stream")] | ||||
|     #[cfg_attr(docsrs, doc(cfg(feature = "stream")))] | ||||
|     pub fn wrap_stream<S, O, E>(stream: S) -> Body | ||||
|     where | ||||
|         S: Stream<Item = Result<O, E>> + Send + 'static, | ||||
|         O: Into<Bytes> + 'static, | ||||
|         E: Into<Box<dyn StdError + Send + Sync>> + 'static, | ||||
|     { | ||||
|         let mapped = stream.map_ok(Into::into).map_err(Into::into); | ||||
|         Body::new(Kind::Wrapped(SyncWrapper::new(Box::pin(mapped)))) | ||||
|     } | ||||
|  | ||||
|     fn new(kind: Kind) -> Body { | ||||
|         Body { kind, extra: None } | ||||
|     } | ||||
| @@ -329,12 +284,6 @@ impl Body { | ||||
|  | ||||
|             #[cfg(feature = "ffi")] | ||||
|             Kind::Ffi(ref mut body) => body.poll_data(cx), | ||||
|  | ||||
|             #[cfg(feature = "stream")] | ||||
|             Kind::Wrapped(ref mut s) => match ready!(s.get_mut().as_mut().poll_next(cx)) { | ||||
|                 Some(res) => Poll::Ready(Some(res.map_err(crate::Error::new_body))), | ||||
|                 None => Poll::Ready(None), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -405,8 +354,6 @@ impl HttpBody for Body { | ||||
|             Kind::H2 { recv: ref h2, .. } => h2.is_end_stream(), | ||||
|             #[cfg(feature = "ffi")] | ||||
|             Kind::Ffi(..) => false, | ||||
|             #[cfg(feature = "stream")] | ||||
|             Kind::Wrapped(..) => false, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -426,8 +373,6 @@ impl HttpBody for Body { | ||||
|         match self.kind { | ||||
|             Kind::Once(Some(ref val)) => SizeHint::with_exact(val.len() as u64), | ||||
|             Kind::Once(None) => SizeHint::with_exact(0), | ||||
|             #[cfg(feature = "stream")] | ||||
|             Kind::Wrapped(..) => SizeHint::default(), | ||||
|             Kind::Chan { content_length, .. } => opt_len!(content_length), | ||||
|             #[cfg(all(feature = "http2", any(feature = "client", feature = "server")))] | ||||
|             Kind::H2 { content_length, .. } => opt_len!(content_length), | ||||
| @@ -457,33 +402,6 @@ impl fmt::Debug for Body { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// # Optional | ||||
| /// | ||||
| /// This function requires enabling the `stream` feature in your | ||||
| /// `Cargo.toml`. | ||||
| #[cfg(feature = "stream")] | ||||
| impl Stream for Body { | ||||
|     type Item = crate::Result<Bytes>; | ||||
|  | ||||
|     fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> { | ||||
|         HttpBody::poll_data(self, cx) | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// # Optional | ||||
| /// | ||||
| /// This function requires enabling the `stream` feature in your | ||||
| /// `Cargo.toml`. | ||||
| #[cfg(feature = "stream")] | ||||
| impl From<Box<dyn Stream<Item = Result<Bytes, Box<dyn StdError + Send + Sync>>> + Send>> for Body { | ||||
|     #[inline] | ||||
|     fn from( | ||||
|         stream: Box<dyn Stream<Item = Result<Bytes, Box<dyn StdError + Send + Sync>>> + Send>, | ||||
|     ) -> Body { | ||||
|         Body::new(Kind::Wrapped(SyncWrapper::new(stream.into()))) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<Bytes> for Body { | ||||
|     #[inline] | ||||
|     fn from(chunk: Bytes) -> Body { | ||||
|   | ||||
| @@ -18,10 +18,7 @@ pub(crate) mod io; | ||||
| #[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))] | ||||
| mod lazy; | ||||
| mod never; | ||||
| #[cfg(any( | ||||
|     feature = "stream", | ||||
|     all(feature = "client", any(feature = "http1", feature = "http2")) | ||||
| ))] | ||||
| #[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))] | ||||
| pub(crate) mod sync_wrapper; | ||||
| pub(crate) mod task; | ||||
| pub(crate) mod watch; | ||||
|   | ||||
| @@ -48,7 +48,7 @@ pub(super) enum Kind { | ||||
|     #[cfg(all(feature = "http1", feature = "server", feature = "runtime"))] | ||||
|     HeaderTimeout, | ||||
|     /// Error while reading a body from connection. | ||||
|     #[cfg(any(feature = "http1", feature = "http2", feature = "stream"))] | ||||
|     #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|     Body, | ||||
|     /// Error while writing a body to connection. | ||||
|     #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| @@ -294,7 +294,7 @@ impl Error { | ||||
|         Error::new(Kind::ChannelClosed) | ||||
|     } | ||||
|  | ||||
|     #[cfg(any(feature = "http1", feature = "http2", feature = "stream"))] | ||||
|     #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|     pub(super) fn new_body<E: Into<Cause>>(cause: E) -> Error { | ||||
|         Error::new(Kind::Body).with(cause) | ||||
|     } | ||||
| @@ -440,7 +440,7 @@ impl Error { | ||||
|             Kind::Accept => "error accepting connection", | ||||
|             #[cfg(all(feature = "http1", feature = "server", feature = "runtime"))] | ||||
|             Kind::HeaderTimeout => "read header from client timeout", | ||||
|             #[cfg(any(feature = "http1", feature = "http2", feature = "stream"))] | ||||
|             #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|             Kind::Body => "error reading a body from connection", | ||||
|             #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|             Kind::BodyWrite => "error writing a body to connection", | ||||
|   | ||||
| @@ -52,7 +52,6 @@ | ||||
| //! - `runtime`: Enables convenient integration with `tokio`, providing | ||||
| //!   connectors and acceptors for TCP, and a default executor. | ||||
| //! - `tcp`: Enables convenient implementations over TCP (using tokio). | ||||
| //! - `stream`: Provides `futures::Stream` capabilities. | ||||
| //! | ||||
| //! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section | ||||
|  | ||||
|   | ||||
| @@ -6,11 +6,6 @@ | ||||
| //!   connections. | ||||
| //! - Utilities like `poll_fn` to ease creating a custom `Accept`. | ||||
|  | ||||
| #[cfg(feature = "stream")] | ||||
| use futures_core::Stream; | ||||
| #[cfg(feature = "stream")] | ||||
| use pin_project_lite::pin_project; | ||||
|  | ||||
| use crate::common::{ | ||||
|     task::{self, Poll}, | ||||
|     Pin, | ||||
| @@ -74,38 +69,3 @@ where | ||||
|  | ||||
|     PollFn(func) | ||||
| } | ||||
|  | ||||
| /// Adapt a `Stream` of incoming connections into an `Accept`. | ||||
| /// | ||||
| /// # Optional | ||||
| /// | ||||
| /// This function requires enabling the `stream` feature in your | ||||
| /// `Cargo.toml`. | ||||
| #[cfg(feature = "stream")] | ||||
| pub fn from_stream<S, IO, E>(stream: S) -> impl Accept<Conn = IO, Error = E> | ||||
| where | ||||
|     S: Stream<Item = Result<IO, E>>, | ||||
| { | ||||
|     pin_project! { | ||||
|         struct FromStream<S> { | ||||
|             #[pin] | ||||
|             stream: S, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     impl<S, IO, E> Accept for FromStream<S> | ||||
|     where | ||||
|         S: Stream<Item = Result<IO, E>>, | ||||
|     { | ||||
|         type Conn = IO; | ||||
|         type Error = E; | ||||
|         fn poll_accept( | ||||
|             self: Pin<&mut Self>, | ||||
|             cx: &mut task::Context<'_>, | ||||
|         ) -> Poll<Option<Result<Self::Conn, Self::Error>>> { | ||||
|             self.project().stream.poll_next(cx) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     FromStream { stream } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user