feat(body): Update Payload to be a trait alias of http_body::Body (#1908)
This commit is contained in:
committed by
Sean McArthur
parent
49b12c415d
commit
79c32f8953
@@ -6,7 +6,7 @@ use bytes::Bytes;
|
||||
use futures_core::{Stream, TryStream};
|
||||
use futures_channel::{mpsc, oneshot};
|
||||
use futures_util::TryStreamExt;
|
||||
//use tokio_buf::SizeHint;
|
||||
use http_body::{SizeHint, Body as HttpBody};
|
||||
use http::HeaderMap;
|
||||
|
||||
use crate::common::{Future, Never, Pin, Poll, task};
|
||||
@@ -296,7 +296,7 @@ impl Default for Body {
|
||||
}
|
||||
}
|
||||
|
||||
impl Payload for Body {
|
||||
impl HttpBody for Body {
|
||||
type Data = Chunk;
|
||||
type Error = crate::Error;
|
||||
|
||||
@@ -304,14 +304,13 @@ impl Payload for Body {
|
||||
self.poll_eof(cx)
|
||||
}
|
||||
|
||||
fn poll_trailers(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<HeaderMap, Self::Error>>> {
|
||||
fn poll_trailers(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
|
||||
match self.kind {
|
||||
Kind::H2 { recv: ref mut h2, .. } => match ready!(h2.poll_trailers(cx)) {
|
||||
Ok(Some(t)) => Poll::Ready(Some(Ok(t))),
|
||||
Err(e) => Poll::Ready(Some(Err(crate::Error::new_h2(e)))),
|
||||
Ok(None) => Poll::Ready(None),
|
||||
Ok(t) => Poll::Ready(Ok(t)),
|
||||
Err(e) => Poll::Ready(Err(crate::Error::new_h2(e))),
|
||||
},
|
||||
_ => Poll::Ready(None),
|
||||
_ => Poll::Ready(Ok(None)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,21 +323,26 @@ impl Payload for Body {
|
||||
}
|
||||
}
|
||||
|
||||
fn content_length(&self) -> Option<u64> {
|
||||
fn size_hint(&self) -> SizeHint {
|
||||
match self.kind {
|
||||
Kind::Once(Some(ref val)) => Some(val.len() as u64),
|
||||
Kind::Once(None) => Some(0),
|
||||
Kind::Wrapped(..) => None,
|
||||
Kind::Chan { content_length, .. } | Kind::H2 { content_length, .. } => content_length,
|
||||
}
|
||||
}
|
||||
Kind::Once(Some(ref val)) => {
|
||||
let mut hint = SizeHint::default();
|
||||
hint.set_exact(val.len() as u64);
|
||||
hint
|
||||
},
|
||||
Kind::Once(None) => {
|
||||
SizeHint::default()
|
||||
},
|
||||
Kind::Wrapped(..) => SizeHint::default(),
|
||||
Kind::Chan { content_length, .. } | Kind::H2 { content_length, .. } => {
|
||||
let mut hint = SizeHint::default();
|
||||
|
||||
// We can improve the performance of `Body` when we know it is a Once kind.
|
||||
#[doc(hidden)]
|
||||
fn __hyper_full_data(&mut self, _: FullDataArg) -> FullDataRet<Self::Data> {
|
||||
match self.kind {
|
||||
Kind::Once(ref mut val) => FullDataRet(val.take()),
|
||||
_ => FullDataRet(None),
|
||||
if let Some(content_length) = content_length {
|
||||
hint.set_exact(content_length as u64);
|
||||
}
|
||||
|
||||
hint
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,43 +367,11 @@ impl fmt::Debug for Body {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl ::http_body::Body for Body {
|
||||
type Data = Chunk;
|
||||
type Error = crate::Error;
|
||||
|
||||
fn poll_data(&mut self) -> Poll<Option<Self::Data>, Self::Error> {
|
||||
<Self as Payload>::poll_data(self)
|
||||
}
|
||||
|
||||
fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, Self::Error> {
|
||||
<Self as Payload>::poll_trailers(self)
|
||||
}
|
||||
|
||||
fn is_end_stream(&self) -> bool {
|
||||
<Self as Payload>::is_end_stream(self)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> SizeHint {
|
||||
let mut hint = SizeHint::default();
|
||||
|
||||
let content_length = <Self as Payload>::content_length(self);
|
||||
|
||||
if let Some(size) = content_length {
|
||||
hint.set_upper(size);
|
||||
hint.set_lower(size)
|
||||
}
|
||||
|
||||
hint
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl Stream for Body {
|
||||
type Item = crate::Result<Chunk>;
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
self.poll_data(cx)
|
||||
HttpBody::poll_data(self, cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@ use http::HeaderMap;
|
||||
|
||||
use crate::common::{Pin, Poll, task};
|
||||
use super::internal::{FullDataArg, FullDataRet};
|
||||
use http_body::{Body as HttpBody, SizeHint};
|
||||
|
||||
/// This trait represents a streaming body of a `Request` or `Response`.
|
||||
///
|
||||
/// The built-in implementation of this trait is [`Body`](::Body), in case you
|
||||
/// don't need to customize a send stream for your own application.
|
||||
pub trait Payload: Send + 'static {
|
||||
pub trait Payload: sealed::Sealed + Send + 'static {
|
||||
/// A buffer of bytes representing a single chunk of a body.
|
||||
type Data: Buf + Send;
|
||||
|
||||
@@ -28,9 +29,9 @@ pub trait Payload: Send + 'static {
|
||||
/// This should **only** be called after `poll_data` has ended.
|
||||
///
|
||||
/// Note: Trailers aren't currently used for HTTP/1, only for HTTP/2.
|
||||
fn poll_trailers(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<HeaderMap, Self::Error>>> {
|
||||
fn poll_trailers(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
|
||||
drop(cx);
|
||||
Poll::Ready(None)
|
||||
Poll::Ready(Ok(None))
|
||||
}
|
||||
|
||||
/// A hint that the `Body` is complete, and doesn't need to be polled more.
|
||||
@@ -48,27 +49,56 @@ pub trait Payload: Send + 'static {
|
||||
false
|
||||
}
|
||||
|
||||
/// Return a length of the total bytes that will be streamed, if known.
|
||||
/// Returns a `SizeHint` providing an upper and lower bound on the possible size.
|
||||
///
|
||||
/// If an exact size of bytes is known, this would allow hyper to send a
|
||||
/// `Content-Length` header automatically, not needing to fall back to
|
||||
/// `Transfer-Encoding: chunked`.
|
||||
/// If there is an exact size of bytes known, this would allow hyper to
|
||||
/// send a `Content-Length` header automatically, not needing to fall back to
|
||||
/// `TransferEncoding: chunked`.
|
||||
///
|
||||
/// This does not need to be kept updated after polls, it will only be
|
||||
/// called once to create the headers.
|
||||
fn content_length(&self) -> Option<u64> {
|
||||
None
|
||||
fn size_hint(&self) -> SizeHint {
|
||||
SizeHint::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T> Payload for T
|
||||
where
|
||||
T: HttpBody + Send + 'static,
|
||||
T::Data: Send,
|
||||
T::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||
{
|
||||
type Data = T::Data;
|
||||
type Error = T::Error;
|
||||
|
||||
fn poll_data(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>> {
|
||||
HttpBody::poll_data(self, cx)
|
||||
}
|
||||
|
||||
// This API is unstable, and is impossible to use outside of hyper. Some
|
||||
// form of it may become stable in a later version.
|
||||
//
|
||||
// The only thing a user *could* do is reference the method, but DON'T
|
||||
// DO THAT! :)
|
||||
#[doc(hidden)]
|
||||
fn __hyper_full_data(&mut self, _: FullDataArg) -> FullDataRet<Self::Data> {
|
||||
FullDataRet(None)
|
||||
fn poll_trailers(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
|
||||
HttpBody::poll_trailers(self, cx)
|
||||
}
|
||||
|
||||
fn is_end_stream(&self) -> bool {
|
||||
HttpBody::is_end_stream(self)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> SizeHint {
|
||||
HttpBody::size_hint(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> sealed::Sealed for T
|
||||
where
|
||||
T: HttpBody + Send + 'static,
|
||||
T::Data: Send,
|
||||
T::Error: Into<Box<dyn StdError + Send + Sync>>,
|
||||
{
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user