http-rs / surf

Fast and friendly HTTP client framework for async Rust
https://docs.rs/surf
Apache License 2.0
1.45k stars 119 forks source link

method HEAD error #218

Open clouds56 opened 4 years ago

clouds56 commented 4 years ago

I tried to use http HEAD method and it would hand

  async_std::task::block_on(async move {
    let res = surf::head("http://example.com").await.expect("surf");
    println!("{:?}", res);
  });

And if i replace http with https, it would give me exception

thread 'test_header' panicked at 'surf: ResponseBodyError(None): unknown error', http/src/lib.rs:84:19

If I replace head with get, all things goes well.

[dependencies]
surf = "2.0.0-alpha.4"
async-std = "1.6.3"
Fishrock123 commented 4 years ago

Could you try with this in your Cargo.toml?

[dependencies]
surf = { version = "2.0.0-alpha.4", features = ["h1-client"] }
clouds56 commented 4 years ago

Yes, I've tried

surf = { version = "2.0.0-alpha.4", features = [ "h1-client" , "middleware-logger", "encoding"], default-features = false }

but with no luck

Fishrock123 commented 4 years ago

@yoshuawuyts

snaumov commented 3 years ago

getting the same error with

surf = "2.1.0"
async-std = { version = "1.6.3" }

client.head("http://192.168.2.12:8080/file.car").recv_string().await?

Fishrock123 commented 3 years ago

For what it's worth, this is a programmer error:

client.head("http://a.b").recv_string().await?;

It is a bug that this panics but will definitely continue to fail. HEAD cannot have a body, and so this will not work. Use this instead, once this is fixed:

client.head("http://a.b").await?;
austinabell commented 3 years ago

For what it's worth, this is a programmer error:

client.head("http://a.b").recv_string().await?;

The docs should be updated when this is fixed as well, as we chatted about in discord, since the docs still show this as the usage: https://github.com/http-rs/surf/blob/55c5d6ace6269f6c47dc32d5ba5069aa8f6aa7d7/src/client.rs#L346

Fishrock123 commented 3 years ago

Upon further investigation it seems like this is only an issue with the default curl-based client.

Try this:

surf = { version = "2.1", default-features = false, features = ["h1-client", "encoding"] }

Note that the async-h1 client is presently still missing a lot of client functionality, listed here: https://github.com/http-rs/surf/pull/223#issuecomment-690606442

The list I gathered:

Other things that may be less-than-complete:

  • redirects (by default?)
  • encodings (?)
  • TLS support (?)

You could also use "hyper-client" although that means opting in to all of hyper, and also using some tokio code.

Fishrock123 commented 3 years ago

That being said, I can't reproduce the panic. For me this test just hangs forever. This machine is running Ubuntu 20 if that matters.

Can anyone get a bracktrace? cargo +nightly build and then run with RUST_BACKTRACE=1 in your ENV/.env.

Fishrock123 commented 3 years ago

Ironically, CI running Ubuntu 20 does fail.

Error: ResponseBodyError(None): unknown error
thread 'head_example_org' panicked at 'assertion failed: `(left == right)`
aswild commented 3 years ago

So... what is the correct way to do a basic HEAD request with surf? All of these return the same Err(ResponseBodyError(None)), both with surf version 2.1.0 and the tip of main (e30aa7cf).

#[async_std::main]
async fn main() -> surf::Result<()> {
    let client = surf::client();
    let req = client.head("https://example.com");
    let resp = req.await;
    dbg!(&resp);

    let resp = surf::head("https://example.com").await;
    dbg!(&resp);

    let resp = surf::head("https://example.com").send().await;
    dbg!(&resp);

    Ok(())
}

What does work:

The error type ResponseBodyError seems to hint that surf is failing due to a missing response body, but HEAD isn't supposed to return a body.

Fishrock123 commented 3 years ago

Use the h1-client.