use std::convert::Infallible;
use std::env;
use std::path::PathBuf;
use std::sync::Arc;
use bytes::Bytes;
use http_body_util::Full;
use hyper::service::service_fn;
use hyper::{Request, Response};
use hyper_util::rt::TokioExecutor;
use hyper_util::server::conn::auto;
use tokio::net::TcpListener;
use tokio_aws_lc::hyper::HyperAcceptor;
use tokio_aws_lc::{ServerConfig, TlsAcceptor};
async fn hello(req: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
let body = format!("hello {} {}\n", req.method(), req.uri().path());
Ok(Response::new(Full::new(Bytes::from(body))))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = env::args().skip(1);
let bind: String = args.next().unwrap_or_else(|| "127.0.0.1:8443".into());
let cert: PathBuf = args
.next()
.map_or_else(|| PathBuf::from("tests/data/cert.pem"), PathBuf::from);
let key: PathBuf = args
.next()
.map_or_else(|| PathBuf::from("tests/data/key.pem"), PathBuf::from);
let cfg = Arc::new(
ServerConfig::builder()
.alpn_protocols(&[b"h2", b"http/1.1"])
.with_pem_files(&cert, &key)?,
);
let acceptor = HyperAcceptor::new(TlsAcceptor::new(cfg));
let listener = TcpListener::bind(&bind).await?;
eprintln!("hyper-server listening on https://{bind}");
loop {
let (tcp, peer) = listener.accept().await?;
let acceptor = acceptor.clone();
tokio::spawn(async move {
let io = match acceptor.accept(tcp).await {
Ok(io) => io,
Err(e) => {
eprintln!("{peer}: handshake failed: {e}");
return;
}
};
if let Err(e) = auto::Builder::new(TokioExecutor::new())
.serve_connection(io, service_fn(hello))
.await
{
eprintln!("{peer}: hyper error: {e}");
}
});
}
}