diff --git a/src/client/conn/http1.rs b/src/client/conn/http1.rs index ec64543c23..0e592165a1 100644 --- a/src/client/conn/http1.rs +++ b/src/client/conn/http1.rs @@ -17,7 +17,7 @@ use crate::body::{Body, Incoming as IncomingBody}; use crate::proto; type Dispatcher = - proto::dispatch::Dispatcher, B, T, proto::h1::ClientTransaction>; + proto::dispatch::Dispatcher<'static, proto::dispatch::Client, B, T, proto::h1::ClientTransaction>; /// The sender side of an established connection. pub struct SendRequest { diff --git a/src/proto/h1/dispatch.rs b/src/proto/h1/dispatch.rs index 3a9b536ea4..8700069bd9 100644 --- a/src/proto/h1/dispatch.rs +++ b/src/proto/h1/dispatch.rs @@ -19,12 +19,13 @@ use crate::common::task; use crate::proto::{BodyLength, Conn, Dispatched, MessageHead, RequestHead}; use crate::upgrade::OnUpgrade; -pub(crate) struct Dispatcher { +pub(crate) struct Dispatcher<'body, D, Bs: Body + 'body, I, T> { conn: Conn, dispatch: D, body_tx: SenderDropGuard, body_rx: Pin>>, is_closing: bool, + _a: std::marker::PhantomData<&'body ()> } pub(crate) trait Dispatch { @@ -64,7 +65,7 @@ cfg_client! { type ClientRx = crate::client::dispatch::Receiver, http::Response>; } -impl Dispatcher +impl<'body, D, Bs, I, T> Dispatcher<'body, D, Bs, I, T> where D: Dispatch< PollItem = MessageHead, @@ -74,7 +75,7 @@ where D::PollError: Into>, I: Read + Write + Unpin, T: Http1Transaction + Unpin, - Bs: Body + 'static, + Bs: Body + 'body, Bs::Error: Into>, { pub(crate) fn new(dispatch: D, conn: Conn) -> Self { @@ -84,6 +85,7 @@ where body_tx: SenderDropGuard::none(), body_rx: Box::pin(None), is_closing: false, + _a: Default::default() } } @@ -476,7 +478,7 @@ where } } -impl Future for Dispatcher +impl<'body, D, Bs, I, T> Future for Dispatcher<'body, D, Bs, I, T> where D: Dispatch< PollItem = MessageHead, @@ -486,7 +488,7 @@ where D::PollError: Into>, I: Read + Write + Unpin, T: Http1Transaction + Unpin, - Bs: Body + 'static, + Bs: Body + 'body, Bs::Error: Into>, { type Output = crate::Result; diff --git a/src/proto/h2/server.rs b/src/proto/h2/server.rs index 6645734f31..c186740bcb 100644 --- a/src/proto/h2/server.rs +++ b/src/proto/h2/server.rs @@ -80,7 +80,7 @@ impl Default for Config { } pin_project! { - pub(crate) struct Server + pub(crate) struct Server<'body, T, S, B, E> where S: HttpService, B: Body, @@ -90,7 +90,8 @@ pin_project! { service: S, state: State, date_header: bool, - close_pending: bool + close_pending: bool, + _v: std::marker::PhantomData<&'body ()> } } @@ -117,12 +118,12 @@ where date_header: bool, } -impl Server +impl<'body, T, S, B, E> Server<'body, T, S, B, E> where T: Read + Write + Unpin, S: HttpService, S::Error: Into>, - B: Body + 'static, + B: Body + 'body, E: Http2ServerConnExec, { pub(crate) fn new( @@ -131,7 +132,7 @@ where config: &Config, exec: E, timer: Time, - ) -> Server { + ) -> Server<'body, T, S, B, E> { let mut builder = h2::server::Builder::default(); builder .initial_window_size(config.initial_stream_window_size) @@ -179,6 +180,7 @@ where service, date_header: config.date_header, close_pending: false, + _v: Default::default() } } @@ -197,12 +199,12 @@ where } } -impl Future for Server +impl<'body, T, S, B, E> Future for Server<'body, T, S, B, E> where T: Read + Write + Unpin, S: HttpService, S::Error: Into>, - B: Body + 'static, + B: Body + 'body, E: Http2ServerConnExec, { type Output = crate::Result; @@ -246,7 +248,7 @@ where impl Serving where T: Read + Write + Unpin, - B: Body + 'static, + B: Body, { fn poll_server( &mut self, diff --git a/src/server/conn/http1.rs b/src/server/conn/http1.rs index 7bd3d72e2f..892bafca95 100644 --- a/src/server/conn/http1.rs +++ b/src/server/conn/http1.rs @@ -22,7 +22,8 @@ use crate::{ rt::Timer, }; -type Http1Dispatcher = proto::h1::Dispatcher< +type Http1Dispatcher<'body, T, B, S> = proto::h1::Dispatcher< + 'body, proto::h1::dispatch::Server, B, T, @@ -37,11 +38,11 @@ pin_project_lite::pin_project! { /// To drive HTTP on this connection this future **must be polled**, typically with /// `.await`. If it isn't polled, no progress will be made on this connection. #[must_use = "futures do nothing unless polled"] - pub struct Connection + pub struct Connection<'body, T, S> where S: HttpService, { - conn: Http1Dispatcher, + conn: Http1Dispatcher<'body, T, S::ResBody, S>, } } @@ -108,7 +109,7 @@ pub struct Parts { // ===== impl Connection ===== -impl fmt::Debug for Connection +impl<'body, I, S> fmt::Debug for Connection<'body, I, S> where S: HttpService, { @@ -117,12 +118,12 @@ where } } -impl Connection +impl<'body, I, B, S> Connection<'body, I, S> where - S: HttpService, + S: HttpService + 'body, S::Error: Into>, - I: Read + Write + Unpin, - B: Body + 'static, + I: Read + Write + Unpin + 'body, + B: Body + 'body, B::Error: Into>, { /// Start a graceful shutdown process for this connection. @@ -178,7 +179,7 @@ where /// # Error /// /// This errors if the underlying connection protocol is not HTTP/1. - pub fn without_shutdown(self) -> impl Future>> { + pub fn without_shutdown(self) -> impl Future>> + 'body { let mut zelf = Some(self); crate::common::future::poll_fn(move |cx| { ready!(zelf @@ -196,7 +197,7 @@ where /// Enable this connection to support higher-level HTTP upgrades. /// /// See [the `upgrade` module](crate::upgrade) for more. - pub fn with_upgrades(self) -> UpgradeableConnection + pub fn with_upgrades(self) -> UpgradeableConnection<'body, I, S> where I: Send, { @@ -204,12 +205,12 @@ where } } -impl Future for Connection +impl<'body, I, B, S> Future for Connection<'body, I, S> where S: HttpService, S::Error: Into>, I: Read + Write + Unpin, - B: Body + 'static, + B: Body + 'body, B::Error: Into>, { type Output = crate::Result<()>; @@ -449,11 +450,11 @@ impl Builder { /// # } /// # fn main() {} /// ``` - pub fn serve_connection(&self, io: I, service: S) -> Connection + pub fn serve_connection<'body, I, S>(&self, io: I, service: S) -> Connection<'body, I, S> where S: HttpService, S::Error: Into>, - S::ResBody: 'static, + S::ResBody: 'body, ::Error: Into>, I: Read + Write + Unpin, { @@ -504,19 +505,19 @@ impl Builder { /// A future binding a connection with a Service with Upgrade support. #[must_use = "futures do nothing unless polled"] #[allow(missing_debug_implementations)] -pub struct UpgradeableConnection +pub struct UpgradeableConnection<'body, T, S> where S: HttpService, { - pub(super) inner: Option>, + pub(super) inner: Option>, } -impl UpgradeableConnection +impl<'body, I, B, S> UpgradeableConnection<'body, I, S> where - S: HttpService, + S: HttpService + 'body, S::Error: Into>, - I: Read + Write + Unpin, - B: Body + 'static, + I: Read + Write + Unpin + 'body, + B: Body + 'body, B::Error: Into>, { /// Start a graceful shutdown process for this connection. @@ -538,12 +539,12 @@ where } } -impl Future for UpgradeableConnection +impl<'body, I, B, S> Future for UpgradeableConnection<'body, I, S> where S: HttpService, S::Error: Into>, I: Read + Write + Unpin + Send + 'static, - B: Body + 'static, + B: Body + 'body, B::Error: Into>, { type Output = crate::Result<()>; diff --git a/src/server/conn/http2.rs b/src/server/conn/http2.rs index e4dac78bea..30e04fd921 100644 --- a/src/server/conn/http2.rs +++ b/src/server/conn/http2.rs @@ -26,11 +26,11 @@ pin_project! { /// To drive HTTP on this connection this future **must be polled**, typically with /// `.await`. If it isn't polled, no progress will be made on this connection. #[must_use = "futures do nothing unless polled"] - pub struct Connection + pub struct Connection<'body, T, S, E> where S: HttpService, { - conn: proto::h2::Server, + conn: proto::h2::Server<'body, T, S, S::ResBody, E>, } } @@ -47,7 +47,7 @@ pub struct Builder { // ===== impl Connection ===== -impl fmt::Debug for Connection +impl<'body, I, S, E> fmt::Debug for Connection<'body, I, S, E> where S: HttpService, { @@ -56,12 +56,12 @@ where } } -impl Connection +impl<'body, I, B, S, E> Connection<'body, I, S, E> where S: HttpService, S::Error: Into>, I: Read + Write + Unpin, - B: Body + 'static, + B: Body + 'body, B::Error: Into>, E: Http2ServerConnExec, { @@ -80,12 +80,12 @@ where } } -impl Future for Connection +impl<'body, I, B, S, E> Future for Connection<'body, I, S, E> where S: HttpService, S::Error: Into>, I: Read + Write + Unpin, - B: Body + 'static, + B: Body + 'body, B::Error: Into>, E: Http2ServerConnExec, { @@ -303,11 +303,11 @@ impl Builder { /// /// This returns a Future that must be polled in order for HTTP to be /// driven on the connection. - pub fn serve_connection(&self, io: I, service: S) -> Connection + pub fn serve_connection<'body, S, I, Bd>(&self, io: I, service: S) -> Connection<'body, I, S, E> where S: HttpService, S::Error: Into>, - Bd: Body + 'static, + Bd: Body + 'body, Bd::Error: Into>, I: Read + Write + Unpin, E: Http2ServerConnExec,