hyper_sync/header/common/
proxy_authorization.rs

1use std::any::Any;
2use std::fmt;
3use std::str::{FromStr, from_utf8};
4use std::ops::{Deref, DerefMut};
5
6use header::{Header, Raw, Scheme};
7
8/// `Proxy-Authorization` header, defined in [RFC7235](https://tools.ietf.org/html/rfc7235#section-4.4)
9///
10/// The `Proxy-Authorization` header field allows a user agent to authenticate
11/// itself with an HTTP proxy -- usually, but not necessarily, after
12/// receiving a 407 (Proxy Authentication Required) response and the
13/// `Proxy-Authenticate` header. Its value consists of credentials containing
14/// the authentication information of the user agent for the realm of the
15/// resource being requested.
16///
17/// # ABNF
18///
19/// ```text
20/// Authorization = credentials
21/// ```
22///
23/// # Example values
24/// * `Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==`
25/// * `Bearer fpKL54jvWmEGVoRdCNjG`
26///
27/// # Examples
28///
29/// ```
30/// use hyper_sync::header::{Headers, ProxyAuthorization};
31///
32/// let mut headers = Headers::new();
33/// headers.set(ProxyAuthorization("let me in".to_owned()));
34/// ```
35/// ```
36/// use hyper_sync::header::{Headers, ProxyAuthorization, Basic};
37///
38/// let mut headers = Headers::new();
39/// headers.set(
40///    ProxyAuthorization(
41///        Basic {
42///            username: "Aladdin".to_owned(),
43///            password: Some("open sesame".to_owned())
44///        }
45///    )
46/// );
47/// ```
48///
49/// ```
50/// use hyper_sync::header::{Headers, ProxyAuthorization, Bearer};
51///
52/// let mut headers = Headers::new();
53/// headers.set(
54///    ProxyAuthorization(
55///        Bearer {
56///            token: "QWxhZGRpbjpvcGVuIHNlc2FtZQ".to_owned()
57///        }
58///    )
59/// );
60/// ```
61#[derive(Clone, PartialEq, Debug)]
62pub struct ProxyAuthorization<S: Scheme>(pub S);
63
64impl<S: Scheme> Deref for ProxyAuthorization<S> {
65    type Target = S;
66
67    fn deref(&self) -> &S {
68        &self.0
69    }
70}
71
72impl<S: Scheme> DerefMut for ProxyAuthorization<S> {
73    fn deref_mut(&mut self) -> &mut S {
74        &mut self.0
75    }
76}
77
78impl<S: Scheme + Any> Header for ProxyAuthorization<S> where <S as FromStr>::Err: 'static {
79    fn header_name() -> &'static str {
80        static NAME: &'static str = "Proxy-Authorization";
81        NAME
82    }
83
84    fn parse_header(raw: &Raw) -> ::Result<ProxyAuthorization<S>> {
85        if let Some(line) = raw.one() {
86            let header = try!(from_utf8(line));
87            if let Some(scheme) = <S as Scheme>::scheme() {
88                if header.starts_with(scheme) && header.len() > scheme.len() + 1 {
89                    match header[scheme.len() + 1..].parse::<S>().map(ProxyAuthorization) {
90                        Ok(h) => Ok(h),
91                        Err(_) => Err(::Error::Header)
92                    }
93                } else {
94                    Err(::Error::Header)
95                }
96            } else {
97                match header.parse::<S>().map(ProxyAuthorization) {
98                    Ok(h) => Ok(h),
99                    Err(_) => Err(::Error::Header)
100                }
101            }
102        } else {
103            Err(::Error::Header)
104        }
105    }
106
107    fn fmt_header(&self, f: &mut ::header::Formatter) -> fmt::Result {
108        f.fmt_line(self)
109    }
110}
111
112impl<S: Scheme> fmt::Display for ProxyAuthorization<S> {
113    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114        if let Some(scheme) = <S as Scheme>::scheme() {
115            try!(write!(f, "{} ", scheme))
116        };
117        self.0.fmt_scheme(f)
118    }
119}
120
121#[cfg(test)]
122mod tests {
123    use super::ProxyAuthorization;
124    use super::super::super::{Headers, Header, Basic, Bearer};
125
126    #[test]
127    fn test_raw_auth() {
128        let mut headers = Headers::new();
129        headers.set(ProxyAuthorization("foo bar baz".to_owned()));
130        assert_eq!(headers.to_string(), "Proxy-Authorization: foo bar baz\r\n".to_owned());
131    }
132
133    #[test]
134    fn test_raw_auth_parse() {
135        let header: ProxyAuthorization<String> = Header::parse_header(&b"foo bar baz".as_ref().into()).unwrap();
136        assert_eq!(header.0, "foo bar baz");
137    }
138
139    #[test]
140    fn test_basic_auth() {
141        let mut headers = Headers::new();
142        headers.set(ProxyAuthorization(
143            Basic { username: "Aladdin".to_owned(), password: Some("open sesame".to_owned()) }));
144        assert_eq!(
145            headers.to_string(),
146            "Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n".to_owned());
147    }
148
149    #[test]
150    fn test_basic_auth_no_password() {
151        let mut headers = Headers::new();
152        headers.set(ProxyAuthorization(Basic { username: "Aladdin".to_owned(), password: None }));
153        assert_eq!(headers.to_string(), "Proxy-Authorization: Basic QWxhZGRpbjo=\r\n".to_owned());
154    }
155
156    #[test]
157    fn test_basic_auth_parse() {
158        let auth: ProxyAuthorization<Basic> = Header::parse_header(
159            &b"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".as_ref().into()).unwrap();
160        assert_eq!(auth.0.username, "Aladdin");
161        assert_eq!(auth.0.password, Some("open sesame".to_owned()));
162    }
163
164    #[test]
165    fn test_basic_auth_parse_no_password() {
166        let auth: ProxyAuthorization<Basic> = Header::parse_header(
167            &b"Basic QWxhZGRpbjo=".as_ref().into()).unwrap();
168        assert_eq!(auth.0.username, "Aladdin");
169        assert_eq!(auth.0.password, Some("".to_owned()));
170    }
171
172    #[test]
173    fn test_bearer_auth() {
174        let mut headers = Headers::new();
175        headers.set(ProxyAuthorization(
176            Bearer { token: "fpKL54jvWmEGVoRdCNjG".to_owned() }));
177        assert_eq!(
178            headers.to_string(),
179            "Proxy-Authorization: Bearer fpKL54jvWmEGVoRdCNjG\r\n".to_owned());
180    }
181
182    #[test]
183    fn test_bearer_auth_parse() {
184        let auth: ProxyAuthorization<Bearer> = Header::parse_header(
185            &b"Bearer fpKL54jvWmEGVoRdCNjG".as_ref().into()).unwrap();
186        assert_eq!(auth.0.token, "fpKL54jvWmEGVoRdCNjG");
187    }
188}
189
190#[cfg(test)]
191#[cfg(feature = "nightly")]
192mod benches {
193    use super::ProxyAuthorization;
194    use ::header::{Basic, Bearer};
195
196    bench_header!(raw, ProxyAuthorization<String>, { vec![b"foo bar baz".to_vec()] });
197    bench_header!(basic, ProxyAuthorization<Basic>, { vec![b"Basic QWxhZGRpbjpuIHNlc2FtZQ==".to_vec()] });
198    bench_header!(bearer, ProxyAuthorization<Bearer>, { vec![b"Bearer fpKL54jvWmEGVoRdCNjG".to_vec()] });
199}