From 6d258d76e8f0cdb115ab6962fe3960358f65e303 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 5 Apr 2024 14:04:38 +0900 Subject: [PATCH] feat(conn/auto): allow serving connection with upgrade after config When using hyper_util::server::conn::auto::Builder, if one wants to set http1 or http2 options one has to specialize the struct into Http1Builder or Http2Builder with .http1()/.http2() methods. However, once the struct has been specialized there is no way to go back to the inner Builder to call serve_connection_with_upgrades(): one would need to either add make inner public, add an inner() method to get it back, or add a stub that just calls the method on inner like we have with serve_connection(). Since we already had one for serve_connection(), add an indentical one for serve_connection_with_upgrades() Note that it does not make sense for serve_connection_with_upgrades() to be called without the http feature (I think?), so it has only been implemented for http1 if the http2 feature is set. --- src/server/conn/auto.rs | 45 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/server/conn/auto.rs b/src/server/conn/auto.rs index 7e74d167..47d88dce 100644 --- a/src/server/conn/auto.rs +++ b/src/server/conn/auto.rs @@ -665,6 +665,27 @@ impl Http1Builder<'_, E> { { self.inner.serve_connection(io, service).await } + + /// Bind a connection together with a [`Service`], with the ability to + /// handle HTTP upgrades. This requires that the IO object implements + /// `Send`. + #[cfg(feature = "http2")] + pub fn serve_connection_with_upgrades( + &self, + io: I, + service: S, + ) -> UpgradeableConnection<'_, I, S, E> + where + S: Service, Response = Response>, + S::Future: 'static, + S::Error: Into>, + B: Body + 'static, + B::Error: Into>, + I: Read + Write + Unpin + Send + 'static, + E: HttpServerConnExec, + { + self.inner.serve_connection_with_upgrades(io, service) + } } /// Http2 part of builder. @@ -824,6 +845,26 @@ impl Http2Builder<'_, E> { { self.inner.serve_connection(io, service).await } + + /// Bind a connection together with a [`Service`], with the ability to + /// handle HTTP upgrades. This requires that the IO object implements + /// `Send`. + pub fn serve_connection_with_upgrades( + &self, + io: I, + service: S, + ) -> UpgradeableConnection<'_, I, S, E> + where + S: Service, Response = Response>, + S::Future: 'static, + S::Error: Into>, + B: Body + 'static, + B::Error: Into>, + I: Read + Write + Unpin + Send + 'static, + E: HttpServerConnExec, + { + self.inner.serve_connection_with_upgrades(io, service) + } } #[cfg(test)] @@ -971,7 +1012,9 @@ mod tests { let stream = TokioIo::new(stream); tokio::task::spawn(async move { let _ = auto::Builder::new(TokioExecutor::new()) - .serve_connection(stream, service_fn(hello)) + .http2() + .max_header_list_size(4096) + .serve_connection_with_upgrades(stream, service_fn(hello)) .await; }); }