如何使用 RUST 编写 https 服务器?

问题描述 投票:0回答:1

如标题所说,我想写一个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来处理客户端请求,

rust hyper
1个回答
0
投票

不幸的是,使用 hyper 创建 https 服务器需要花费一些精力。我不明白为什么这么难,但是这个例子帮助了我:

https://github.com/rustls/hyper-rustls/blob/cb05f463ed7d34e18fa580fd7249eddebcc39ec5/examples/server.rs

请注意,该版本应该在它所在的代码库中工作,但您的板条箱可能是不同的版本。在这种情况下,您应该找到适合您的 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:#}");
            }
        });
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.