diff --git a/src/client/conn/http1.rs b/src/client/conn/http1.rs index 85c1fdc665..b2149f2510 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 5daeb5ebf6..6e1f3ebb73 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: Option, 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: None, body_rx: Box::pin(None), is_closing: false, + _a: Default::default() } } @@ -451,7 +453,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, @@ -461,7 +463,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 483ed96dd9..c7ab5a42b4 100644 --- a/src/proto/h2/server.rs +++ b/src/proto/h2/server.rs @@ -78,7 +78,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, @@ -88,7 +88,8 @@ pin_project! { service: S, state: State, date_header: bool, - close_pending: bool + close_pending: bool, + _v: std::marker::PhantomData<&'body ()> } } @@ -113,12 +114,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( @@ -127,7 +128,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) @@ -172,6 +173,7 @@ where service, date_header: config.date_header, close_pending: false, + _v: Default::default() } } @@ -190,12 +192,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; @@ -239,7 +241,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 36dda98069..50c2a2f8c0 100644 --- a/src/server/conn/http1.rs +++ b/src/server/conn/http1.rs @@ -21,7 +21,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, @@ -36,11 +37,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>, } } @@ -107,7 +108,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, { @@ -116,12 +117,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. @@ -177,7 +178,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.as_mut().unwrap().conn.poll_without_shutdown(cx))?; @@ -188,7 +189,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, { @@ -196,12 +197,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<()>; @@ -441,11 +442,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, { @@ -496,19 +497,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. @@ -524,12 +525,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 0452109c3c..e1c743ecb3 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, { @@ -291,11 +291,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,