4

I would like to get the Authorization Bearer header for OAuth purposes, but it looks a bit confusing reading the docs

use nickel::{Nickel, JsonBody, HttpRouter, Request, Response, MiddlewareResult, MediaType};

    // Get the full Authorization header from the incoming request headers
    let auth_header = match request.origin.headers.get::<Authorization<Bearer>>() {
        Some(header) => header,
        None => panic!("No authorization header found")
    };

This generates the error:

src/main.rs:84:56: 84:86 error: the trait hyper::header::HeaderFormat is not implemented for the type hyper::header::common::authorization::Authorization<hyper::header::common::authorization::Bearer> [E0277]

Looking at implementation it appears for me to be correct:

https://github.com/hyperium/hyper/blob/master/src/header/common/authorization.rs

impl<S: Scheme + Any> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static {
    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Some(scheme) = <S as Scheme>::scheme() {
            try!(write!(f, "{} ", scheme))
        };
        self.0.fmt_scheme(f)
    }
}

https://github.com/auth0/rust-api-example/issues/1

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Marcos
  • 43
  • 3

1 Answers1

2

Looking at the documentation for Authorization, we can see that it does indeed implement Header:

impl<S: Scheme + Any> Header for Authorization<S>
    where S::Err: 'static

So you were on the right track. My guess is that you are running into something more insidious: multiple versions of the same crate.

Specifically, the version of nickel that I compiled today (0.7.3), depends on hyper 0.6.16. However, if I add hyper = "*" to my Cargo.toml, then I also get the newest version of hyper - 0.7.0.

As unintuitive as it may seem, items from hyper 0.7 are not compatible with items from hyper 0.6. This is nothing specific about hyper either; it's true for all crates.

If you update your dependency to lock to the same version of hyper that nickel wants, then you should be good to go.


Cargo.toml

# ...

[dependencies]
hyper = "0.6.16"
nickel = "*"

src/main.rs

extern crate nickel;
extern crate hyper;

use hyper::header::{Authorization, Bearer};
use nickel::{HttpRouter, Request};

fn foo(request: Request) {
    // Get the full Authorization header from the incoming request headers
    let auth_header = match request.origin.headers.get::<Authorization<Bearer>>() {
        Some(header) => header,
        None => panic!("No authorization header found")
    };
}

fn main() {}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • It looks like it is related with https://github.com/rust-lang/cargo/issues/1636, also wildcard is [deprecated](http://doc.crates.io/faq.html#can-libraries-use-*-as-a-version-for-their-dependencies?) and yet another [dependency-hell problem](https://en.wikipedia.org/wiki/Dependency_hell) – Marcos Dec 16 '15 at 19:20
  • @Marcos wildcard dependencies are deprecated *for published libraries*. Binaries may use them as they have a corresponding `Cargo.lock` file. Amusingly, this is the inverse of the traditional dependency hell issue. There, you cannot have conflicting versions of the same crate. Here, you can, but they conflict if you try to use them interchangeably. – Shepmaster Dec 16 '15 at 19:23