feat(ssl): redesign SSL usage
BREAKING CHANGE: Server::https was changed to allow any implementation of Ssl. Server in general was also changed. HttpConnector no longer uses SSL; using HttpsConnector instead.
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
//! // handle things here
|
||||
//! }
|
||||
//!
|
||||
//! Server::http(hello).listen("0.0.0.0:0").unwrap();
|
||||
//! Server::http("0.0.0.0:0").unwrap().handle(hello).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! As with any trait, you can also define a struct and implement `Handler`
|
||||
@@ -43,9 +43,9 @@
|
||||
//!
|
||||
//!
|
||||
//! let (tx, rx) = channel();
|
||||
//! Server::http(SenderHandler {
|
||||
//! Server::http("0.0.0.0:0").unwrap().handle(SenderHandler {
|
||||
//! sender: Mutex::new(tx)
|
||||
//! }).listen("0.0.0.0:0").unwrap();
|
||||
//! }).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! Since the `Server` will be listening on multiple threads, the `Handler`
|
||||
@@ -56,9 +56,9 @@
|
||||
//! use hyper::server::{Server, Request, Response};
|
||||
//!
|
||||
//! let counter = AtomicUsize::new(0);
|
||||
//! Server::http(move |req: Request, res: Response| {
|
||||
//! Server::http("0.0.0.0:0").unwrap().handle(move |req: Request, res: Response| {
|
||||
//! counter.fetch_add(1, Ordering::Relaxed);
|
||||
//! }).listen("0.0.0.0:0").unwrap();
|
||||
//! }).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! # The `Request` and `Response` pair
|
||||
@@ -76,14 +76,14 @@
|
||||
//! use hyper::server::{Server, Request, Response};
|
||||
//! use hyper::status::StatusCode;
|
||||
//!
|
||||
//! Server::http(|mut req: Request, mut res: Response| {
|
||||
//! Server::http("0.0.0.0:0").unwrap().handle(|mut req: Request, mut res: Response| {
|
||||
//! match req.method {
|
||||
//! hyper::Post => {
|
||||
//! io::copy(&mut req, &mut res.start().unwrap()).unwrap();
|
||||
//! },
|
||||
//! _ => *res.status_mut() = StatusCode::MethodNotAllowed
|
||||
//! }
|
||||
//! }).listen("0.0.0.0:0").unwrap();
|
||||
//! }).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! ## An aside: Write Status
|
||||
@@ -107,30 +107,12 @@
|
||||
//! out by calling `start` on the `Request<Fresh>`. This will return a new
|
||||
//! `Request<Streaming>` object, that no longer has `headers_mut()`, but does
|
||||
//! implement `Write`.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use hyper::server::{Server, Request, Response};
|
||||
//! use hyper::status::StatusCode;
|
||||
//! use hyper::uri::RequestUri;
|
||||
//!
|
||||
//! let server = Server::http(|req: Request, mut res: Response| {
|
||||
//! *res.status_mut() = match (req.method, req.uri) {
|
||||
//! (hyper::Get, RequestUri::AbsolutePath(ref path)) if path == "/" => {
|
||||
//! StatusCode::Ok
|
||||
//! },
|
||||
//! (hyper::Get, _) => StatusCode::NotFound,
|
||||
//! _ => StatusCode::MethodNotAllowed
|
||||
//! };
|
||||
//! }).listen("0.0.0.0:8080").unwrap();
|
||||
use std::fmt;
|
||||
use std::io::{ErrorKind, BufWriter, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::net::{SocketAddr, ToSocketAddrs};
|
||||
use std::path::Path;
|
||||
use std::thread::{self, JoinHandle};
|
||||
|
||||
use num_cpus;
|
||||
use openssl::ssl::SslContext;
|
||||
|
||||
pub use self::request::Request;
|
||||
pub use self::response::Response;
|
||||
@@ -142,7 +124,7 @@ use buffer::BufReader;
|
||||
use header::{Headers, Expect, Connection};
|
||||
use http;
|
||||
use method::Method;
|
||||
use net::{NetworkListener, NetworkStream, HttpListener};
|
||||
use net::{NetworkListener, NetworkStream, HttpListener, HttpsListener, Ssl};
|
||||
use status::StatusCode;
|
||||
use uri::RequestUri;
|
||||
use version::HttpVersion::Http11;
|
||||
@@ -154,21 +136,13 @@ pub mod response;
|
||||
|
||||
mod listener;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum SslConfig<'a> {
|
||||
CertAndKey(&'a Path, &'a Path),
|
||||
Context(SslContext),
|
||||
}
|
||||
|
||||
/// 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.
|
||||
#[derive(Debug)]
|
||||
pub struct Server<'a, H: Handler, L = HttpListener> {
|
||||
handler: H,
|
||||
ssl: Option<SslConfig<'a>>,
|
||||
_marker: PhantomData<L>
|
||||
pub struct Server<L = HttpListener> {
|
||||
listener: L,
|
||||
}
|
||||
|
||||
macro_rules! try_option(
|
||||
@@ -180,64 +154,41 @@ macro_rules! try_option(
|
||||
}}
|
||||
);
|
||||
|
||||
impl<'a, H: Handler, L: NetworkListener> Server<'a, H, L> {
|
||||
impl<L: NetworkListener> Server<L> {
|
||||
/// Creates a new server with the provided handler.
|
||||
pub fn new(handler: H) -> Server<'a, H, L> {
|
||||
#[inline]
|
||||
pub fn new(listener: L) -> Server<L> {
|
||||
Server {
|
||||
handler: handler,
|
||||
ssl: None,
|
||||
_marker: PhantomData
|
||||
listener: listener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, H: Handler + 'static> Server<'a, H, HttpListener> {
|
||||
impl Server<HttpListener> {
|
||||
/// Creates a new server that will handle `HttpStream`s.
|
||||
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 {
|
||||
handler: handler,
|
||||
ssl: Some(SslConfig::CertAndKey(cert, key)),
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
/// Creates a new server that will handler `HttpStreams`s using a TLS connection defined by an SslContext.
|
||||
pub fn https_with_context(handler: H, ssl_context: SslContext) -> Server<'a, H, HttpListener> {
|
||||
Server {
|
||||
handler: handler,
|
||||
ssl: Some(SslConfig::Context(ssl_context)),
|
||||
_marker: PhantomData
|
||||
}
|
||||
pub fn http<To: ToSocketAddrs>(addr: To) -> ::Result<Server<HttpListener>> {
|
||||
HttpListener::new(addr).map(Server::new)
|
||||
}
|
||||
}
|
||||
|
||||
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<T: ToSocketAddrs>(self, addr: T, threads: usize) -> ::Result<Listening> {
|
||||
let listener = try!(match self.ssl {
|
||||
Some(SslConfig::CertAndKey(cert, key)) => HttpListener::https(addr, cert, key),
|
||||
Some(SslConfig::Context(ssl_context)) => HttpListener::https_with_context(addr, ssl_context),
|
||||
None => HttpListener::http(addr)
|
||||
});
|
||||
with_listener(self.handler, listener, threads)
|
||||
impl<S: Ssl + Clone + Send> Server<HttpsListener<S>> {
|
||||
/// Creates a new server that will handle `HttpStream`s over SSL.
|
||||
///
|
||||
/// You can use any SSL implementation, as long as implements `hyper::net::Ssl`.
|
||||
pub fn https<A: ToSocketAddrs>(addr: A, ssl: S) -> ::Result<Server<HttpsListener<S>>> {
|
||||
HttpsListener::new(addr, ssl).map(Server::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: NetworkListener + Send + 'static> Server<L> {
|
||||
/// Binds to a socket and starts handling connections.
|
||||
pub fn listen<T: ToSocketAddrs>(self, addr: T) -> ::Result<Listening> {
|
||||
self.listen_threads(addr, num_cpus::get() * 5 / 4)
|
||||
pub fn handle<H: Handler + 'static>(self, handler: H) -> ::Result<Listening> {
|
||||
with_listener(handler, self.listener, num_cpus::get() * 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, listener: L, threads: usize) -> ::Result<Listening> {
|
||||
with_listener(self.handler, listener, threads)
|
||||
/// Binds to a socket and starts handling connections with the provided
|
||||
/// number of threads.
|
||||
pub fn handle_threads<H: Handler + 'static>(self, handler: H, threads: usize) -> ::Result<Listening> {
|
||||
with_listener(handler, self.listener, threads)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +198,7 @@ L: NetworkListener + Send + 'static {
|
||||
let socket = try!(listener.local_addr());
|
||||
|
||||
debug!("threads = {:?}", threads);
|
||||
let pool = ListenerPool::new(listener.clone());
|
||||
let pool = ListenerPool::new(listener);
|
||||
let work = move |mut stream| Worker(&handler).handle_connection(&mut stream);
|
||||
|
||||
let guard = thread::spawn(move || pool.accept(work, threads));
|
||||
|
||||
Reference in New Issue
Block a user