Usage of http 2.0 with reqwest

I tried to use http 2.0 with reqwest:

But simple example, like this:

use reqwest::Client;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::builder()
        .connection_verbose(true)
        .http2_prior_knowledge()
        .build()?;
    let resp = client
        .get("https://httpbin.org/ip")
        .send()
        .await?
        .json::<HashMap<String, String>>()
        .await?;
    println!("{:#?}", resp);
    Ok(())
}

give me error:

Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("httpbin.org")), port: None, path: "/ip", query: None, fragment: None }, source: hyper::Error(Http2, Error { kind: GoAway(b"", FRAME_SIZE_ERROR, Library) }) }

while curl -v -v https://httpbin.org/ip works just fine, and it shows that it uses HTTP/2.0

I tried to reduce size of "frame", but by default minium size is used (16KB),
also I tried .http2_adaptive_window(true), but this is changes nothing.

So any hint how to use HTTP/2.0 with reqwest ?

http2_prior_knowledge means that you know the server will immediately handle/respond with http2. This is exceedingly rare, as most servers want to maintain compatibility with http1 clients. You generally need to ensure TLS APLN is available to handle the upgrade to http2.

At least as of 2022 it looks like you might need to be using the rustls backend of reqwest for that to work

3 Likes

With rustls,rustls-tls as features, plus ClientBuilder::use_rustls_tls it works.
But it is rather strange, why openssl not enough for http2.

I assume it's just that native TLS APIs don't consistently expose an API to configure APLN correctly for http2, but I'm not sure honestly!

The native-tls backend has supported ALPN since reqwest 0.11.4.

1 Like