//! Run with //! //! ```not_rust //! cargo run -p example-low-level-rustls //! ``` use axum::{extract::ConnectInfo, routing::get, Router}; use futures_util::future::poll_fn; use hyper::server::{ accept::Accept, conn::{AddrIncoming, Http}, }; use rustls_pemfile::{certs, pkcs8_private_keys}; use std::{fs::File, io::BufReader, net::SocketAddr, pin::Pin, sync::Arc}; use tokio::net::TcpListener; use tokio_rustls::{ rustls::{Certificate, PrivateKey, ServerConfig}, TlsAcceptor, }; use tower::MakeService; #[tokio::main] async fn main() { // Set the RUST_LOG, if it hasn't been explicitly defined if std::env::var_os("RUST_LOG").is_none() { std::env::set_var("RUST_LOG", "example_tls_rustls=debug") } tracing_subscriber::fmt::init(); let rustls_config = rustls_server_config( "examples/tls-rustls/self_signed_certs/key.pem", "examples/tls-rustls/self_signed_certs/cert.pem", ); let acceptor = TlsAcceptor::from(rustls_config); let listener = TcpListener::bind("127.0.0.1:3000").await.unwrap(); let mut listener = AddrIncoming::from_listener(listener).unwrap(); let mut app = Router::new() .route("/", get(handler)) .into_make_service_with_connect_info::(); loop { let stream = poll_fn(|cx| Pin::new(&mut listener).poll_accept(cx)) .await .unwrap() .unwrap(); let acceptor = acceptor.clone(); let app = app.make_service(&stream).await.unwrap(); tokio::spawn(async move { if let Ok(stream) = acceptor.accept(stream).await { let _ = Http::new().serve_connection(stream, app).await; } }); } } async fn handler(ConnectInfo(addr): ConnectInfo) -> String { addr.to_string() } fn rustls_server_config(key: &str, cert: &str) -> Arc { let mut key_reader = BufReader::new(File::open(key).unwrap()); let mut cert_reader = BufReader::new(File::open(cert).unwrap()); let key = PrivateKey(pkcs8_private_keys(&mut key_reader).unwrap().remove(0)); let certs = certs(&mut cert_reader) .unwrap() .into_iter() .map(Certificate) .collect(); let mut config = ServerConfig::builder() .with_safe_defaults() .with_no_client_auth() .with_single_cert(certs, key) .expect("bad certificate/key"); config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; Arc::new(config) }