Reqwest: Defining Custom Headers

Created on 8 Jul 2018  Â·  18Comments  Â·  Source: seanmonstar/reqwest

hyper::header::Headers has been removed in recent versions and the method described here of implementing custom headers no longer works. I tried using hyperx, a crate which extracts the same functionality from hyper, but it doesn't implement the trait used in reqwest. Optimally I think reqwest should implement it's own custom header functionality and not rely on Hyper for this.

Most helpful comment

Now this documentation has been removed in the latest version; so for the people looking for this: Diving deep into the source code reveals that you can just use strings, e.g.:

client.get(&url).header("X-API-KEY", "123");

I wonder why this is not on the very first page of the documentation; people might think that reqwest is unusable for dealing with APIs where you have to add your API key via a custom header.

All 18 comments

It is still possible to implement Header trait for your own structure (it takes ~20 loc for simple ones). Though there's still an explicit dependency on hyper::error::Error

This is indeed missing. An example would help a lot.

Running into the same problem.

Optimally I think reqwest should implement it's own custom header functionality and not rely on Hyper for this.

@sajattack refing #11 here where this functionality is discussed.

@pmuens that's right, but there is not any full solution provided here yet...

Is there a way to implement a custom header in reqwest that someone could provide, or to implement the required trait?
If not in reqwest, is there another library I can use to make a POST request from rust with custom headers? Is rewriting this functionality with hyper feasible?

I'm trying to write a proxy for authentication, for which I need to forward an incoming request while adding a custom header to it. Incoming request is handled with Rocket.

header!{(Version, "Version") => [String]}

#[derive(Serialize, Deserialize)]
struct UserPost {
    username: String,
    password: String,
}
#[post("/auth", data = "<data>")]
fn authenticate(data: Json<UserPost>) -> Json<String> {
    let mut version_header = hyper::header::Headers::new();
    version_header.set(Version("2".to_owned()));

    match reqwest::Client::new()
        .post("<url>")
        .form(&data.into_inner())
        .header(reqwest::header::ContentType::json())
        .header(version_header)
        .send()
    {
        Ok(res) => Json(format!("{:?}", res)),
        Err(e) => Json(format!("{:?}", e)),
    }
}

and of course I get:

error[E0277]: the trait bound `hyper::header::Headers: reqwest::header::Header` is not satisfied
  --> src\main.rs:95:4
   |
95 |         .header(version_header)
   |          ^^^^^^ the trait `reqwest::header::Header` is not implemented for `hyper::header::Headers`

The header function takes a single header, you're passing a map of Headers. Just call .header(Version("2".to_owned())) instead.

That gives me:

error[E0277]: the trait bound `Version: reqwest::header::Header` is not satisfied
  --> src\main.rs:90:4
   |
90 |         .header(Version("2".to_owned()))
   |          ^^^^^^ the trait `reqwest::header::Header` is not implemented for `Version`

EDIT: Am I now on the correct issue? :p

Nevermind, I guess I must be on a version too old to work for a different reason, but not new enough to not be working for this reason. Switching to the newest version of hyper gives me:

error: cannot find macro `header!` in this scope
  --> src\main.rs:31:1
   |
31 | header!{(Version, "Version") => [String]}
   | ^^^^^^

which I assume this issue is about. Sorry for cluttering the issue, I'll figure it out from here...

So - where do we stand on this? Am I to understand that if I want to include a custom header in my request, I need to write "~20 loc"? Is there an example of that somewhere?

It seems like a very, very silly thing to have to do for so common a use-case as passing a custom header in a request, which is just a string in the http request. Like, I'm all for type safety where headers are properly defined, but I can't think of any reason why there isn't a raw_header("foo","bar") somewhere.

edit: I guess downgrading to hyper = "^0.11" allows me to use the header! macro as documented, but it would definitely be better to be compatible with the newest.

There could definitely be a raw_header added to RequestBuilder.

Yeah, sorry - that comment sounds a lot crankier than I intended now that I re-read it. :sweat_smile:

If adding raw_header to RequestBuilder sounds like an OK design decision to you @seanmonstar , I'll put together a PR for it.

+1 on getting an example of how to do this. I'm trying to do a simple GET with custom headers and struggling to work out how.

error[E0599]: no method named `header` found for type `reqwest::Client` in the current scope

@tkondrashov @joedborg consider implementing Header trait instead. It requires hyper::error::Error being exported.
Here's an example of usage and its implementation. Though the approach isn't that elegant as it can be and I agree that reqwest::Client api should be extended

As of the new v0.9 release, the RequestBuilder now has simple methods to add headers via strings.

@l4l @seanmonstar The Header trait seems to have gone away in 0.9.x – is there a standard way of defining a custom header now, outside of RequestBuilder? I'd like to check a response for a custom header containing an i32 value using get(), as per #397, but I can't find any examples…

Sorry for a long reply, @urschrei. There's a method Response::headers, if you're still interested.

For anyone else stumbling upon this, a bit of documentation is hidden deep inside - as part of the page of the RequestBuilder: https://docs.rs/reqwest/0.9.11/reqwest/struct.RequestBuilder.html

Now this documentation has been removed in the latest version; so for the people looking for this: Diving deep into the source code reveals that you can just use strings, e.g.:

client.get(&url).header("X-API-KEY", "123");

I wonder why this is not on the very first page of the documentation; people might think that reqwest is unusable for dealing with APIs where you have to add your API key via a custom header.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CGQAQ picture CGQAQ  Â·  4Comments

apiraino picture apiraino  Â·  3Comments

samuela picture samuela  Â·  5Comments

encombhat picture encombhat  Â·  6Comments

dbrgn picture dbrgn  Â·  5Comments