@@ -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