#![deny(warnings)]
extern crate futures;
extern crate hyper;
extern crate rustls;
extern crate tokio;
extern crate tokio_rustls;
extern crate tokio_tcp;
use futures::future;
use futures::Stream;
use hyper::rt::Future;
use hyper::service::service_fn;
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use rustls::internal::pemfile;
use std::{env, fs, io, sync};
use tokio_rustls::TlsAcceptor;
fn main() {
if let Err(e) = run_server() {
eprintln!("FAILED: {}", e);
std::process::exit(1);
}
}
fn error(err: String) -> io::Error {
io::Error::new(io::ErrorKind::Other, err)
}
fn run_server() -> io::Result<()> {
let port = match env::args().nth(1) {
Some(ref p) => p.to_owned(),
None => "1337".to_owned(),
};
let addr = format!("127.0.0.1:{}", port)
.parse()
.map_err(|e| error(format!("{}", e)))?;
let tls_cfg = {
let certs = load_certs("examples/sample.pem")?;
let key = load_private_key("examples/sample.rsa")?;
let mut cfg = rustls::ServerConfig::new(rustls::NoClientAuth::new());
cfg.set_single_cert(certs, key)
.map_err(|e| error(format!("{}", e)))?;
sync::Arc::new(cfg)
};
let tcp = tokio_tcp::TcpListener::bind(&addr)?;
let tls_acceptor = TlsAcceptor::from(tls_cfg);
let tls = tcp.incoming()
.and_then(move |s| tls_acceptor.accept(s))
.then(|r| match r {
Ok(x) => Ok::<_, io::Error>(Some(x)),
Err(_e) => {
println!("[!] Voluntary server halt due to client-connection error...");
Err(_e)
}
})
.filter_map(|x| x);
let fut = Server::builder(tls).serve(|| service_fn(echo));
println!("Starting to serve on https://{}.", addr);
let mut rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(fut)
.map_err(|e| error(format!("{}", e)))?;
Ok(())
}
type ResponseFuture = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;
fn echo(req: Request<Body>) -> ResponseFuture {
let mut response = Response::new(Body::empty());
match (req.method(), req.uri().path()) {
(&Method::GET, "/") => {
*response.body_mut() = Body::from("Try POST /echo\n");
}
(&Method::POST, "/echo") => {
*response.body_mut() = req.into_body();
}
_ => {
*response.status_mut() = StatusCode::NOT_FOUND;
}
};
Box::new(future::ok(response))
}
fn load_certs(filename: &str) -> io::Result<Vec<rustls::Certificate>> {
let certfile = fs::File::open(filename).map_err(|e| {
error(format!("failed to open {}: {}", filename, e))
})?;
let mut reader = io::BufReader::new(certfile);
pemfile::certs(&mut reader)
.map_err(|_| error("failed to load certificate".into()))
}
fn load_private_key(filename: &str) -> io::Result<rustls::PrivateKey> {
let keyfile = fs::File::open(filename).map_err(|e| {
error(format!("failed to open {}: {}", filename, e))
})?;
let mut reader = io::BufReader::new(keyfile);
let keys = pemfile::rsa_private_keys(&mut reader)
.map_err(|_| error("failed to load private key".into()))?;
if keys.len() != 1 {
return Err(error("expected a single private key".into()));
}
Ok(keys[0].clone())
}