#![warn(rust_2018_idioms)] // A tiny async TLS echo server with Tokio use native_tls::Identity; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; /** an example to setup a tls server. how to test: wget https://127.0.0.1:12345 --no-check-certificate */ #[tokio::main] async fn main() -> Result<(), Box> { // Bind the server's socket let addr = "127.0.0.1:12345".to_string(); let tcp: TcpListener = TcpListener::bind(&addr).await?; // Create the TLS acceptor. let der = include_bytes!("identity.p12"); let cert = Identity::from_pkcs12(der, "mypass")?; let tls_acceptor = tokio_native_tls::TlsAcceptor::from(native_tls::TlsAcceptor::builder(cert).build()?); loop { // Asynchronously wait for an inbound socket. let (socket, remote_addr) = tcp.accept().await?; let tls_acceptor = tls_acceptor.clone(); println!("accept connection from {}", remote_addr); tokio::spawn(async move { // Accept the TLS connection. let mut tls_stream = tls_acceptor.accept(socket).await.expect("accept error"); // In a loop, read data from the socket and write the data back. let mut buf = [0; 1024]; let n = tls_stream .read(&mut buf) .await .expect("failed to read data from socket"); if n == 0 { return; } println!("read={}", unsafe { String::from_utf8_unchecked(buf[0..n].into()) }); tls_stream .write_all(&buf[0..n]) .await .expect("failed to write data to socket"); }); } }