From dd08d9c3e59657b637cf29a31f62bd6815a1e04b Mon Sep 17 00:00:00 2001 From: SabrinaJewson Date: Sat, 12 Mar 2022 13:12:34 +0000 Subject: [PATCH] refactor(server): simplify server cfgs `server.rs` is currently littered with `cfg`s for `http1` or `http2`, since the majority of server behaviour is only available with either one of those feature flags active. This is hard to maintain and confusing to read, so this commit extracts the two implementations into their own files, since there is very little benefit in sharing code between the two. --- src/server/conn.rs | 1 + src/server/mod.rs | 9 ++- src/server/server.rs | 131 ++++++++++++++++---------------------- src/server/server_stub.rs | 16 +++++ 4 files changed, 80 insertions(+), 77 deletions(-) create mode 100644 src/server/server_stub.rs diff --git a/src/server/conn.rs b/src/server/conn.rs index 1e6cb469..3f9eaf9e 100644 --- a/src/server/conn.rs +++ b/src/server/conn.rs @@ -48,6 +48,7 @@ not(all(feature = "http1", feature = "http2")) ))] use std::marker::PhantomData; +#[cfg(all(any(feature = "http1", feature = "http2"), feature = "runtime"))] use std::time::Duration; #[cfg(feature = "http2")] diff --git a/src/server/mod.rs b/src/server/mod.rs index d658f421..b5508aef 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -149,7 +149,6 @@ pub mod accept; pub mod conn; -pub(crate) mod server; #[cfg(feature = "tcp")] mod tcp; @@ -158,7 +157,15 @@ pub use self::server::Server; cfg_feature! { #![any(feature = "http1", feature = "http2")] + pub(crate) mod server; pub use self::server::Builder; mod shutdown; } + +cfg_feature! { + #![not(any(feature = "http1", feature = "http2"))] + + mod server_stub; + use server_stub as server; +} diff --git a/src/server/server.rs b/src/server/server.rs index f2fb8bd8..e3058da4 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -1,36 +1,29 @@ +use std::error::Error as StdError; use std::fmt; #[cfg(feature = "tcp")] use std::net::{SocketAddr, TcpListener as StdTcpListener}; #[cfg(any(feature = "tcp", feature = "http1"))] use std::time::Duration; -#[cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))] +use pin_project_lite::pin_project; +use tokio::io::{AsyncRead, AsyncWrite}; +use tracing::trace; + +use super::accept::Accept; +#[cfg(all(feature = "tcp"))] use super::tcp::AddrIncoming; +use crate::body::{Body, HttpBody}; use crate::common::exec::Exec; +use crate::common::exec::{ConnStreamExec, NewSvcExec}; +use crate::common::{task, Future, Pin, Poll, Unpin}; +// Renamed `Http` as `Http_` for now so that people upgrading don't see an +// error that `hyper::server::Http` is private... +use super::conn::{Connection, Http as Http_, UpgradeableConnection}; +use super::shutdown::{Graceful, GracefulWatcher}; +use crate::service::{HttpService, MakeServiceRef}; -cfg_feature! { - #![any(feature = "http1", feature = "http2")] +use self::new_svc::NewSvcTask; - use std::error::Error as StdError; - - use pin_project_lite::pin_project; - use tokio::io::{AsyncRead, AsyncWrite}; - use tracing::trace; - - use super::accept::Accept; - use crate::body::{Body, HttpBody}; - use crate::common::{task, Future, Pin, Poll, Unpin}; - use crate::common::exec::{ConnStreamExec, NewSvcExec}; - // Renamed `Http` as `Http_` for now so that people upgrading don't see an - // error that `hyper::server::Http` is private... - use super::conn::{Connection, Http as Http_, UpgradeableConnection}; - use super::shutdown::{Graceful, GracefulWatcher}; - use crate::service::{HttpService, MakeServiceRef}; - - use self::new_svc::NewSvcTask; -} - -#[cfg(any(feature = "http1", feature = "http2"))] pin_project! { /// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default. /// @@ -46,17 +39,8 @@ pin_project! { } } -/// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default. -/// -/// Needs at least one of the `http1` and `http2` features to be activated to actually be useful. -#[cfg(not(any(feature = "http1", feature = "http2")))] -pub struct Server { - _marker: std::marker::PhantomData<(I, S, E)>, -} - /// A builder for a [`Server`](Server). #[derive(Debug)] -#[cfg(any(feature = "http1", feature = "http2"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] pub struct Builder { incoming: I, @@ -65,7 +49,6 @@ pub struct Builder { // ===== impl Server ===== -#[cfg(any(feature = "http1", feature = "http2"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] impl Server { /// Starts a [`Builder`](Builder) with the provided incoming stream. @@ -77,47 +60,48 @@ impl Server { } } -cfg_feature! { - #![all(feature = "tcp", any(feature = "http1", feature = "http2"))] +#[cfg(feature = "tcp")] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))) +)] +impl Server { + /// Binds to the provided address, and returns a [`Builder`](Builder). + /// + /// # Panics + /// + /// This method will panic if binding to the address fails. For a method + /// to bind to an address and return a `Result`, see `Server::try_bind`. + pub fn bind(addr: &SocketAddr) -> Builder { + let incoming = AddrIncoming::new(addr).unwrap_or_else(|e| { + panic!("error binding to {}: {}", addr, e); + }); + Server::builder(incoming) + } - impl Server { - /// Binds to the provided address, and returns a [`Builder`](Builder). - /// - /// # Panics - /// - /// This method will panic if binding to the address fails. For a method - /// to bind to an address and return a `Result`, see `Server::try_bind`. - pub fn bind(addr: &SocketAddr) -> Builder { - let incoming = AddrIncoming::new(addr).unwrap_or_else(|e| { - panic!("error binding to {}: {}", addr, e); - }); - Server::builder(incoming) - } + /// Tries to bind to the provided address, and returns a [`Builder`](Builder). + pub fn try_bind(addr: &SocketAddr) -> crate::Result> { + AddrIncoming::new(addr).map(Server::builder) + } - /// Tries to bind to the provided address, and returns a [`Builder`](Builder). - pub fn try_bind(addr: &SocketAddr) -> crate::Result> { - AddrIncoming::new(addr).map(Server::builder) - } - - /// Create a new instance from a `std::net::TcpListener` instance. - pub fn from_tcp(listener: StdTcpListener) -> Result, crate::Error> { - AddrIncoming::from_std(listener).map(Server::builder) - } + /// Create a new instance from a `std::net::TcpListener` instance. + pub fn from_tcp(listener: StdTcpListener) -> Result, crate::Error> { + AddrIncoming::from_std(listener).map(Server::builder) } } -cfg_feature! { - #![all(feature = "tcp", any(feature = "http1", feature = "http2"))] - - impl Server { - /// Returns the local address that this server is bound to. - pub fn local_addr(&self) -> SocketAddr { - self.incoming.local_addr() - } +#[cfg(feature = "tcp")] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))) +)] +impl Server { + /// Returns the local address that this server is bound to. + pub fn local_addr(&self) -> SocketAddr { + self.incoming.local_addr() } } -#[cfg(any(feature = "http1", feature = "http2"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] impl Server where @@ -220,7 +204,6 @@ where } } -#[cfg(any(feature = "http1", feature = "http2"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] impl Future for Server where @@ -244,7 +227,6 @@ where impl fmt::Debug for Server { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut st = f.debug_struct("Server"); - #[cfg(any(feature = "http1", feature = "http2"))] st.field("listener", &self.incoming); st.finish() } @@ -252,7 +234,6 @@ impl fmt::Debug for Server { // ===== impl Builder ===== -#[cfg(any(feature = "http1", feature = "http2"))] #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] impl Builder { /// Start a new builder, wrapping an incoming stream and low-level options. @@ -572,7 +553,11 @@ impl Builder { } } -#[cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))] +#[cfg(feature = "tcp")] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))) +)] impl Builder { /// Set whether TCP keepalive messages are enabled on accepted connections. /// @@ -619,7 +604,6 @@ impl Builder { // The `Server::with_graceful_shutdown` needs to keep track of all active // connections, and signal that they start to shutdown when prompted, so // it has a `GracefulWatcher` implementation to do that. -#[cfg(any(feature = "http1", feature = "http2"))] pub trait Watcher, E>: Clone { type Future: Future>; @@ -628,10 +612,8 @@ pub trait Watcher, E>: Clone { #[allow(missing_debug_implementations)] #[derive(Copy, Clone)] -#[cfg(any(feature = "http1", feature = "http2"))] pub struct NoopWatcher; -#[cfg(any(feature = "http1", feature = "http2"))] impl Watcher for NoopWatcher where I: AsyncRead + AsyncWrite + Unpin + Send + 'static, @@ -647,7 +629,6 @@ where } } -#[cfg(any(feature = "http1", feature = "http2"))] // used by exec.rs pub(crate) mod new_svc { use std::error::Error as StdError; @@ -759,7 +740,6 @@ pub(crate) mod new_svc { } } -#[cfg(any(feature = "http1", feature = "http2"))] pin_project! { /// A future building a new `Service` to a `Connection`. /// @@ -776,7 +756,6 @@ pin_project! { } } -#[cfg(any(feature = "http1", feature = "http2"))] impl Future for Connecting where I: AsyncRead + AsyncWrite + Unpin, diff --git a/src/server/server_stub.rs b/src/server/server_stub.rs new file mode 100644 index 00000000..87b1f513 --- /dev/null +++ b/src/server/server_stub.rs @@ -0,0 +1,16 @@ +use std::fmt; + +use crate::common::exec::Exec; + +/// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default. +/// +/// Needs at least one of the `http1` and `http2` features to be activated to actually be useful. +pub struct Server { + _marker: std::marker::PhantomData<(I, S, E)>, +} + +impl fmt::Debug for Server { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Server").finish() + } +}