shuttle-hq / shuttle

Build & ship backends without writing any infrastructure files.
https://shuttle.rs
Apache License 2.0
6.1k stars 252 forks source link

Make a request to a shuttle endpoint with reqwest #448

Closed bcpeinhardt closed 2 years ago

bcpeinhardt commented 2 years ago

Hello! Whenever I try to make a request to any shuttle endpoint using reqwest, I get the following error:

 panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("hello_world.shuttleapp.rs")), port: None, path: "/hello", query: None, fragment: None }, source: hyper::Error(Connect, Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "ssl/statem/statem_clnt.c", line: 1887 }]))) }, X509VerifyResult { code: 62, error: "hostname mismatch" })) }', src/bindings.rs:29:41

Can you help me understand why reqwest is failing to verify the ssl certificate?

brokad commented 2 years ago

Hey there!

I'm not sure. Our TLS termination is handled by AWS load balancers (so is signed by Amazon Root CA). Any chance you're trying this from an environment that is missing some root CAs?

Could you run

$ curl https://hello_world.shuttleapp.rs/hello

from the same environment (i.e. if running in Docker, do it in the same container, etc)?

bcpeinhardt commented 2 years ago

The curl command works like a charm. I will create a simple example repo duplicating the issue and link it, maybe then we can figure out what I'm doing wrong xD Should take <5 minutes

bcpeinhardt commented 2 years ago

https://github.com/bcpeinhardt/replicate_reqwest_shuttle_issue

Created. The gist is this:

// Works
    let resp = reqwest::get("https://httpbin.org/ip")
        .await?
        .json::<HashMap<String, String>>()
        .await?;
    println!("{:#?}", resp);

    // Fails
    let resp = reqwest::get("https://hello_world.shuttleapp.rs/hello")
        .await?
        .json::<String>()
        .await?;
    println!("{:#?}", resp);

with error

Error: reqwest::Error { kind: Request, url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("hello_world.shuttleapp.rs")), port: None, path: "/hello", query: None, fragment: None }, source: hyper::Error(Connect, Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "ssl/statem/statem_clnt.c", line: 1887 }]))) }, X509VerifyResult { code: 62, error: "hostname mismatch" })) }
oddgrd commented 2 years ago

Hey Benjamin! I can reproduce your issue, and it seems to be caused by having an underscore in the hostname: https://github.com/hyperium/hyper/issues/2257#issuecomment-666922210 & https://github.com/openssl/openssl/issues/12566. For now you can work around this by using the rustls backend for reqwest:

reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] }

Thanks for reporting this! It seems like we might want to restrict underscores from project names.

bcpeinhardt commented 2 years ago

That is SO much simpler than I thought this would end up being haha, thank you so much for the prompt response!! Very excited for the growth of shuttle c:

nanaknihal commented 1 month ago

In case anyone else is stuck with this same issue and is wants another solution, installing curl fixed it for me. It failed in a bookworm-slim docker container until running apt install -y curl. I am not sure yet why this worked. Perhaps it installed some binaries or root CAs.