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

如何创建支持TLS(HTTPS)的Mock HTTP测试服务器?

实现支持HTTPS的测试回显服务器

由于mockito等工具不原生支持TLS,我们可以用hyper + rustls + rcgen组合搭建纯Rust的HTTPS测试服务器,完全复刻原mockito的回显逻辑,且无需依赖外部服务。

步骤1:添加依赖

在Cargo.toml中添加所需依赖:

[dependencies]
hyper = { version = "1.1", features = ["full"] }
rustls = "0.22"
rcgen = "0.11"
tokio = { version = "1.0", features = ["full"] }
reqwest = { version = "0.11", features = ["rustls-tls"] }
hyper-rustls = "0.24"
http = "1.0"

步骤2:生成自签名测试证书

用rcgen动态生成自签名证书,无需提前准备证书文件:

use rcgen::{Certificate, CertificateParams, DnType};
use rustls::ServerConfig;
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::io::Cursor;

fn generate_self_signed_cert() -> ServerConfig {
    // 配置证书参数,指定localhost为域名
    let mut params = CertificateParams::new(vec!["localhost".to_string()]);
    params.distinguished_name.push(DnType::CommonName, "localhost");
    
    let cert = Certificate::from_params(params).unwrap();
    let cert_pem = cert.serialize_pem().unwrap();
    let key_pem = cert.serialize_private_key_pem();

    // 解析证书和私钥为rustls可识别的格式
    let cert_chain = certs(&mut Cursor::new(cert_pem)).unwrap();
    let mut keys = pkcs8_private_keys(&mut Cursor::new(key_pem)).unwrap();
    
    let mut config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(cert_chain, keys.remove(0)).unwrap();
    
    // 启用HTTP/1.1 ALPN协议
    config.alpn_protocols = vec![b"http/1.1".to_vec()];
    config
}

步骤3:搭建HTTPS回显服务器

基于hyper实现和原mockito逻辑一致的回显功能:

use hyper::{Body, Request, Response, Server, StatusCode};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::net::SocketAddr;

async fn echo_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let path = req.uri().path();
    // 匹配/echo/前缀的路径,返回后续内容
    if let Some(echo_content) = path.strip_prefix("/echo/") {
        Ok(Response::new(Body::from(echo_content)))
    } else {
        Ok(Response::builder()
            .status(StatusCode::NOT_FOUND)
            .body(Body::from("Not Found"))
            .unwrap())
    }
}

async fn start_tls_server() -> (String, impl futures::Future<Output = ()>) {
    // 使用随机端口避免冲突
    let addr = SocketAddr::from(([127, 0, 0, 1], 0));
    let tls_config = generate_self_signed_cert();

    // 创建服务处理函数
    let make_svc = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(echo_handler))
    });

    // 启动TLS服务器
    let server = Server::builder(hyper_rustls::TlsAcceptor::new(tls_config, addr))
        .serve(make_svc);

    let server_addr = server.local_addr();
    let server_url = format!("https://{}", server_addr);

    // 返回服务器URL和运行未来对象
    (server_url, server)
}

步骤4:编写测试用例

启动HTTPS服务器,配置reqwest客户端信任自签名证书,完成测试:

#[tokio::test]
async fn test_https_echo() {
    let (server_url, server_future) = start_tls_server().await;

    // 在后台异步运行服务器
    tokio::spawn(async move {
        if let Err(e) = server_future.await {
            eprintln!("Server error: {}", e);
        }
    });

    // 配置reqwest客户端信任我们生成的自签名证书
    let tls_config = generate_self_signed_cert();
    let mut root_certs = rustls::RootCertStore::empty();
    for cert_der in tls_config.cert_chain.iter() {
        root_certs.add(&rustls::Certificate(cert_der.clone())).unwrap();
    }

    let client_tls_config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(root_certs)
        .with_no_client_auth();

    let client = reqwest::Client::builder()
        .use_preconfigured_tls(client_tls_config)
        .build().unwrap();

    // 发送请求并验证回显结果
    let resp = client.get(format!("{}/echo/foobar", server_url))
        .send().await.unwrap()
        .text().await.unwrap();

    assert_eq!(resp, "foobar");
}

方案优势

  • 纯Rust实现,无外部依赖,测试环境稳定
  • 动态生成证书,无需手动管理测试证书文件
  • 完全复刻原mockito的回显逻辑,无缝替换原有测试
  • 支持异步/同步场景(示例用异步,如需同步可调整reqwest为blocking客户端)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:22:37