You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Rust结合hyper crate编写HTTPS服务端?

hyper本身服务端没有内置TLS能力,你需要搭配rustls生态的相关库完成HTTPS适配,具体实现步骤如下:

1. 新增依赖

首先在Cargo.toml中添加以下依赖,版本可根据实际情况更新到最新兼容版:

[dependencies]
hyper = { version = "1.0", features = ["full"] }
tokio = { version = "1.0", features = ["full"] }
rustls = "0.21"
rustls-pemfile = "1.0"
tokio-rustls = "0.24"
2. 准备TLS证书和私钥

你需要提前准备好PEM格式的TLS证书链文件(通常命名为fullchain.pem)和私钥文件(通常命名为privkey.pem):

  • 测试场景可以使用openssl生成自签名证书
  • 生产环境使用CA签发的有效公网证书
3. 适配HTTPS的完整代码示例

首先实现证书和私钥的加载逻辑,再替换原有的HTTP服务启动逻辑,修改后的代码如下:

use hyper::{Body, Request, Response, StatusCode};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::fs::File;
use std::io::BufReader;
use std::net::SocketAddr;
use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
use tokio_rustls::TlsAcceptor;
use tokio::net::TcpListener;

// 原有的请求处理逻辑无需修改
async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
    Ok(Response::new(Body::from("Hello HTTPS!")))
}

// 加载PEM格式证书
fn load_certs(path: &str) -> Vec<Certificate> {
    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    certs(&mut reader).unwrap().into_iter().map(Certificate).collect()
}

// 加载PEM格式私钥
fn load_private_key(path: &str) -> PrivateKey {
    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    pkcs8_private_keys(&mut reader).unwrap().remove(0).into()
}

async fn runmain() {
    let addr = SocketAddr::from(([127, 0, 0, 1], 25025));

    // 加载证书和私钥,替换为你自己的文件路径
    let certs = load_certs("fullchain.pem");
    let key = load_private_key("privkey.pem");

    // 初始化TLS服务端配置
    let config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(certs, key)
        .unwrap();
    let tls_acceptor = TlsAcceptor::from(std::sync::Arc::new(config));

    // 绑定TCP监听器
    let listener = TcpListener::bind(&addr).await.unwrap();
    println!("HTTPS server running on https://{}", addr);

    // 循环处理接入的连接
    loop {
        let (stream, _) = listener.accept().await.unwrap();
        let tls_acceptor = tls_acceptor.clone();
        let make_svc = make_service_fn(|_conn| async {
            Ok::<_, Infallible>(service_fn(handle))
        });

        tokio::spawn(async move {
            // 先完成TLS握手
            let tls_stream = match tls_acceptor.accept(stream).await {
                Ok(s) => s,
                Err(e) => {
                    eprintln!("TLS handshake failed: {}", e);
                    return;
                }
            };
            // 把握手后的TLS流交给hyper处理
            if let Err(e) = hyper::server::conn::Http::new()
                .serve_connection(tls_stream, make_svc)
                .await
            {
                eprintln!("HTTP service error: {}", e);
            }
        });
    }
}

#[tokio::main]
async fn main() {
    runmain().await;
}
注意事项
  • 测试自签名证书时浏览器会弹出安全警告,属于正常情况,手动信任证书后即可正常访问
  • 生产环境请使用有效期内、由可信CA签发的证书,避免用户访问报错
  • rustls默认配置已兼容HTTP/2,不需要额外修改配置即可启用

内容的提问来源于stack exchange,提问作者Hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:27:02