From aac0e2dd57244d13e0972b46148fd1cbe4a9f509 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 19 Apr 2020 21:59:52 +0200 Subject: [PATCH] refactor(body): use HttpBody with extra bounds instead of Payload trait --- src/body/mod.rs | 5 +- src/body/payload.rs | 139 --------------------------------------- src/client/conn.rs | 36 ++++++---- src/client/mod.rs | 21 +++--- src/client/service.rs | 7 +- src/common/exec.rs | 8 +-- src/error.rs | 4 +- src/proto/h1/dispatch.rs | 14 ++-- src/proto/h1/encode.rs | 2 +- src/proto/h1/role.rs | 6 +- src/proto/h2/client.rs | 12 ++-- src/proto/h2/mod.rs | 10 +-- src/proto/h2/server.rs | 26 ++++---- src/server/conn.rs | 38 +++++++---- src/server/mod.rs | 11 ++-- src/server/shutdown.rs | 10 ++- src/service/http.rs | 10 +-- src/service/make.rs | 12 ++-- src/service/util.rs | 6 +- tests/server.rs | 8 +-- 20 files changed, 142 insertions(+), 243 deletions(-) delete mode 100644 src/body/payload.rs diff --git a/src/body/mod.rs b/src/body/mod.rs index 4693cbc8..ce704f5b 100644 --- a/src/body/mod.rs +++ b/src/body/mod.rs @@ -22,17 +22,14 @@ pub use self::aggregate::aggregate; pub use self::body::{Body, Sender}; pub use self::to_bytes::to_bytes; -pub(crate) use self::payload::Payload; - mod aggregate; mod body; -mod payload; mod to_bytes; /// An optimization to try to take a full body if immediately available. /// /// This is currently limited to *only* `hyper::Body`s. -pub(crate) fn take_full_data(body: &mut T) -> Option { +pub(crate) fn take_full_data(body: &mut T) -> Option { use std::any::{Any, TypeId}; // This static type check can be optimized at compile-time. diff --git a/src/body/payload.rs b/src/body/payload.rs deleted file mode 100644 index f24adad1..00000000 --- a/src/body/payload.rs +++ /dev/null @@ -1,139 +0,0 @@ -use std::error::Error as StdError; - -use bytes::Buf; -use http::HeaderMap; - -use crate::common::{task, Pin, Poll}; -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: sealed::Sealed + Send + 'static { - /// A buffer of bytes representing a single chunk of a body. - type Data: Buf + Send; - - /// The error type of this stream. - type Error: Into>; - - /// Poll for a `Data` buffer. - /// - /// Similar to `Stream::poll_next`, this yields `Some(Data)` until - /// the body ends, when it yields `None`. - fn poll_data( - self: Pin<&mut Self>, - cx: &mut task::Context<'_>, - ) -> Poll>>; - - /// Poll for an optional **single** `HeaderMap` of trailers. - /// - /// 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, Self::Error>> { - Poll::Ready(Ok(None)) - } - - /// A hint that the `Body` is complete, and doesn't need to be polled more. - /// - /// This can be useful to determine if the there is any body or trailers - /// without having to poll. An empty `Body` could return `true` and hyper - /// would be able to know that only the headers need to be sent. Or, it can - /// also be checked after each `poll_data` call, to allow hyper to try to - /// end the underlying stream with the last chunk, instead of needing to - /// send an extra `DATA` frame just to mark the stream as finished. - /// - /// As a hint, it is used to try to optimize, and thus is OK for a default - /// implementation to return `false`. - fn is_end_stream(&self) -> bool { - false - } - - /// Returns a `SizeHint` providing an upper and lower bound on the possible size. - /// - /// 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 size_hint(&self) -> SizeHint { - SizeHint::default() - } -} - -impl Payload for T -where - T: HttpBody + Send + 'static, - T::Data: Send, - T::Error: Into>, -{ - type Data = T::Data; - type Error = T::Error; - - fn poll_data( - self: Pin<&mut Self>, - cx: &mut task::Context<'_>, - ) -> Poll>> { - HttpBody::poll_data(self, cx) - } - - fn poll_trailers( - self: Pin<&mut Self>, - cx: &mut task::Context<'_>, - ) -> Poll, 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 sealed::Sealed for T -where - T: HttpBody + Send + 'static, - T::Data: Send, - T::Error: Into>, -{ -} - -mod sealed { - pub trait Sealed {} -} - -/* -impl Payload for Box { - type Data = E::Data; - type Error = E::Error; - - fn poll_data(&mut self) -> Poll, Self::Error> { - (**self).poll_data() - } - - fn poll_trailers(&mut self) -> Poll, Self::Error> { - (**self).poll_trailers() - } - - fn is_end_stream(&self) -> bool { - (**self).is_end_stream() - } - - fn content_length(&self) -> Option { - (**self).content_length() - } - - #[doc(hidden)] - fn __hyper_full_data(&mut self, arg: FullDataArg) -> FullDataRet { - (**self).__hyper_full_data(arg) - } -} -*/ diff --git a/src/client/conn.rs b/src/client/conn.rs index 81eaf828..42d75faa 100644 --- a/src/client/conn.rs +++ b/src/client/conn.rs @@ -8,6 +8,7 @@ //! If don't have need to manage connections yourself, consider using the //! higher-level [Client](super) API. +use std::error::Error as StdError; use std::fmt; use std::mem; use std::sync::Arc; @@ -21,7 +22,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use tower_service::Service; use super::dispatch; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, BoxSendFuture, Exec, Executor, Future, Pin, Poll}; use crate::proto; use crate::upgrade::Upgraded; @@ -32,7 +33,7 @@ type Http1Dispatcher = proto::dispatch::Dispatcher where - B: Payload, + B: HttpBody, { H1(#[pin] Http1Dispatcher), H2(#[pin] proto::h2::ClientTask), @@ -63,7 +64,7 @@ pub struct SendRequest { pub struct Connection where T: AsyncRead + AsyncWrite + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, { inner: Option>, } @@ -160,7 +161,7 @@ impl SendRequest { impl SendRequest where - B: Payload + 'static, + B: HttpBody + 'static, { /// Sends a `Request` on the associated connection. /// @@ -245,7 +246,7 @@ where impl Service> for SendRequest where - B: Payload + 'static, + B: HttpBody + 'static, { type Response = Response; type Error = crate::Error; @@ -280,7 +281,7 @@ impl Http2SendRequest { impl Http2SendRequest where - B: Payload + 'static, + B: HttpBody + 'static, { pub(super) fn send_request_retryable( &mut self, @@ -328,7 +329,9 @@ impl Clone for Http2SendRequest { impl Connection where T: AsyncRead + AsyncWrite + Unpin + Send + 'static, - B: Payload + Unpin + 'static, + B: HttpBody + Unpin + Send + 'static, + B::Data: Send, + B::Error: Into>, { /// Return the inner IO object, and additional information. /// @@ -380,7 +383,9 @@ where impl Future for Connection where T: AsyncRead + AsyncWrite + Unpin + Send + 'static, - B: Payload + 'static, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into>, { type Output = crate::Result<()>; @@ -404,7 +409,7 @@ where impl fmt::Debug for Connection where T: AsyncRead + AsyncWrite + fmt::Debug + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Connection").finish() @@ -580,7 +585,9 @@ impl Builder { ) -> impl Future, Connection)>> where T: AsyncRead + AsyncWrite + Unpin + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, + B::Data: Send, + B::Error: Into>, { let opts = self.clone(); @@ -652,7 +659,9 @@ impl fmt::Debug for ResponseFuture { impl Future for ProtoClient where T: AsyncRead + AsyncWrite + Send + Unpin + 'static, - B: Payload + 'static, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into>, { type Output = crate::Result; @@ -678,7 +687,8 @@ impl AssertSendSync for SendRequest {} impl AssertSend for Connection where T: AsyncRead + AsyncWrite + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, + B::Data: Send, { } @@ -686,7 +696,7 @@ where impl AssertSendSync for Connection where T: AsyncRead + AsyncWrite + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, B::Data: Send + Sync + 'static, { } diff --git a/src/client/mod.rs b/src/client/mod.rs index 42fad345..f0ccb0eb 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -48,6 +48,7 @@ //! # fn main () {} //! ``` +use std::error::Error as StdError; use std::fmt; use std::mem; use std::time::Duration; @@ -60,7 +61,7 @@ use http::{Method, Request, Response, Uri, Version}; use self::connect::{sealed::Connect, Alpn, Connected, Connection}; use self::pool::{Key as PoolKey, Pool, Poolable, Pooled, Reservation}; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::common::{lazy as hyper_lazy, task, BoxSendFuture, Executor, Future, Lazy, Pin, Poll}; #[cfg(feature = "tcp")] @@ -150,16 +151,17 @@ impl Client<(), Body> { impl Client where C: Connect + Clone + Send + Sync + 'static, - B: Payload + Send + 'static, + B: HttpBody + Send + 'static, B::Data: Send, + B::Error: Into>, { /// Send a `GET` request to the supplied `Uri`. /// /// # Note /// - /// This requires that the `Payload` type have a `Default` implementation. + /// This requires that the `HttpBody` type have a `Default` implementation. /// It *should* return an "empty" version of itself, such that - /// `Payload::is_end_stream` is `true`. + /// `HttpBody::is_end_stream` is `true`. /// /// # Example /// @@ -180,7 +182,7 @@ where { let body = B::default(); if !body.is_end_stream() { - warn!("default Payload used for get() does not return true for is_end_stream"); + warn!("default HttpBody used for get() does not return true for is_end_stream"); } let mut req = Request::new(body); @@ -543,8 +545,9 @@ where impl tower_service::Service> for Client where C: Connect + Clone + Send + Sync + 'static, - B: Payload + Send + 'static, + B: HttpBody + Send + 'static, B::Data: Send, + B::Error: Into>, { type Response = Response; type Error = crate::Error; @@ -653,7 +656,7 @@ impl PoolClient { } } -impl PoolClient { +impl PoolClient { fn send_request_retryable( &mut self, req: Request, @@ -1132,7 +1135,7 @@ impl Builder { #[cfg(feature = "tcp")] pub fn build_http(&self) -> Client where - B: Payload + Send, + B: HttpBody + Send, B::Data: Send, { let mut connector = HttpConnector::new(); @@ -1146,7 +1149,7 @@ impl Builder { pub fn build(&self, connector: C) -> Client where C: Connect + Clone, - B: Payload + Send, + B: HttpBody + Send, B::Data: Send, { Client { diff --git a/src/client/service.rs b/src/client/service.rs index ef3a9bab..4013c5e5 100644 --- a/src/client/service.rs +++ b/src/client/service.rs @@ -8,7 +8,7 @@ use std::marker::PhantomData; use super::conn::{Builder, SendRequest}; use crate::{ - body::Payload, + body::HttpBody, common::{task, Pin, Poll}, service::{MakeConnection, Service}, }; @@ -43,8 +43,9 @@ where C::Connection: Unpin + Send + 'static, C::Future: Send + 'static, C::Error: Into> + Send, - B: Payload + Unpin + 'static, - B::Data: Unpin, + B: HttpBody + Unpin + Send + 'static, + B::Data: Send + Unpin, + B::Error: Into>, { type Response = SendRequest; type Error = crate::Error; diff --git a/src/common/exec.rs b/src/common/exec.rs index 94ad4610..f4e80ead 100644 --- a/src/common/exec.rs +++ b/src/common/exec.rs @@ -3,7 +3,7 @@ use std::future::Future; use std::pin::Pin; use std::sync::Arc; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::proto::h2::server::H2Stream; use crate::server::conn::spawn_all::{NewSvcTask, Watcher}; use crate::service::HttpService; @@ -14,7 +14,7 @@ pub trait Executor { fn execute(&self, fut: Fut); } -pub trait H2Exec: Clone { +pub trait H2Exec: Clone { fn execute_h2stream(&mut self, fut: H2Stream); } @@ -67,7 +67,7 @@ impl fmt::Debug for Exec { impl H2Exec for Exec where H2Stream: Future + Send + 'static, - B: Payload, + B: HttpBody, { fn execute_h2stream(&mut self, fut: H2Stream) { self.execute(fut) @@ -91,7 +91,7 @@ impl H2Exec for E where E: Executor> + Clone, H2Stream: Future, - B: Payload, + B: HttpBody, { fn execute_h2stream(&mut self, fut: H2Stream) { self.execute(fut) diff --git a/src/error.rs b/src/error.rs index 99a994b8..2cffe3d9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -65,7 +65,7 @@ pub(crate) enum Parse { #[derive(Debug, PartialEq)] pub(crate) enum User { - /// Error calling user's Payload::poll_data(). + /// Error calling user's HttpBody::poll_data(). Body, /// Error calling user's MakeService. MakeService, @@ -316,7 +316,7 @@ impl Error { Kind::Http2 => "http2 error", Kind::Io => "connection error", - Kind::User(User::Body) => "error from user's Payload stream", + Kind::User(User::Body) => "error from user's HttpBody stream", Kind::User(User::MakeService) => "error from user's MakeService", Kind::User(User::Service) => "error from user's Service", Kind::User(User::UnexpectedHeader) => "user sent unexpected header", diff --git a/src/proto/h1/dispatch.rs b/src/proto/h1/dispatch.rs index 84ee412c..a878651f 100644 --- a/src/proto/h1/dispatch.rs +++ b/src/proto/h1/dispatch.rs @@ -5,7 +5,7 @@ use http::{Request, Response, StatusCode}; use tokio::io::{AsyncRead, AsyncWrite}; use super::{Http1Transaction, Wants}; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::common::{task, Future, Never, Pin, Poll, Unpin}; use crate::proto::{ BodyLength, Conn, DecodedLength, Dispatched, MessageHead, RequestHead, RequestLine, @@ -13,7 +13,7 @@ use crate::proto::{ }; use crate::service::HttpService; -pub(crate) struct Dispatcher { +pub(crate) struct Dispatcher { conn: Conn, dispatch: D, body_tx: Option, @@ -58,7 +58,8 @@ where D::PollError: Into>, I: AsyncRead + AsyncWrite + Unpin, T: Http1Transaction + Unpin, - Bs: Payload, + Bs: HttpBody + 'static, + Bs::Error: Into>, { pub fn new(dispatch: D, conn: Conn) -> Self { Dispatcher { @@ -400,7 +401,8 @@ where D::PollError: Into>, I: AsyncRead + AsyncWrite + Unpin, T: Http1Transaction + Unpin, - Bs: Payload, + Bs: HttpBody + 'static, + Bs::Error: Into>, { type Output = crate::Result; @@ -459,7 +461,7 @@ impl Dispatch for Server where S: HttpService, S::Error: Into>, - Bs: Payload, + Bs: HttpBody, { type PollItem = MessageHead; type PollBody = Bs; @@ -530,7 +532,7 @@ impl Client { impl Dispatch for Client where - B: Payload, + B: HttpBody, { type PollItem = RequestHead; type PollBody = B; diff --git a/src/proto/h1/encode.rs b/src/proto/h1/encode.rs index 95b0d82b..e480945e 100644 --- a/src/proto/h1/encode.rs +++ b/src/proto/h1/encode.rs @@ -170,7 +170,7 @@ impl Encoder { /// Encodes the full body, without verifying the remaining length matches. /// - /// This is used in conjunction with Payload::__hyper_full_data(), which + /// This is used in conjunction with HttpBody::__hyper_full_data(), which /// means we can trust that the buf has the correct size (the buf itself /// was checked to make the headers). pub(super) fn danger_full_buf(self, msg: B, dst: &mut WriteBuf>) diff --git a/src/proto/h1/role.rs b/src/proto/h1/role.rs index e99f4cf5..46b8b264 100644 --- a/src/proto/h1/role.rs +++ b/src/proto/h1/role.rs @@ -359,7 +359,7 @@ impl Http1Transaction for Server { } match msg.body { Some(BodyLength::Known(known_len)) => { - // The Payload claims to know a length, and + // The HttpBody claims to know a length, and // the headers are already set. For performance // reasons, we are just going to trust that // the values match. @@ -388,7 +388,7 @@ impl Http1Transaction for Server { continue 'headers; } Some(BodyLength::Unknown) => { - // The Payload impl didn't know how long the + // The HttpBody impl didn't know how long the // body is, but a length header was included. // We have to parse the value to return our // Encoder... @@ -825,7 +825,7 @@ impl Client { let headers = &mut head.headers; // If the user already set specific headers, we should respect them, regardless - // of what the Payload knows about itself. They set them for a reason. + // of what the HttpBody knows about itself. They set them for a reason. // Because of the borrow checker, we can't check the for an existing // Content-Length header while holding an `Entry` for the Transfer-Encoding diff --git a/src/proto/h2/client.rs b/src/proto/h2/client.rs index bf4cfcce..6633b1bf 100644 --- a/src/proto/h2/client.rs +++ b/src/proto/h2/client.rs @@ -1,3 +1,4 @@ +use std::error::Error as StdError; #[cfg(feature = "runtime")] use std::time::Duration; @@ -8,7 +9,7 @@ use h2::client::{Builder, SendRequest}; use tokio::io::{AsyncRead, AsyncWrite}; use super::{decode_content_length, ping, PipeToSendStream, SendBuf}; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, Exec, Future, Never, Pin, Poll}; use crate::headers; use crate::proto::Dispatched; @@ -67,7 +68,8 @@ pub(crate) async fn handshake( ) -> crate::Result> where T: AsyncRead + AsyncWrite + Send + Unpin + 'static, - B: Payload, + B: HttpBody, + B::Data: Send + 'static, { let (h2_tx, mut conn) = Builder::default() .initial_window_size(config.initial_stream_window_size) @@ -167,7 +169,7 @@ where pub(crate) struct ClientTask where - B: Payload, + B: HttpBody, { ping: ping::Recorder, conn_drop_ref: ConnDropRef, @@ -179,7 +181,9 @@ where impl Future for ClientTask where - B: Payload + 'static, + B: HttpBody + Send + 'static, + B::Data: Send, + B::Error: Into>, { type Output = crate::Result; diff --git a/src/proto/h2/mod.rs b/src/proto/h2/mod.rs index e25f038c..565f4e61 100644 --- a/src/proto/h2/mod.rs +++ b/src/proto/h2/mod.rs @@ -6,9 +6,10 @@ use http::header::{ }; use http::HeaderMap; use pin_project::pin_project; +use std::error::Error as StdError; use super::DecodedLength; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, Future, Pin, Poll}; use crate::headers::content_length_parse_all; @@ -91,7 +92,7 @@ fn decode_content_length(headers: &HeaderMap) -> DecodedLength { #[pin_project] struct PipeToSendStream where - S: Payload, + S: HttpBody, { body_tx: SendStream>, data_done: bool, @@ -101,7 +102,7 @@ where impl PipeToSendStream where - S: Payload, + S: HttpBody, { fn new(stream: S, tx: SendStream>) -> PipeToSendStream { PipeToSendStream { @@ -114,7 +115,8 @@ where impl Future for PipeToSendStream where - S: Payload, + S: HttpBody, + S::Error: Into>, { type Output = crate::Result<()>; diff --git a/src/proto/h2/server.rs b/src/proto/h2/server.rs index bf81c119..50572262 100644 --- a/src/proto/h2/server.rs +++ b/src/proto/h2/server.rs @@ -9,7 +9,7 @@ use pin_project::{pin_project, project}; use tokio::io::{AsyncRead, AsyncWrite}; use super::{decode_content_length, ping, PipeToSendStream, SendBuf}; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::exec::H2Exec; use crate::common::{task, Future, Pin, Poll}; use crate::headers; @@ -58,7 +58,7 @@ impl Default for Config { pub(crate) struct Server where S: HttpService, - B: Payload, + B: HttpBody, { exec: E, service: S, @@ -67,7 +67,7 @@ where enum State where - B: Payload, + B: HttpBody, { Handshaking { ping_config: ping::Config, @@ -79,7 +79,7 @@ where struct Serving where - B: Payload, + B: HttpBody, { ping: Option<(ping::Recorder, ping::Ponger)>, conn: Connection>, @@ -91,7 +91,7 @@ where T: AsyncRead + AsyncWrite + Unpin, S: HttpService, S::Error: Into>, - B: Payload, + B: HttpBody + 'static, E: H2Exec, { pub(crate) fn new(io: T, service: S, config: &Config, exec: E) -> Server { @@ -157,7 +157,7 @@ where T: AsyncRead + AsyncWrite + Unpin, S: HttpService, S::Error: Into>, - B: Payload, + B: HttpBody + 'static, E: H2Exec, { type Output = crate::Result; @@ -201,7 +201,7 @@ where impl Serving where T: AsyncRead + AsyncWrite + Unpin, - B: Payload, + B: HttpBody + 'static, { fn poll_server( &mut self, @@ -315,7 +315,7 @@ where #[pin_project] pub struct H2Stream where - B: Payload, + B: HttpBody, { reply: SendResponse>, #[pin] @@ -325,7 +325,7 @@ where #[pin_project] enum H2StreamState where - B: Payload, + B: HttpBody, { Service(#[pin] F), Body(#[pin] PipeToSendStream), @@ -333,7 +333,7 @@ where impl H2Stream where - B: Payload, + B: HttpBody, { fn new(fut: F, respond: SendResponse>) -> H2Stream { H2Stream { @@ -359,7 +359,8 @@ macro_rules! reply { impl H2Stream where F: Future, E>>, - B: Payload, + B: HttpBody, + B::Error: Into>, E: Into>, { #[project] @@ -424,7 +425,8 @@ where impl Future for H2Stream where F: Future, E>>, - B: Payload, + B: HttpBody, + B::Error: Into>, E: Into>, { type Output = (); diff --git a/src/server/conn.rs b/src/server/conn.rs index aa8233da..fec1f975 100644 --- a/src/server/conn.rs +++ b/src/server/conn.rs @@ -21,7 +21,7 @@ use pin_project::{pin_project, project}; use tokio::io::{AsyncRead, AsyncWrite}; use super::Accept; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::common::exec::{Exec, H2Exec, NewSvcExec}; use crate::common::io::Rewind; use crate::common::{task, Future, Pin, Poll, Unpin}; @@ -122,7 +122,7 @@ where pub(super) enum ProtoServer where S: HttpService, - B: Payload, + B: HttpBody, { H1( #[pin] @@ -429,7 +429,8 @@ impl Http { where S: HttpService, S::Error: Into>, - Bd: Payload, + Bd: HttpBody + 'static, + Bd::Error: Into>, I: AsyncRead + AsyncWrite + Unpin, E: H2Exec, { @@ -477,7 +478,7 @@ impl Http { IO: AsyncRead + AsyncWrite + Unpin, S: MakeServiceRef, S::Error: Into>, - Bd: Payload, + Bd: HttpBody, E: H2Exec<>::Future, Bd>, { Serve { @@ -495,7 +496,8 @@ where S: HttpService, S::Error: Into>, I: AsyncRead + AsyncWrite + Unpin, - B: Payload + 'static, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, { /// Start a graceful shutdown process for this connection. @@ -640,7 +642,8 @@ where S: HttpService, S::Error: Into>, I: AsyncRead + AsyncWrite + Unpin + 'static, - B: Payload + 'static, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, { type Output = crate::Result<()>; @@ -707,7 +710,7 @@ where IO: AsyncRead + AsyncWrite + Unpin, IE: Into>, S: MakeServiceRef, - B: Payload, + B: HttpBody, E: H2Exec<>::Future, B>, { fn poll_next_( @@ -744,7 +747,8 @@ where I: AsyncRead + AsyncWrite + Unpin, F: Future>, S: HttpService, - B: Payload, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, { type Output = Result, FE>; @@ -778,7 +782,7 @@ where IE: Into>, IO: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: MakeServiceRef, - B: Payload, + B: HttpBody, E: H2Exec<>::Future, B>, { pub(super) fn poll_watch( @@ -814,7 +818,8 @@ where T: AsyncRead + AsyncWrite + Unpin, S: HttpService, S::Error: Into>, - B: Payload, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, { type Output = crate::Result; @@ -834,7 +839,7 @@ pub(crate) mod spawn_all { use tokio::io::{AsyncRead, AsyncWrite}; use super::{Connecting, UpgradeableConnection}; - use crate::body::{Body, Payload}; + use crate::body::{Body, HttpBody}; use crate::common::exec::H2Exec; use crate::common::{task, Future, Pin, Poll, Unpin}; use crate::service::HttpService; @@ -863,6 +868,8 @@ pub(crate) mod spawn_all { I: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: HttpService, E: H2Exec, + S::ResBody: 'static, + ::Error: Into>, { type Future = UpgradeableConnection; @@ -908,7 +915,8 @@ pub(crate) mod spawn_all { N: Future>, NE: Into>, S: HttpService, - B: Payload, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, W: Watcher, { @@ -975,7 +983,8 @@ mod upgrades { S: HttpService, S::Error: Into>, I: AsyncRead + AsyncWrite + Unpin, - B: Payload + 'static, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec, { /// Start a graceful shutdown process for this connection. @@ -992,7 +1001,8 @@ mod upgrades { S: HttpService, S::Error: Into>, I: AsyncRead + AsyncWrite + Unpin + Send + 'static, - B: Payload + 'static, + B: HttpBody + 'static, + B::Error: Into>, E: super::H2Exec, { type Output = crate::Result<()>; diff --git a/src/server/mod.rs b/src/server/mod.rs index ed6068c8..a57eaebb 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -69,7 +69,7 @@ use pin_project::pin_project; use tokio::io::{AsyncRead, AsyncWrite}; use self::accept::Accept; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::common::exec::{Exec, H2Exec, NewSvcExec}; use crate::common::{task, Future, Pin, Poll, Unpin}; use crate::service::{HttpService, MakeServiceRef}; @@ -152,7 +152,8 @@ where IO: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: MakeServiceRef, S::Error: Into>, - B: Payload, + B: HttpBody + Send + Sync + 'static, + B::Error: Into>, E: H2Exec<>::Future, B>, E: NewSvcExec, { @@ -207,7 +208,8 @@ where IO: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: MakeServiceRef, S::Error: Into>, - B: Payload, + B: HttpBody + 'static, + B::Error: Into>, E: H2Exec<>::Future, B>, E: NewSvcExec, { @@ -430,7 +432,8 @@ impl Builder { I::Conn: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: MakeServiceRef, S::Error: Into>, - B: Payload, + B: HttpBody + 'static, + B::Error: Into>, E: NewSvcExec, E: H2Exec<>::Future, B>, { diff --git a/src/server/shutdown.rs b/src/server/shutdown.rs index 1dc668ce..6a8d32cc 100644 --- a/src/server/shutdown.rs +++ b/src/server/shutdown.rs @@ -5,7 +5,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use super::conn::{SpawnAll, UpgradeableConnection, Watcher}; use super::Accept; -use crate::body::{Body, Payload}; +use crate::body::{Body, HttpBody}; use crate::common::drain::{self, Draining, Signal, Watch, Watching}; use crate::common::exec::{H2Exec, NewSvcExec}; use crate::common::{task, Future, Pin, Poll, Unpin}; @@ -50,7 +50,8 @@ where IO: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: MakeServiceRef, S::Error: Into>, - B: Payload, + B: HttpBody + Send + Sync + 'static, + B::Error: Into>, F: Future, E: H2Exec<>::Future, B>, E: NewSvcExec, @@ -98,6 +99,8 @@ where I: AsyncRead + AsyncWrite + Unpin + Send + 'static, S: HttpService, E: H2Exec, + S::ResBody: Send + Sync + 'static, + ::Error: Into>, { type Future = Watching, fn(Pin<&mut UpgradeableConnection>)>; @@ -112,7 +115,8 @@ where S: HttpService, S::Error: Into>, I: AsyncRead + AsyncWrite + Unpin, - S::ResBody: Payload + 'static, + S::ResBody: HttpBody + Send + 'static, + ::Error: Into>, E: H2Exec, { conn.graceful_shutdown() diff --git a/src/service/http.rs b/src/service/http.rs index 9c91f652..81a20c80 100644 --- a/src/service/http.rs +++ b/src/service/http.rs @@ -1,13 +1,13 @@ use std::error::Error as StdError; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, Future, Poll}; use crate::{Request, Response}; /// An asynchronous function from `Request` to `Response`. pub trait HttpService: sealed::Sealed { - /// The `Payload` body of the `http::Response`. - type ResBody: Payload; + /// The `HttpBody` body of the `http::Response`. + type ResBody: HttpBody; /// The error type that can occur within this `Service`. /// @@ -29,7 +29,7 @@ pub trait HttpService: sealed::Sealed { impl HttpService for T where T: tower_service::Service, Response = Response>, - B2: Payload, + B2: HttpBody, T::Error: Into>, { type ResBody = B2; @@ -49,7 +49,7 @@ where impl sealed::Sealed for T where T: tower_service::Service, Response = Response>, - B2: Payload, + B2: HttpBody, { } diff --git a/src/service/make.rs b/src/service/make.rs index 490992e1..074d66f1 100644 --- a/src/service/make.rs +++ b/src/service/make.rs @@ -4,7 +4,7 @@ use std::fmt; use tokio::io::{AsyncRead, AsyncWrite}; use super::{HttpService, Service}; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, Future, Poll}; // The same "trait alias" as tower::MakeConnection, but inlined to reduce @@ -41,7 +41,7 @@ where // Just a sort-of "trait alias" of `MakeService`, not to be implemented // by anyone, only used as bounds. pub trait MakeServiceRef: self::sealed::Sealed<(Target, ReqBody)> { - type ResBody: Payload; + type ResBody: HttpBody; type Error: Into>; type Service: HttpService; type MakeError: Into>; @@ -70,8 +70,8 @@ where ME: Into>, S: HttpService, F: Future>, - IB: Payload, - OB: Payload, + IB: HttpBody, + OB: HttpBody, { type Error = E; type Service = S; @@ -94,8 +94,8 @@ impl self::sealed::Sealed<(Target, B1)> for T where T: for<'a> Service<&'a Target, Response = S>, S: HttpService, - B1: Payload, - B2: Payload, + B1: HttpBody, + B2: HttpBody, { } diff --git a/src/service/util.rs b/src/service/util.rs index be597f7a..7cba1206 100644 --- a/src/service/util.rs +++ b/src/service/util.rs @@ -2,7 +2,7 @@ use std::error::Error as StdError; use std::fmt; use std::marker::PhantomData; -use crate::body::Payload; +use crate::body::HttpBody; use crate::common::{task, Future, Poll}; use crate::{Request, Response}; @@ -45,10 +45,10 @@ impl tower_service::Service for ServiceFn where F: FnMut(Request) -> Ret, - ReqBody: Payload, + ReqBody: HttpBody, Ret: Future, E>>, E: Into>, - ResBody: Payload, + ResBody: HttpBody, { type Response = crate::Response; type Error = E; diff --git a/tests/server.rs b/tests/server.rs index cdc79ef7..19b4cac2 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -258,7 +258,7 @@ mod response_body_lengths { fn auto_response_with_unknown_length() { run_test(TestCase { version: 1, - // no headers means trying to guess from Payload + // no headers means trying to guess from HttpBody headers: &[], body: Bd::Unknown("foo bar baz"), expects_chunked: true, @@ -270,7 +270,7 @@ mod response_body_lengths { fn auto_response_with_known_length() { run_test(TestCase { version: 1, - // no headers means trying to guess from Payload + // no headers means trying to guess from HttpBody headers: &[], body: Bd::Known("foo bar baz"), expects_chunked: false, @@ -282,7 +282,7 @@ mod response_body_lengths { fn auto_response_known_empty() { run_test(TestCase { version: 1, - // no headers means trying to guess from Payload + // no headers means trying to guess from HttpBody headers: &[], body: Bd::Known(""), expects_chunked: false, @@ -294,7 +294,7 @@ mod response_body_lengths { fn http10_auto_response_with_unknown_length() { run_test(TestCase { version: 0, - // no headers means trying to guess from Payload + // no headers means trying to guess from HttpBody headers: &[], body: Bd::Unknown("foo bar baz"), expects_chunked: false,