feat(lib): Export more things with Cargo features [server, !http1, !http2]
* server::Server
* server::conn::{AddrIncoming, AddrStream}
This allows higher-level libraries to use or re-export more parts of the
API without deciding for the end user which HTTP versions the hyper
server will support.
			
			
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							cf6f62c71e
						
					
				
				
					commit
					0a4b56acb8
				
			| @@ -3,14 +3,16 @@ use std::future::Future; | ||||
| use std::pin::Pin; | ||||
| use std::sync::Arc; | ||||
|  | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| use crate::body::Body; | ||||
| #[cfg(feature = "server")] | ||||
| use crate::body::{Body, HttpBody}; | ||||
| use crate::body::HttpBody; | ||||
| #[cfg(all(feature = "http2", feature = "server"))] | ||||
| use crate::proto::h2::server::H2Stream; | ||||
| use crate::rt::Executor; | ||||
| #[cfg(feature = "server")] | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| use crate::server::conn::spawn_all::{NewSvcTask, Watcher}; | ||||
| #[cfg(feature = "server")] | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| use crate::service::HttpService; | ||||
|  | ||||
| #[cfg(feature = "server")] | ||||
| @@ -18,7 +20,7 @@ pub trait ConnStreamExec<F, B: HttpBody>: Clone { | ||||
|     fn execute_h2stream(&mut self, fut: H2Stream<F, B>); | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "server")] | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| pub trait NewSvcExec<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>>: Clone { | ||||
|     fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>); | ||||
| } | ||||
| @@ -76,7 +78,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "server")] | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec | ||||
| where | ||||
|     NewSvcTask<I, N, S, E, W>: Future<Output = ()> + Send + 'static, | ||||
| @@ -102,7 +104,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "server")] | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for E | ||||
| where | ||||
|     E: Executor<NewSvcTask<I, N, S, E, W>> + Clone, | ||||
|   | ||||
| @@ -12,7 +12,7 @@ pub(crate) mod buf; | ||||
| pub(crate) mod date; | ||||
| #[cfg(all(feature = "server", any(feature = "http1", feature = "http2")))] | ||||
| pub(crate) mod drain; | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg(any(feature = "http1", feature = "http2", feature = "server"))] | ||||
| pub(crate) mod exec; | ||||
| pub(crate) mod io; | ||||
| #[cfg(all(feature = "client", any(feature = "http1", feature = "http2")))] | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/error.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/error.rs
									
									
									
									
									
								
							| @@ -38,11 +38,7 @@ pub(super) enum Kind { | ||||
|     #[allow(unused)] | ||||
|     Connect, | ||||
|     /// Error creating a TcpListener. | ||||
|     #[cfg(all( | ||||
|         any(feature = "http1", feature = "http2"), | ||||
|         feature = "tcp", | ||||
|         feature = "server" | ||||
|     ))] | ||||
|     #[cfg(all(feature = "tcp", feature = "server"))] | ||||
|     Listen, | ||||
|     /// Error accepting on an Incoming stream. | ||||
|     #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| @@ -265,8 +261,7 @@ impl Error { | ||||
|         Error::new(Kind::Io).with(cause) | ||||
|     } | ||||
|  | ||||
|     #[cfg(all(any(feature = "http1", feature = "http2"), feature = "tcp"))] | ||||
|     #[cfg(feature = "server")] | ||||
|     #[cfg(all(feature = "server", feature = "tcp"))] | ||||
|     pub(super) fn new_listen<E: Into<Cause>>(cause: E) -> Error { | ||||
|         Error::new(Kind::Listen).with(cause) | ||||
|     } | ||||
| @@ -410,8 +405,7 @@ impl Error { | ||||
|             Kind::ChannelClosed => "channel closed", | ||||
|             Kind::Connect => "error trying to connect", | ||||
|             Kind::Canceled => "operation was canceled", | ||||
|             #[cfg(all(any(feature = "http1", feature = "http2"), feature = "tcp"))] | ||||
|             #[cfg(feature = "server")] | ||||
|             #[cfg(all(feature = "server", feature = "tcp"))] | ||||
|             Kind::Listen => "error creating server listener", | ||||
|             #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|             #[cfg(feature = "server")] | ||||
|   | ||||
| @@ -104,7 +104,6 @@ cfg_feature! { | ||||
|     #![feature = "server"] | ||||
|  | ||||
|     pub mod server; | ||||
|     #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|     #[doc(no_inline)] | ||||
|     pub use crate::server::Server; | ||||
| } | ||||
|   | ||||
| @@ -43,15 +43,29 @@ | ||||
| //! # } | ||||
| //! ``` | ||||
|  | ||||
| use std::error::Error as StdError; | ||||
| use std::fmt; | ||||
| #[cfg(not(all(feature = "http1", feature = "http2")))] | ||||
| #[cfg(all( | ||||
|     any(feature = "http1", feature = "http2"), | ||||
|     not(all(feature = "http1", feature = "http2")) | ||||
| ))] | ||||
| use std::marker::PhantomData; | ||||
| #[cfg(feature = "tcp")] | ||||
| use std::net::SocketAddr; | ||||
| #[cfg(all(feature = "runtime", feature = "http2"))] | ||||
| use std::time::Duration; | ||||
|  | ||||
| #[cfg(feature = "http2")] | ||||
| use crate::common::io::Rewind; | ||||
| #[cfg(all(feature = "http1", feature = "http2"))] | ||||
| use crate::error::{Kind, Parse}; | ||||
| #[cfg(feature = "http1")] | ||||
| use crate::upgrade::Upgraded; | ||||
|  | ||||
| cfg_feature! { | ||||
|     #![any(feature = "http1", feature = "http2")] | ||||
|  | ||||
|     use std::error::Error as StdError; | ||||
|     use std::fmt; | ||||
|  | ||||
|     use bytes::Bytes; | ||||
|     use pin_project_lite::pin_project; | ||||
|     use tokio::io::{AsyncRead, AsyncWrite}; | ||||
| @@ -59,22 +73,17 @@ use tracing::trace; | ||||
|  | ||||
|     use super::accept::Accept; | ||||
|     use crate::body::{Body, HttpBody}; | ||||
| use crate::common::exec::{ConnStreamExec, Exec, NewSvcExec}; | ||||
| #[cfg(feature = "http2")] | ||||
| use crate::common::io::Rewind; | ||||
|     use crate::common::{task, Future, Pin, Poll, Unpin}; | ||||
|     #[cfg(not(all(feature = "http1", feature = "http2")))] | ||||
|     use crate::common::Never; | ||||
| use crate::common::{task, Future, Pin, Poll, Unpin}; | ||||
| #[cfg(all(feature = "http1", feature = "http2"))] | ||||
| use crate::error::{Kind, Parse}; | ||||
|     use crate::common::exec::{ConnStreamExec, Exec, NewSvcExec}; | ||||
|     use crate::proto; | ||||
|     use crate::service::{HttpService, MakeServiceRef}; | ||||
| #[cfg(feature = "http1")] | ||||
| use crate::upgrade::Upgraded; | ||||
|  | ||||
|     use self::spawn_all::NewSvcTask; | ||||
|  | ||||
|     pub(super) use self::spawn_all::{NoopWatcher, Watcher}; | ||||
|     pub(super) use self::upgrades::UpgradeableConnection; | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "tcp")] | ||||
| pub use super::tcp::{AddrIncoming, AddrStream}; | ||||
| @@ -86,6 +95,8 @@ pub use super::tcp::{AddrIncoming, AddrStream}; | ||||
| /// If you don't have need to manage connections yourself, consider using the | ||||
| /// higher-level [Server](super) API. | ||||
| #[derive(Clone, Debug)] | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| pub struct Http<E = Exec> { | ||||
|     exec: E, | ||||
|     h1_half_close: bool, | ||||
| @@ -100,6 +111,7 @@ pub struct Http<E = Exec> { | ||||
| } | ||||
|  | ||||
| /// The internal mode of HTTP protocol which indicates the behavior when a parse error occurs. | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| enum ConnectionMode { | ||||
|     /// Always use HTTP/1 and do not upgrade when a parse error occurs. | ||||
| @@ -113,6 +125,7 @@ enum ConnectionMode { | ||||
|     Fallback, | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     /// A stream mapping incoming IOs to new services. | ||||
|     /// | ||||
| @@ -127,6 +140,7 @@ pin_project! { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     /// A future building a new `Service` to a `Connection`. | ||||
|     /// | ||||
| @@ -134,6 +148,7 @@ pin_project! { | ||||
|     /// a `Connection`. | ||||
|     #[must_use = "futures do nothing unless polled"] | ||||
|     #[derive(Debug)] | ||||
|     #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
|     pub struct Connecting<I, F, E = Exec> { | ||||
|         #[pin] | ||||
|         future: F, | ||||
| @@ -142,6 +157,7 @@ pin_project! { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     #[must_use = "futures do nothing unless polled"] | ||||
|     #[derive(Debug)] | ||||
| @@ -154,11 +170,13 @@ pin_project! { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     /// A future binding a connection with a Service. | ||||
|     /// | ||||
|     /// Polling this future will drive HTTP forward. | ||||
|     #[must_use = "futures do nothing unless polled"] | ||||
|     #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
|     pub struct Connection<T, S, E = Exec> | ||||
|     where | ||||
|         S: HttpService<Body>, | ||||
| @@ -172,18 +190,19 @@ pin_project! { | ||||
| type Http1Dispatcher<T, B, S> = | ||||
|     proto::h1::Dispatcher<proto::h1::dispatch::Server<S, Body>, B, T, proto::ServerTransaction>; | ||||
|  | ||||
| #[cfg(not(feature = "http1"))] | ||||
| #[cfg(all(not(feature = "http1"), feature = "http2"))] | ||||
| type Http1Dispatcher<T, B, S> = (Never, PhantomData<(T, Box<Pin<B>>, Box<Pin<S>>)>); | ||||
|  | ||||
| #[cfg(feature = "http2")] | ||||
| type Http2Server<T, B, S, E> = proto::h2::Server<Rewind<T>, S, B, E>; | ||||
|  | ||||
| #[cfg(not(feature = "http2"))] | ||||
| #[cfg(all(not(feature = "http2"), feature = "http1"))] | ||||
| type Http2Server<T, B, S, E> = ( | ||||
|     Never, | ||||
|     PhantomData<(T, Box<Pin<S>>, Box<Pin<B>>, Box<Pin<E>>)>, | ||||
| ); | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     #[project = ProtoServerProj] | ||||
|     pub(super) enum ProtoServer<T, B, S, E = Exec> | ||||
| @@ -209,7 +228,10 @@ enum Fallback<E> { | ||||
|     Http1Only, | ||||
| } | ||||
|  | ||||
| #[cfg(not(all(feature = "http1", feature = "http2")))] | ||||
| #[cfg(all( | ||||
|     any(feature = "http1", feature = "http2"), | ||||
|     not(all(feature = "http1", feature = "http2")) | ||||
| ))] | ||||
| type Fallback<E> = PhantomData<E>; | ||||
|  | ||||
| #[cfg(all(feature = "http1", feature = "http2"))] | ||||
| @@ -230,6 +252,8 @@ impl<E> Unpin for Fallback<E> {} | ||||
| /// This allows taking apart a `Connection` at a later time, in order to | ||||
| /// reclaim the IO object, and additional related pieces. | ||||
| #[derive(Debug)] | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| pub struct Parts<T, S> { | ||||
|     /// The original IO object used in the handshake. | ||||
|     pub io: T, | ||||
| @@ -249,6 +273,7 @@ pub struct Parts<T, S> { | ||||
|  | ||||
| // ===== impl Http ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl Http { | ||||
|     /// Creates a new instance of the HTTP protocol, ready to spawn a server or | ||||
|     /// start accepting connections. | ||||
| @@ -268,6 +293,7 @@ impl Http { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<E> Http<E> { | ||||
|     /// Sets whether HTTP1 is required. | ||||
|     /// | ||||
| @@ -633,6 +659,7 @@ impl<E> Http<E> { | ||||
|  | ||||
| // ===== impl Connection ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, B, S, E> Connection<I, S, E> | ||||
| where | ||||
|     S: HttpService<Body, ResBody = B>, | ||||
| @@ -802,6 +829,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, B, S, E> Future for Connection<I, S, E> | ||||
| where | ||||
|     S: HttpService<Body, ResBody = B>, | ||||
| @@ -848,6 +876,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, S> fmt::Debug for Connection<I, S> | ||||
| where | ||||
|     S: HttpService<Body>, | ||||
| @@ -859,6 +888,7 @@ where | ||||
|  | ||||
| // ===== impl ConnectionMode ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl Default for ConnectionMode { | ||||
|     #[cfg(all(feature = "http1", feature = "http2"))] | ||||
|     fn default() -> ConnectionMode { | ||||
| @@ -878,6 +908,7 @@ impl Default for ConnectionMode { | ||||
|  | ||||
| // ===== impl Serve ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, S, E> Serve<I, S, E> { | ||||
|     /// Get a reference to the incoming stream. | ||||
|     #[inline] | ||||
| @@ -899,6 +930,7 @@ impl<I, S, E> Serve<I, S, E> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, IO, IE, S, B, E> Serve<I, S, E> | ||||
| where | ||||
|     I: Accept<Conn = IO, Error = IE>, | ||||
| @@ -937,6 +969,7 @@ where | ||||
|  | ||||
| // ===== impl Connecting ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, F, S, FE, E, B> Future for Connecting<I, F, E> | ||||
| where | ||||
|     I: AsyncRead + AsyncWrite + Unpin, | ||||
| @@ -958,19 +991,21 @@ where | ||||
|  | ||||
| // ===== impl SpawnAll ===== | ||||
|  | ||||
| #[cfg(feature = "tcp")] | ||||
| #[cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))] | ||||
| impl<S, E> SpawnAll<AddrIncoming, S, E> { | ||||
|     pub(super) fn local_addr(&self) -> SocketAddr { | ||||
|         self.serve.incoming.local_addr() | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, S, E> SpawnAll<I, S, E> { | ||||
|     pub(super) fn incoming_ref(&self) -> &I { | ||||
|         self.serve.incoming_ref() | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<I, IO, IE, S, B, E> SpawnAll<I, S, E> | ||||
| where | ||||
|     I: Accept<Conn = IO, Error = IE>, | ||||
| @@ -1008,6 +1043,7 @@ where | ||||
|  | ||||
| // ===== impl ProtoServer ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| impl<T, B, S, E> Future for ProtoServer<T, B, S, E> | ||||
| where | ||||
|     T: AsyncRead + AsyncWrite + Unpin, | ||||
| @@ -1034,6 +1070,7 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pub(crate) mod spawn_all { | ||||
|     use std::error::Error as StdError; | ||||
|     use tokio::io::{AsyncRead, AsyncWrite}; | ||||
| @@ -1177,6 +1214,7 @@ pub(crate) mod spawn_all { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| mod upgrades { | ||||
|     use super::*; | ||||
|  | ||||
|   | ||||
| @@ -148,15 +148,17 @@ | ||||
| //! [`tower::make::Shared`]: https://docs.rs/tower/latest/tower/make/struct.Shared.html | ||||
|  | ||||
| pub mod accept; | ||||
| pub mod conn; | ||||
| mod server; | ||||
| #[cfg(feature = "tcp")] | ||||
| mod tcp; | ||||
|  | ||||
| pub use self::server::Server; | ||||
|  | ||||
| cfg_feature! { | ||||
|     #![any(feature = "http1", feature = "http2")] | ||||
|  | ||||
|     pub use self::server::{Builder, Server}; | ||||
|     pub use self::server::Builder; | ||||
|  | ||||
|     pub mod conn; | ||||
|     mod server; | ||||
|     mod shutdown; | ||||
|     #[cfg(feature = "tcp")] | ||||
|     mod tcp; | ||||
| } | ||||
|   | ||||
| @@ -1,26 +1,33 @@ | ||||
| use std::error::Error as StdError; | ||||
| use std::fmt; | ||||
| #[cfg(feature = "tcp")] | ||||
| use std::net::{SocketAddr, TcpListener as StdTcpListener}; | ||||
|  | ||||
| #[cfg(feature = "tcp")] | ||||
| use std::time::Duration; | ||||
|  | ||||
| #[cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))] | ||||
| use super::tcp::AddrIncoming; | ||||
| use crate::common::exec::Exec; | ||||
|  | ||||
| cfg_feature! { | ||||
|     #![any(feature = "http1", feature = "http2")] | ||||
|  | ||||
|     use std::error::Error as StdError; | ||||
|  | ||||
|     use pin_project_lite::pin_project; | ||||
|     use tokio::io::{AsyncRead, AsyncWrite}; | ||||
|  | ||||
|     use super::accept::Accept; | ||||
|     use crate::body::{Body, HttpBody}; | ||||
| use crate::common::exec::{ConnStreamExec, Exec, NewSvcExec}; | ||||
|     use crate::common::{task, Future, Pin, Poll, Unpin}; | ||||
| use crate::service::{HttpService, MakeServiceRef}; | ||||
|     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::{Http as Http_, NoopWatcher, SpawnAll}; | ||||
|     use super::shutdown::{Graceful, GracefulWatcher}; | ||||
| #[cfg(feature = "tcp")] | ||||
| use super::tcp::AddrIncoming; | ||||
|     use crate::service::{HttpService, MakeServiceRef}; | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| pin_project! { | ||||
|     /// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default. | ||||
|     /// | ||||
| @@ -34,8 +41,18 @@ 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<I, S, E = Exec> { | ||||
|     _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<I, E = Exec> { | ||||
|     incoming: I, | ||||
|     protocol: Http_<E>, | ||||
| @@ -43,6 +60,8 @@ pub struct Builder<I, E = Exec> { | ||||
|  | ||||
| // ===== impl Server ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| impl<I> Server<I, ()> { | ||||
|     /// Starts a [`Builder`](Builder) with the provided incoming stream. | ||||
|     pub fn builder(incoming: I) -> Builder<I> { | ||||
| @@ -54,7 +73,7 @@ impl<I> Server<I, ()> { | ||||
| } | ||||
|  | ||||
| cfg_feature! { | ||||
|     #![all(feature = "tcp")] | ||||
|     #![all(feature = "tcp", any(feature = "http1", feature = "http2"))] | ||||
|  | ||||
|     impl Server<AddrIncoming, ()> { | ||||
|         /// Binds to the provided address, and returns a [`Builder`](Builder). | ||||
| @@ -83,7 +102,7 @@ cfg_feature! { | ||||
| } | ||||
|  | ||||
| cfg_feature! { | ||||
|     #![all(feature = "tcp")] | ||||
|     #![all(feature = "tcp", any(feature = "http1", feature = "http2"))] | ||||
|  | ||||
|     impl<S, E> Server<AddrIncoming, S, E> { | ||||
|         /// Returns the local address that this server is bound to. | ||||
| @@ -93,6 +112,8 @@ cfg_feature! { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| impl<I, IO, IE, S, E, B> Server<I, S, E> | ||||
| where | ||||
|     I: Accept<Conn = IO, Error = IE>, | ||||
| @@ -149,6 +170,8 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| impl<I, IO, IE, S, B, E> Future for Server<I, S, E> | ||||
| where | ||||
|     I: Accept<Conn = IO, Error = IE>, | ||||
| @@ -170,14 +193,17 @@ where | ||||
|  | ||||
| impl<I: fmt::Debug, S: fmt::Debug> fmt::Debug for Server<I, S> { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         f.debug_struct("Server") | ||||
|             .field("listener", &self.spawn_all.incoming_ref()) | ||||
|             .finish() | ||||
|         let mut st = f.debug_struct("Server"); | ||||
|         #[cfg(any(feature = "http1", feature = "http2"))] | ||||
|         st.field("listener", &self.spawn_all.incoming_ref()); | ||||
|         st.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ===== impl Builder ===== | ||||
|  | ||||
| #[cfg(any(feature = "http1", feature = "http2"))] | ||||
| #[cfg_attr(docsrs, doc(cfg(any(feature = "http1", feature = "http2"))))] | ||||
| impl<I, E> Builder<I, E> { | ||||
|     /// Start a new builder, wrapping an incoming stream and low-level options. | ||||
|     /// | ||||
| @@ -435,7 +461,7 @@ impl<I, E> Builder<I, E> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "tcp")] | ||||
| #[cfg(all(feature = "tcp", any(feature = "http1", feature = "http2")))] | ||||
| impl<E> Builder<AddrIncoming, E> { | ||||
|     /// Set whether TCP keepalive messages are enabled on accepted connections. | ||||
|     /// | ||||
|   | ||||
		Reference in New Issue
	
	Block a user