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

如何在axum中仅启用HTTP/2?启用后无法访问求助

Axum启用HTTP/2后无法访问的解决方案

问题原因

HTTP/2协议默认要求通过TLS(HTTPS)传输,明文HTTP/2(h2c)并非主流客户端默认支持的方式。你的配置存在以下问题:

  • 仅启用http2特性但未配置TLS时,Axum服务器仅支持h2c连接,但浏览器、httpie等客户端默认不会发起h2c请求,服务器会拒绝HTTP/1的连接请求,导致报错WinError 10061
  • 同时启用http1和http2特性时,服务器兼容两种协议,因此能通过HTTP/1正常访问,但客户端不会自动切换到HTTP/2(除非通过TLS连接)
  • 启用http2_only(true)后,服务器仅接受h2c连接,普通客户端无法适配,因此完全无法访问

解决方案

方案1:配置TLS证书(生产环境推荐)

通过HTTPS提供HTTP/2服务,这是浏览器和标准客户端支持的方式:

  1. 生成自签名证书
    用openssl生成本地测试用的证书:
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj "/CN=localhost"
  1. 更新Cargo.toml
    添加TLS支持的特性:
[dependencies.axum]
version = "0.6"
default-features = false
features = ["http2", "tokio", "matched-path", "tls-rustls"]
  1. 修改服务代码
    加载证书并启动TLS服务器:
// src/main.rs
use axum::{Router, routing::get};
use std::net::SocketAddr;
use tokio_rustls::rustls::{Certificate, PrivateKey, ServerConfig};
use tokio_rustls::TlsAcceptor;
use std::fs::File;
use std::io::BufReader;

#[tokio::main]
async fn main() {
    // 读取证书文件
    let cert = {
        let file = File::open("cert.pem").unwrap();
        let buf = BufReader::new(file);
        Certificate(std::io::read_to_end(buf).unwrap())
    };

    // 读取私钥文件
    let key = {
        let file = File::open("key.pem").unwrap();
        let buf = BufReader::new(file);
        PrivateKey(std::io::read_to_end(buf).unwrap())
    };

    // 配置TLS
    let tls_config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_single_cert(vec![cert], key)
        .unwrap();

    let tls_acceptor = TlsAcceptor::from(tls_config);

    // 构建路由
    let app = Router::new().route("/", get(|| async { "Hello, World!" }));
    let addr = SocketAddr::from(([127, 0, 0, 1], 8443));

    // 启动TLS服务器
    axum::Server::bind(&addr)
        .tls(tls_acceptor)
        .serve(app.into_make_service())
        .await
        .unwrap();
}
  1. 测试访问
    用httpie访问(忽略自签名证书的安全提示):
http --verify=no https://localhost:8443

方案2:用h2c兼容客户端调试(开发用)

如果不想配置TLS,可使用支持明文HTTP/2的客户端,比如curl:

curl --http2-prior-knowledge http://localhost:8080

--http2-prior-knowledge参数会强制curl使用h2c协议连接服务器。

关于http2_only(true)的说明

启用该配置后,服务器仅接受h2c连接,而浏览器、httpie等客户端默认不会发起h2c请求,因此会出现连接被拒绝的情况,这是正常行为。仅当你明确使用支持h2c的客户端时,该配置才有效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:43:11