diff --git a/src/server/mod.rs b/src/server/mod.rs index f07ee03554..21769bcf71 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -51,21 +51,33 @@ //! ``` pub mod conn; -#[cfg(feature = "runtime")] mod tcp; +#[cfg(feature = "runtime")] +mod tcp; +#[cfg(feature = "runtime")] +use std::error; use std::fmt; -#[cfg(feature = "runtime")] use std::net::SocketAddr; -#[cfg(feature = "runtime")] use std::time::Duration; +#[cfg(feature = "runtime")] +use std::net; +#[cfg(feature = "runtime")] +use std::net::SocketAddr; +#[cfg(feature = "runtime")] +use std::time::Duration; -use futures::{Future, Stream, Poll}; +use futures::{Future, Poll, Stream}; use tokio_io::{AsyncRead, AsyncWrite}; +#[cfg(feature = "runtime")] +use tokio_reactor; +#[cfg(feature = "runtime")] +use tokio_tcp; use body::{Body, Payload}; use service::{NewService, Service}; // Renamed `Http` as `Http_` for now so that people upgrading don't see an // error that `hyper::server::Http` is private... use self::conn::{Http as Http_, SpawnAll}; -#[cfg(feature = "runtime")] use self::tcp::{AddrIncoming}; +#[cfg(feature = "runtime")] +use self::tcp::AddrIncoming; /// A listening HTTP server that accepts connections in both HTTP1 and HTTP2 by default. /// @@ -96,6 +108,18 @@ impl Server { } } +impl Server { + /// Create a new instance from a `std::net::TcpListener` instance. + #[cfg(feature = "runtime")] + pub fn from_tcp( + listener: net::TcpListener, + ) -> Result, Box> { + let handle = tokio_reactor::Handle::current(); + let listener = tokio_tcp::TcpListener::from_std(listener, &handle)?; + Ok(Self::builder(listener.incoming())) + } +} + #[cfg(feature = "runtime")] impl Server { /// Binds to the provided address, and returns a [`Builder`](Builder). @@ -105,17 +129,15 @@ impl Server { /// 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, None) - .unwrap_or_else(|e| { - panic!("error binding to {}: {}", addr, e); - }); + let incoming = AddrIncoming::new(addr, None).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) -> ::Result> { - AddrIncoming::new(addr, None) - .map(Server::builder) + AddrIncoming::new(addr, None).map(Server::builder) } } @@ -132,7 +154,7 @@ where I: Stream, I::Error: Into>, I::Item: AsyncRead + AsyncWrite + Send + 'static, - S: NewService + Send + 'static, + S: NewService + Send + 'static, S::Error: Into>, S::Service: Send, S::Future: Send + 'static, @@ -162,10 +184,7 @@ impl Builder { /// /// For a more convenient constructor, see [`Server::bind`](Server::bind). pub fn new(incoming: I, protocol: Http_) -> Self { - Builder { - incoming, - protocol, - } + Builder { incoming, protocol } } /// Sets whether HTTP/1 is required. @@ -243,7 +262,7 @@ impl Builder { I: Stream, I::Error: Into>, I::Item: AsyncRead + AsyncWrite + Send + 'static, - S: NewService + Send + 'static, + S: NewService + Send + 'static, S::Error: Into>, S::Service: Send, ::Future: Send + 'static, @@ -251,9 +270,7 @@ impl Builder { { let serve = self.protocol.serve_incoming(self.incoming, new_service); let spawn_all = serve.spawn_all(); - Server { - spawn_all, - } + Server { spawn_all } } } @@ -275,4 +292,3 @@ impl Builder { self } } -