@@ -164,6 +164,11 @@ impl HttpListener {
|
|||||||
try!(ssl_context.set_certificate_file(cert, X509FileType::PEM).map_err(lift_ssl_error));
|
try!(ssl_context.set_certificate_file(cert, X509FileType::PEM).map_err(lift_ssl_error));
|
||||||
try!(ssl_context.set_private_key_file(key, X509FileType::PEM).map_err(lift_ssl_error));
|
try!(ssl_context.set_private_key_file(key, X509FileType::PEM).map_err(lift_ssl_error));
|
||||||
ssl_context.set_verify(SSL_VERIFY_NONE, None);
|
ssl_context.set_verify(SSL_VERIFY_NONE, None);
|
||||||
|
HttpListener::https_with_context(addr, ssl_context)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start listening to an address of HTTPS using the given SslContext
|
||||||
|
pub fn https_with_context<To: ToSocketAddrs>(addr: To, ssl_context: SslContext) -> io::Result<HttpListener> {
|
||||||
Ok(HttpListener::Https(try!(TcpListener::bind(addr)), Arc::new(ssl_context)))
|
Ok(HttpListener::Https(try!(TcpListener::bind(addr)), Arc::new(ssl_context)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use std::path::Path;
|
|||||||
use std::thread::{self, JoinHandle};
|
use std::thread::{self, JoinHandle};
|
||||||
|
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
|
use openssl::ssl::SslContext;
|
||||||
|
|
||||||
pub use self::request::Request;
|
pub use self::request::Request;
|
||||||
pub use self::response::Response;
|
pub use self::response::Response;
|
||||||
@@ -50,6 +51,12 @@ pub mod response;
|
|||||||
|
|
||||||
mod listener;
|
mod listener;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum SslConfig<'a> {
|
||||||
|
CertAndKey(&'a Path, &'a Path),
|
||||||
|
Context(SslContext),
|
||||||
|
}
|
||||||
|
|
||||||
/// A server can listen on a TCP socket.
|
/// A server can listen on a TCP socket.
|
||||||
///
|
///
|
||||||
/// Once listening, it will create a `Request`/`Response` pair for each
|
/// Once listening, it will create a `Request`/`Response` pair for each
|
||||||
@@ -57,7 +64,7 @@ mod listener;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Server<'a, H: Handler, L = HttpListener> {
|
pub struct Server<'a, H: Handler, L = HttpListener> {
|
||||||
handler: H,
|
handler: H,
|
||||||
ssl: Option<(&'a Path, &'a Path)>,
|
ssl: Option<SslConfig<'a>>,
|
||||||
_marker: PhantomData<L>
|
_marker: PhantomData<L>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +97,15 @@ impl<'a, H: Handler + 'static> Server<'a, H, HttpListener> {
|
|||||||
pub fn https(handler: H, cert: &'a Path, key: &'a Path) -> Server<'a, H, HttpListener> {
|
pub fn https(handler: H, cert: &'a Path, key: &'a Path) -> Server<'a, H, HttpListener> {
|
||||||
Server {
|
Server {
|
||||||
handler: handler,
|
handler: handler,
|
||||||
ssl: Some((cert, key)),
|
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
|
_marker: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,10 +115,11 @@ impl<'a, H: Handler + 'static> Server<'a, H, HttpListener> {
|
|||||||
/// Binds to a socket, and starts handling connections using a task pool.
|
/// Binds to a socket, and starts handling connections using a task pool.
|
||||||
pub fn listen_threads<T: ToSocketAddrs>(self, addr: T, threads: usize) -> HttpResult<Listening> {
|
pub fn listen_threads<T: ToSocketAddrs>(self, addr: T, threads: usize) -> HttpResult<Listening> {
|
||||||
let listener = try!(match self.ssl {
|
let listener = try!(match self.ssl {
|
||||||
Some((cert, key)) => HttpListener::https(addr, cert, key),
|
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)
|
None => HttpListener::http(addr)
|
||||||
});
|
});
|
||||||
self.with_listener(listener, threads)
|
with_listener(self.handler, listener, threads)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Binds to a socket and starts handling connections.
|
/// Binds to a socket and starts handling connections.
|
||||||
@@ -117,9 +133,15 @@ H: Handler + 'static,
|
|||||||
L: NetworkListener<Stream=S> + Send + 'static,
|
L: NetworkListener<Stream=S> + Send + 'static,
|
||||||
S: NetworkStream + Clone + Send> Server<'a, H, L> {
|
S: NetworkStream + Clone + Send> Server<'a, H, L> {
|
||||||
/// Creates a new server that will handle `HttpStream`s.
|
/// Creates a new server that will handle `HttpStream`s.
|
||||||
pub fn with_listener(self, mut listener: L, threads: usize) -> HttpResult<Listening> {
|
pub fn with_listener(self, listener: L, threads: usize) -> HttpResult<Listening> {
|
||||||
|
with_listener(self.handler, listener, threads)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_listener<H, L>(handler: H, mut listener: L, threads: usize) -> HttpResult<Listening>
|
||||||
|
where H: Handler + 'static,
|
||||||
|
L: NetworkListener + Send + 'static {
|
||||||
let socket = try!(listener.local_addr());
|
let socket = try!(listener.local_addr());
|
||||||
let handler = self.handler;
|
|
||||||
|
|
||||||
debug!("threads = {:?}", threads);
|
debug!("threads = {:?}", threads);
|
||||||
let pool = ListenerPool::new(listener.clone());
|
let pool = ListenerPool::new(listener.clone());
|
||||||
@@ -132,8 +154,6 @@ S: NetworkStream + Clone + Send> Server<'a, H, L> {
|
|||||||
socket: socket,
|
socket: socket,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn handle_connection<'h, S, H>(mut stream: &mut S, handler: &'h H)
|
fn handle_connection<'h, S, H>(mut stream: &mut S, handler: &'h H)
|
||||||
where S: NetworkStream + Clone, H: Handler {
|
where S: NetworkStream + Clone, H: Handler {
|
||||||
|
|||||||
Reference in New Issue
Block a user