Skip to content

Instantly share code, notes, and snippets.

@alex
Created September 23, 2017 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex/f67158c64c9d2c0b9e44f82028fef6fb to your computer and use it in GitHub Desktop.
Save alex/f67158c64c9d2c0b9e44f82028fef6fb to your computer and use it in GitHub Desktop.
// ...
serve_https(addr.parse().unwrap(), tls_config, 16, move |handle,
tls_session| {
let http_client = new_http_client(handle);
HttpHandler {
templates: Arc::clone(&templates),
http_client: Arc::new(http_client),
logs: Arc::clone(&logs),
handle: handle.clone(),
client_certs: tls_session.get_peer_certificates(),
}
});
}
fn serve_https<F, S>(
addr: SocketAddr,
tls_config: rustls::ServerConfig,
threads: usize,
new_service: F,
) where
F: Fn(&Handle, &rustls::ServerSession) -> S + Sync + Send + 'static,
S: tokio_service::Service<
Request = hyper::server::Request,
Response = hyper::server::Response,
Error = hyper::Error,
>
+ 'static,
{
let tls_config = Arc::new(tls_config);
let new_service = Arc::new(new_service);
let threads = (0..threads - 1)
.map(|i| {
let tls_config = Arc::clone(&tls_config);
let new_service = Arc::clone(&new_service);
thread::Builder::new()
.name(format!("worker{}", i))
.spawn(move || { _serve(addr, tls_config, &*new_service); })
.unwrap()
})
.collect::<Vec<_>>();
_serve(addr, tls_config, &*new_service);
for t in threads {
t.join().unwrap();
}
}
fn _serve<F, S>(addr: SocketAddr, tls_config: Arc<rustls::ServerConfig>, new_service: &F)
where
F: Fn(&Handle, &rustls::ServerSession) -> S,
S: tokio_service::Service<
Request = hyper::server::Request,
Response = hyper::server::Response,
Error = hyper::Error,
>
+ 'static,
{
let mut core = tokio_core::reactor::Core::new().unwrap();
let handle = core.handle();
let listener = match addr {
SocketAddr::V4(_) => net2::TcpBuilder::new_v4().unwrap(),
SocketAddr::V6(_) => net2::TcpBuilder::new_v6().unwrap(),
};
listener.reuse_port(true).unwrap();
listener.reuse_address(true).unwrap();
listener.bind(addr).unwrap();
let work = tokio_core::net::TcpListener::from_listener(
listener.listen(1024).unwrap(),
&addr,
&core.handle(),
).unwrap()
.incoming()
.for_each(move |(sock, addr)| {
let handle = handle.clone();
tls_config.accept_async(sock).map_err(|_| ()).and_then(move |s| {
let http = hyper::server::Http::new();
let service = new_service(&handle, s.get_ref().1);
http.bind_connection(&handle, s, addr, service);
Ok(())
}).or_else(|()| Ok(()))
});
core.run(work).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment