feat(hyper): switch to std::io, std::net, and std::path.
All instances of `old_io` and `old_path` were switched to use the new shiny `std::io`, `std::net`, and `std::path` modules. This means that `Request` and `Response` implement `Read` and `Write` now. Because of the changes to `TcpListener`, this also takes the opportunity to correct the method usage of `Server`. As with other languages/frameworks, the server is first created with a handler, and then a host/port is passed to a `listen` method. This reverses what `Server` used to do. Closes #347 BREAKING CHANGE: Check the docs. Everything was touched.
This commit is contained in:
		| @@ -1,7 +1,9 @@ | ||||
| //! HTTP Server | ||||
| use std::old_io::{Listener, BufferedReader, BufferedWriter}; | ||||
| use std::old_io::net::ip::{IpAddr, Port, SocketAddr}; | ||||
| use std::io::{BufReader, BufWriter}; | ||||
| use std::marker::PhantomData; | ||||
| use std::net::{IpAddr, SocketAddr}; | ||||
| use std::os; | ||||
| use std::path::Path; | ||||
| use std::thread::{self, JoinGuard}; | ||||
|  | ||||
| pub use self::request::Request; | ||||
| @@ -13,25 +15,24 @@ use HttpError::HttpIoError; | ||||
| use {HttpResult}; | ||||
| use header::Connection; | ||||
| use header::ConnectionOption::{Close, KeepAlive}; | ||||
| use net::{NetworkListener, NetworkStream, NetworkAcceptor, | ||||
|           HttpAcceptor, HttpListener}; | ||||
| use net::{NetworkListener, NetworkStream, HttpListener}; | ||||
| use version::HttpVersion::{Http10, Http11}; | ||||
|  | ||||
| use self::acceptor::AcceptorPool; | ||||
| use self::listener::ListenerPool; | ||||
|  | ||||
| pub mod request; | ||||
| pub mod response; | ||||
|  | ||||
| mod acceptor; | ||||
| mod listener; | ||||
|  | ||||
| /// 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<L = HttpListener> { | ||||
|     ip: IpAddr, | ||||
|     port: Port, | ||||
|     listener: L, | ||||
| pub struct Server<'a, H: Handler, L = HttpListener> { | ||||
|     handler: H, | ||||
|     ssl: Option<(&'a Path, &'a Path)>, | ||||
|     _marker: PhantomData<L> | ||||
| } | ||||
|  | ||||
| macro_rules! try_option( | ||||
| @@ -43,38 +44,59 @@ macro_rules! try_option( | ||||
|     }} | ||||
| ); | ||||
|  | ||||
| impl Server<HttpListener> { | ||||
|     /// Creates a new server that will handle `HttpStream`s. | ||||
|     pub fn http(ip: IpAddr, port: Port) -> Server { | ||||
|         Server::with_listener(ip, port, HttpListener::Http) | ||||
|     } | ||||
|     /// Creates a new server that will handler `HttpStreams`s using a TLS connection. | ||||
|     pub fn https(ip: IpAddr, port: Port, cert: Path, key: Path) -> Server { | ||||
|         Server::with_listener(ip, port, HttpListener::Https(cert, key)) | ||||
| impl<'a, H: Handler, L: NetworkListener> Server<'a, H, L> { | ||||
|     pub fn new(handler: H) -> Server<'a, H, L> { | ||||
|         Server { | ||||
|             handler: handler, | ||||
|             ssl: None, | ||||
|             _marker: PhantomData | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl< | ||||
| L: NetworkListener<Acceptor=A> + Send, | ||||
| A: NetworkAcceptor<Stream=S> + Send + 'static, | ||||
| S: NetworkStream + Clone + Send> Server<L> { | ||||
| impl<'a, H: Handler + 'static> Server<'a, H, HttpListener> { | ||||
|     /// Creates a new server that will handle `HttpStream`s. | ||||
|     pub fn with_listener(ip: IpAddr, port: Port, listener: L) -> Server<L> { | ||||
|     pub fn http(handler: H) -> Server<'a, H, HttpListener> { | ||||
|         Server::new(handler) | ||||
|     } | ||||
|     /// Creates a new server that will handler `HttpStreams`s using a TLS connection. | ||||
|     pub fn https(handler: H, cert: &'a Path, key: &'a Path) -> Server<'a, H, HttpListener> { | ||||
|         Server { | ||||
|             ip: ip, | ||||
|             port: port, | ||||
|             listener: listener, | ||||
|             handler: handler, | ||||
|             ssl: Some((cert, key)), | ||||
|             _marker: PhantomData | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a, H: Handler + 'static> Server<'a, H, HttpListener> { | ||||
|     /// Binds to a socket, and starts handling connections using a task pool. | ||||
|     pub fn listen_threads<H: Handler + 'static>(mut self, handler: H, threads: usize) -> HttpResult<Listening<L::Acceptor>> { | ||||
|         debug!("binding to {:?}:{:?}", self.ip, self.port); | ||||
|         let acceptor = try!(self.listener.listen((self.ip, self.port))); | ||||
|         let socket = try!(acceptor.socket_name()); | ||||
|     pub fn listen_threads(self, ip: IpAddr, port: u16, threads: usize) -> HttpResult<Listening> { | ||||
|         let addr = &(ip, port); | ||||
|         let listener = try!(match self.ssl { | ||||
|             Some((cert, key)) => HttpListener::https(addr, cert, key), | ||||
|             None => HttpListener::http(addr) | ||||
|         }); | ||||
|         self.with_listener(listener, threads) | ||||
|     } | ||||
|  | ||||
|     /// Binds to a socket and starts handling connections. | ||||
|     pub fn listen(self, ip: IpAddr, port: u16) -> HttpResult<Listening> { | ||||
|         self.listen_threads(ip, port, os::num_cpus() * 5 / 4) | ||||
|     } | ||||
| } | ||||
| impl< | ||||
| 'a, | ||||
| H: Handler + 'static, | ||||
| L: NetworkListener<Stream=S> + Send + 'static, | ||||
| S: NetworkStream + Clone + Send> Server<'a, H, L> { | ||||
|     /// Creates a new server that will handle `HttpStream`s. | ||||
|     pub fn with_listener(self, mut listener: L, threads: usize) -> HttpResult<Listening> { | ||||
|         let socket = try!(listener.socket_addr()); | ||||
|         let handler = self.handler; | ||||
|  | ||||
|         debug!("threads = {:?}", threads); | ||||
|         let pool = AcceptorPool::new(acceptor.clone()); | ||||
|         let pool = ListenerPool::new(listener.clone()); | ||||
|         let work = move |stream| handle_connection(stream, &handler); | ||||
|  | ||||
|         let guard = thread::scoped(move || pool.accept(work, threads)); | ||||
| @@ -82,21 +104,15 @@ S: NetworkStream + Clone + Send> Server<L> { | ||||
|         Ok(Listening { | ||||
|             _guard: guard, | ||||
|             socket: socket, | ||||
|             acceptor: acceptor | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     /// Binds to a socket and starts handling connections. | ||||
|     pub fn listen<H: Handler + 'static>(self, handler: H) -> HttpResult<Listening<L::Acceptor>> { | ||||
|         self.listen_threads(handler, os::num_cpus() * 5 / 4) | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| fn handle_connection<S, H>(mut stream: S, handler: &H) | ||||
| where S: NetworkStream + Clone, H: Handler { | ||||
|     debug!("Incoming stream"); | ||||
|     let addr = match stream.peer_name() { | ||||
|     let addr = match stream.peer_addr() { | ||||
|         Ok(addr) => addr, | ||||
|         Err(e) => { | ||||
|             error!("Peer Name error: {:?}", e); | ||||
| @@ -104,8 +120,8 @@ where S: NetworkStream + Clone, H: Handler { | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let mut rdr = BufferedReader::new(stream.clone()); | ||||
|     let mut wrt = BufferedWriter::new(stream); | ||||
|     let mut rdr = BufReader::new(stream.clone()); | ||||
|     let mut wrt = BufWriter::new(stream); | ||||
|  | ||||
|     let mut keep_alive = true; | ||||
|     while keep_alive { | ||||
| @@ -135,18 +151,17 @@ where S: NetworkStream + Clone, H: Handler { | ||||
| } | ||||
|  | ||||
| /// A listening server, which can later be closed. | ||||
| pub struct Listening<A = HttpAcceptor> { | ||||
|     acceptor: A, | ||||
| pub struct Listening { | ||||
|     _guard: JoinGuard<'static, ()>, | ||||
|     /// The socket addresses that the server is bound to. | ||||
|     pub socket: SocketAddr, | ||||
| } | ||||
|  | ||||
| impl<A: NetworkAcceptor> Listening<A> { | ||||
| impl Listening { | ||||
|     /// Stop the server from listening to its socket address. | ||||
|     pub fn close(&mut self) -> HttpResult<()> { | ||||
|         debug!("closing server"); | ||||
|         try!(self.acceptor.close()); | ||||
|         //try!(self.acceptor.close()); | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user