I tested my service using this website: https://myssl.com/
log:
[101.89.87.44:5388] TLS handshake failed: tls handshake eof
[101.89.87.44:5390] TLS handshake failed: tls handshake eof
[101.89.87.44:5392] TLS handshake failed: tls handshake eof
[101.89.87.44:5393] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5395] TLS handshake failed: tls handshake eof
[101.89.87.44:5394] TLS handshake failed: tls handshake eof
[101.89.87.44:5398] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5396] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5397] TLS handshake failed: tls handshake eof
[101.89.87.44:5401] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5402] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5403] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5400] TLS handshake failed: tls handshake eof
[101.89.87.44:5408] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5404] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5406] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5405] TLS handshake failed: Connection reset by peer (os error 104)
code is :
use anyhow::Result;
use hyper::{body::Incoming as IncomingBody, Request, Response};
use hyper::service::service_fn;
use rustls::ServerConfig;
use rustls_pemfile::{certs, private_key};
use std::fs::File;
use std::io::BufReader;
use std::net::SocketAddr;
use std::sync::Arc;
use tokio::net::TcpListener;
use tokio_rustls::TlsAcceptor;
// Load TLS certificates
fn load_certs(path: &str) -> Result<Vec<rustls::pki_types::CertificateDer<'static>>> {
let file = File::open(path)?;
let mut reader = BufReader::new(file);
// Use collect to convert iterator to Vec<Result<...>>
let certs_result: Result<Vec<_>, _> = certs(&mut reader).collect();
let certs = certs_result.map_err(|e| anyhow::anyhow!("Failed to load certificates: {}", e))?;
Ok(certs)
}
// Load TLS private key
fn load_private_key(path: &str) -> Result<rustls::pki_types::PrivateKeyDer<'static>> {
let file = File::open(path)?;
let mut reader = BufReader::new(file);
// Use private_key function instead of pkcs8_private_keys
let key = private_key(&mut reader)
.map_err(|e| anyhow::anyhow!("Failed to load private key: {}", e))?
.ok_or_else(|| anyhow::anyhow!("Private key not found"))?;
Ok(key)
}
// Handle HTTP requests
async fn handle_request(_req: Request<IncomingBody>) -> Result<Response<String>, hyper::Error> {
Ok(Response::new("Hello, HTTPS World with Latest Deps!".to_string()))
}
#[tokio::main]
async fn main() -> Result<()> {
// --- 1. Generate self-signed certificate (for development) ---
// openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
// --- 2. Load TLS configuration ---
let certs = load_certs("certs/cert.pem")?;
let key = load_private_key("certs/key.pem")?;
// Rustls 0.22+ config construction
let tls_config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.map_err(|e| anyhow::anyhow!("TLS configuration failed: {}", e))?;
let tls_acceptor = TlsAcceptor::from(Arc::new(tls_config));
// --- 3. Bind to port 443 (requires root privileges) ---
let addr: SocketAddr = ([0, 0, 0, 0], 443).into();
let listener = TcpListener::bind(addr).await?;
println!("HTTPS server started: https://{}", addr);
// --- 4. Accept connections in a loop (Hyper 1.x new API) ---
loop {
let (tcp_stream, peer_addr) = listener.accept().await?;
let tls_acceptor = tls_acceptor.clone();
tokio::spawn(async move {
// TLS handshake
let tls_stream = match tls_acceptor.accept(tcp_stream).await {
Ok(stream) => stream,
Err(e) => {
eprintln!("[{}] TLS handshake failed: {}", peer_addr, e);
return;
}
};
// Use hyper_util's TokioIo
// Ensure Cargo.toml has: hyper-util = { version = "0.1", features = ["tokio"] }
use hyper_util::rt::tokio::TokioIo;
let io = TokioIo::new(tls_stream);
// Serve the connection
if let Err(e) = hyper::server::conn::http1::Builder::new()
.serve_connection(io, service_fn(handle_request))
.await
{
eprintln!("[{}] Connection handling error: {}", peer_addr, e);
}
});
}
}
toml is:
[package]
name = "hyper-rustls-demo"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.102"
hyper = { version = "1.8.1", features = ["full"] }
rustls = "0.23.37"
rustls-pemfile = "2.2.0"
tokio = { version = "1.50.0", features = ["full"] }
tokio-rustls = "0.26.4"
hyper-util={version = "0.1.20" , features = ["tokio"]}
I tested my service using this website: https://myssl.com/
log:
[101.89.87.44:5388] TLS handshake failed: tls handshake eof
[101.89.87.44:5390] TLS handshake failed: tls handshake eof
[101.89.87.44:5392] TLS handshake failed: tls handshake eof
[101.89.87.44:5393] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5395] TLS handshake failed: tls handshake eof
[101.89.87.44:5394] TLS handshake failed: tls handshake eof
[101.89.87.44:5398] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5396] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5397] TLS handshake failed: tls handshake eof
[101.89.87.44:5401] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5402] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5403] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5400] TLS handshake failed: tls handshake eof
[101.89.87.44:5408] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5404] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5406] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5405] TLS handshake failed: Connection reset by peer (os error 104)
code is :
toml is: