//! HTTP Server use std::io::{Listener, IoResult, EndOfFile}; use std::io::net::ip::{IpAddr, Port, SocketAddr}; use intertwine::{Intertwine, Intertwined}; use macceptor::MoveAcceptor; pub use self::request::Request; pub use self::response::Response; use {HttpResult}; use net::{NetworkListener, NetworkAcceptor, NetworkStream, HttpAcceptor, HttpListener, HttpStream, Fresh}; pub mod request; pub mod response; /// A server can listen on a TCP socket. /// /// Once listening, it will create a `Request`/`Response` pair for each /// incoming connection, and hand them to the provided handler. pub struct Server { pairs: Vec<(IpAddr, Port)> } macro_rules! try_option( ($e:expr) => {{ match $e { Some(v) => v, None => return None } }} ) impl Server { /// Creates a new server that will handle `HttpStream`s. pub fn http(ip: IpAddr, port: Port) -> Server { Server { pairs: vec![(ip, port)] } } /// Creates a server that can listen to many (ip, port) pairs. pub fn many(pairs: Vec<(IpAddr, Port)>) -> Server { Server { pairs: pairs } } } impl, S: NetworkStream, A: NetworkAcceptor> Server { /// Binds to a socket, and starts handling connections. /// /// This method has unbound type parameters, so can be used when you want to use /// something other than the provided HttpStream, HttpAcceptor, and HttpListener. pub fn listen_network(self, handler: H) -> HttpResult> where H: Handler, S: NetworkStream, A: NetworkAcceptor, L: NetworkListener, { let mut acceptors = Vec::new(); let mut sockets = Vec::new(); for (ip, port) in self.pairs.into_iter() { let mut listener: L = try_io!(NetworkListener::::bind(ip.to_string().as_slice(), port)); sockets.push(try_io!(listener.socket_name())); let acceptor = try_io!(listener.listen()); acceptors.push(acceptor.clone()); } let connections = acceptors.clone() .into_iter() .map(|acceptor| acceptor.move_incoming()) .intertwine(); spawn(proc() { handler.handle(Incoming { from: connections }); }); Ok(Listening { acceptors: acceptors, sockets: sockets, }) } /// Binds to a socket and starts handling connections. pub fn listen>(self, handler: H) -> HttpResult> { self.listen_network::(handler) } } /// An iterator over incoming connections, represented as pairs of /// hyper Requests and Responses. pub struct Incoming { from: Intertwined> } impl Iterator<(Request, Response)> for Incoming { fn next(&mut self) -> Option<(Request, Response)> { for conn in self.from { match conn { Ok(stream) => { debug!("Incoming stream"); let clone = stream.clone(); let req = match Request::new(stream) { Ok(r) => r, Err(err) => { error!("creating Request: {}", err); continue; } }; let mut res = Response::new(clone); res.version = req.version; return Some((req, res)) }, Err(ref e) if e.kind == EndOfFile => return None, // server closed Err(e) => { error!("Connection failed: {}", e); continue; } } } None } } /// A listening server, which can later be closed. pub struct Listening { acceptors: Vec, /// The socket addresses that the server is bound to. pub sockets: Vec, } impl, S: NetworkStream> Listening { /// Stop the server from listening to all of its socket addresses. /// /// If closing any of the servers acceptors fails, this function returns Err /// and does not close the rest of the acceptors. pub fn close(&mut self) -> HttpResult<()> { debug!("closing server"); for acceptor in self.acceptors.iter_mut() { try_io!(acceptor.close()); } Ok(()) } } /// A handler that can handle incoming requests for a server. pub trait Handler, S: NetworkStream>: Send { /// Receives a `Request`/`Response` pair, and should perform some action on them. /// /// This could reading from the request, and writing to the response. fn handle(self, Incoming); } impl, S: NetworkStream> Handler for fn(Incoming) { fn handle(self, incoming: Incoming) { (self)(incoming) } }