Skip to content

Instantly share code, notes, and snippets.

@boxofrox
Created May 22, 2017 00:16
Show Gist options
  • Save boxofrox/4d9b3bc05173b96543a1fce7680c8f67 to your computer and use it in GitHub Desktop.
Save boxofrox/4d9b3bc05173b96543a1fce7680c8f67 to your computer and use it in GitHub Desktop.
snippet of tokio-rs wrapping io:Error in a custom error-chain::Error
// load ssl certificate into tls handler
let tls_acceptor = TlsAcceptor::builder(load_pkcs12(pkcs12_file)?)
.chain_err(|| "invalid cert")?
.build()
.chain_err(|| "cannot build tls acceptor")?;
// create event loop for socket listener
let mut core = Core::new().chain_err(|| "cannot create event loop")?;
let handle = core.handle();
// open socket.
let listener = TcpListener::bind(&addr, &handle)
.chain_err(|| "cannot open socket")?;
info!("Server bound to socket: {}", addr);;
// accept incoming connections.
let connections = listener.incoming();
// Service can use custom error-chain errors instead of io::Error.
let service = HttpServer::new();
// pipe through tls handler.
let tls_handshake = connections.map(|(socket, addr)| {
tls_acceptor
.accept_async(socket)
.map_err(|e| {
error!("unexpected ssl error: closing connection: {}", e);
Error::from(e)
})
});
let server = tls_handshake.map(|acceptor| {
let service_handler = {
acceptor.and_then(move |socket| {
debug!("new connection handler for socket");
let (writer, reader) = socket.framed(HttpCodec::new()).split();
let responses = reader
.map_err(Error::from)
.and_then(move |request| service.call(request));
writer
.sink_map_err(Error::from)
.send_all(responses)
})
};
let server = service_handler
.then(|result| {
if let Err(e) = result {
error!("{}", e);
}
info!("connection closed");
Ok(())
});
handle.clone().spawn(server);
()
});
core.run(server.for_each(|_| Ok(())))
.chain_err(|| "server shutdown")?;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment