如标题所说,我想写一个https服务器,使用hyper crate。
async fn runmain() {
let addr = SocketAddr::from(([127, 0, 0, 1], 25025));
let make_service = make_service_fn(|_conn| async {
Ok::<_, hyper::Error>(service_fn(handle))
});
// Then bind and serve...
// And run forever...
if let Err(e) = Server::bind(&addr).serve(make_service).await {
eprintln!("server error: {}", e);
}
println!("START!");
}
但是只能服务http请求,文档没有展示如何服务https,只是提到可以使用hyper_tls来处理客户端请求,
不幸的是,使用 hyper 创建 https 服务器需要花费一些精力。我不明白为什么这么难,但是这个例子帮助了我:
请注意,该版本应该在它所在的代码库中工作,但您的板条箱可能是不同的版本。在这种情况下,您应该找到适合您的 hyper-rustls 版本的示例。
#[tokio::main]
async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Set a process wide default crypto provider.
#[cfg(feature = "ring")]
let _ = rustls::crypto::ring::default_provider().install_default();
#[cfg(feature = "aws-lc-rs")]
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
// First parameter is port number (optional, defaults to 1337)
let port = match env::args().nth(1) {
Some(ref p) => p.parse()?,
None => 1337,
};
let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port);
// Load public certificate.
let certs = load_certs("examples/sample.pem")?;
// Load private key.
let key = load_private_key("examples/sample.rsa")?;
println!("Starting to serve on https://{}", addr);
// Create a TCP listener via tokio.
let incoming = TcpListener::bind(&addr).await?;
// Build TLS configuration.
let mut server_config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.map_err(|e| error(e.to_string()))?;
server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()];
let tls_acceptor = TlsAcceptor::from(Arc::new(server_config));
let service = service_fn(echo);
loop {
let (tcp_stream, _remote_addr) = incoming.accept().await?;
let tls_acceptor = tls_acceptor.clone();
tokio::spawn(async move {
let tls_stream = match tls_acceptor.accept(tcp_stream).await {
Ok(tls_stream) => tls_stream,
Err(err) => {
eprintln!("failed to perform tls handshake: {err:#}");
return;
}
};
if let Err(err) = Builder::new(TokioExecutor::new())
.serve_connection(TokioIo::new(tls_stream), service)
.await
{
eprintln!("failed to serve connection: {err:#}");
}
});
}
}