Search code examples
httprusthttp2rust-axum

How to use HTTP/2 in axum only


I'm trying to use HTPP/2 in axum but I can't access it, neither with my browser nor with httpie. I've checked the documentation for axum and hyper, and since my English and programming skills are poor and I haven't found any information on the web, I'm hoping to get some help here

// src/main.rs
#[tokio::main]
async fn main() {
    let app = axum::Router::new().route("/", axum::routing::get(|| async {"Hello, World!"}));
    let addr = std::net::SocketAddr::from(([127,0,0,1], 8080));
    let _server = axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}
# Cargo.toml
[dependencies.axum]
version = "0.6"
default-features = false
features = ["http2", "tokio", "matched-path"]
C:\Users\user>http :8080

http: error: ConnectionError: HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000002843AB5D670>: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。')) while doing a GET request to URL: http://localhost:8080/

When both http1 and http2 are enabled, access is normal, but http1 is used by default, and when http2_only(true) is enabled, it does not work.


Solution

  • As hinted at by this discussion on GitHub, many clients will perform an initial request with HTTP 1 but use the Upgrade header to communicate their desire to upgrade to HTTP 2. Servers that don't support HTTP 2 will simply ignore the header and data interchange will proceed using HTTP 1, but servers that support HTTP 2 will reply with a 101 Switching Protocols response and then the client and server will proceed using HTTP 2.

    If you aren't including HTTP 1 support in the server then this upgrade mechanism cannot be used, and the client must make the initial request using HTTP 2. However, this is backwards-incompatible with HTTP 1 servers, so it's usually not done unless explicitly requested using some kind of setting or flag. You would need to check the documentation of the HTTP client you're using to see if it has a setting you can use to make the initial request using HTTP 2.