hyper_sync/header/common/
authorization.rs1use base64::{encode, decode};
2use std::any::Any;
3use std::fmt::{self, Display};
4use std::str::{FromStr, from_utf8};
5use std::ops::{Deref, DerefMut};
6
7use header::{Header, Raw};
8
9#[derive(Clone, PartialEq, Debug)]
62pub struct Authorization<S: Scheme>(pub S);
63
64impl<S: Scheme> Deref for Authorization<S> {
65 type Target = S;
66
67 fn deref(&self) -> &S {
68 &self.0
69 }
70}
71
72impl<S: Scheme> DerefMut for Authorization<S> {
73 fn deref_mut(&mut self) -> &mut S {
74 &mut self.0
75 }
76}
77
78impl<S: Scheme + Any> Header for Authorization<S> where <S as FromStr>::Err: 'static {
79 fn header_name() -> &'static str {
80 static NAME: &'static str = "Authorization";
81 NAME
82 }
83
84 fn parse_header(raw: &Raw) -> ::Result<Authorization<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(Authorization) {
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(Authorization) {
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 Authorization<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
121pub trait Scheme: FromStr + fmt::Debug + Clone + Send + Sync {
123 fn scheme() -> Option<&'static str>;
127 fn fmt_scheme(&self, &mut fmt::Formatter) -> fmt::Result;
129}
130
131impl Scheme for String {
132 fn scheme() -> Option<&'static str> {
133 None
134 }
135
136 fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
137 Display::fmt(self, f)
138 }
139}
140
141#[derive(Clone, PartialEq, Debug)]
143pub struct Basic {
144 pub username: String,
146 pub password: Option<String>
150}
151
152impl Scheme for Basic {
153 fn scheme() -> Option<&'static str> {
154 Some("Basic")
155 }
156
157 fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
158 let mut text = self.username.clone();
162 text.push(':');
163 if let Some(ref pass) = self.password {
164 text.push_str(&pass[..]);
165 }
166
167 f.write_str(&encode(&text))
168 }
169}
170
171impl FromStr for Basic {
173 type Err = ::Error;
174 fn from_str(s: &str) -> ::Result<Basic> {
175 match decode(s) {
176 Ok(decoded) => match String::from_utf8(decoded) {
177 Ok(text) => {
178 let parts = &mut text.split(':');
179 let user = match parts.next() {
180 Some(part) => part.to_owned(),
181 None => return Err(::Error::Header)
182 };
183 let password = match parts.next() {
184 Some(part) => Some(part.to_owned()),
185 None => None
186 };
187 Ok(Basic {
188 username: user,
189 password: password
190 })
191 },
192 Err(_) => {
193 debug!("Basic::from_str utf8 error");
194 Err(::Error::Header)
195 }
196 },
197 Err(_) => {
198 debug!("Basic::from_str base64 error");
199 Err(::Error::Header)
200 }
201 }
202 }
203}
204
205#[derive(Clone, PartialEq, Debug)]
206pub struct Bearer {
208 pub token: String
210}
211
212impl Scheme for Bearer {
213 fn scheme() -> Option<&'static str> {
214 Some("Bearer")
215 }
216
217 fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
218 write!(f, "{}", self.token)
219 }
220}
221
222impl FromStr for Bearer {
223 type Err = ::Error;
224 fn from_str(s: &str) -> ::Result<Bearer> {
225 Ok(Bearer { token: s.to_owned()})
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::{Authorization, Basic, Bearer};
232 use super::super::super::{Headers, Header};
233
234 #[test]
235 fn test_raw_auth() {
236 let mut headers = Headers::new();
237 headers.set(Authorization("foo bar baz".to_owned()));
238 assert_eq!(headers.to_string(), "Authorization: foo bar baz\r\n".to_owned());
239 }
240
241 #[test]
242 fn test_raw_auth_parse() {
243 let header: Authorization<String> = Header::parse_header(&b"foo bar baz".as_ref().into()).unwrap();
244 assert_eq!(header.0, "foo bar baz");
245 }
246
247 #[test]
248 fn test_basic_auth() {
249 let mut headers = Headers::new();
250 headers.set(Authorization(
251 Basic { username: "Aladdin".to_owned(), password: Some("open sesame".to_owned()) }));
252 assert_eq!(
253 headers.to_string(),
254 "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n".to_owned());
255 }
256
257 #[test]
258 fn test_basic_auth_no_password() {
259 let mut headers = Headers::new();
260 headers.set(Authorization(Basic { username: "Aladdin".to_owned(), password: None }));
261 assert_eq!(headers.to_string(), "Authorization: Basic QWxhZGRpbjo=\r\n".to_owned());
262 }
263
264 #[test]
265 fn test_basic_auth_parse() {
266 let auth: Authorization<Basic> = Header::parse_header(
267 &b"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".as_ref().into()).unwrap();
268 assert_eq!(auth.0.username, "Aladdin");
269 assert_eq!(auth.0.password, Some("open sesame".to_owned()));
270 }
271
272 #[test]
273 fn test_basic_auth_parse_no_password() {
274 let auth: Authorization<Basic> = Header::parse_header(
275 &b"Basic QWxhZGRpbjo=".as_ref().into()).unwrap();
276 assert_eq!(auth.0.username, "Aladdin");
277 assert_eq!(auth.0.password, Some("".to_owned()));
278 }
279
280 #[test]
281 fn test_bearer_auth() {
282 let mut headers = Headers::new();
283 headers.set(Authorization(
284 Bearer { token: "fpKL54jvWmEGVoRdCNjG".to_owned() }));
285 assert_eq!(
286 headers.to_string(),
287 "Authorization: Bearer fpKL54jvWmEGVoRdCNjG\r\n".to_owned());
288 }
289
290 #[test]
291 fn test_bearer_auth_parse() {
292 let auth: Authorization<Bearer> = Header::parse_header(
293 &b"Bearer fpKL54jvWmEGVoRdCNjG".as_ref().into()).unwrap();
294 assert_eq!(auth.0.token, "fpKL54jvWmEGVoRdCNjG");
295 }
296}
297
298bench_header!(raw, Authorization<String>, { vec![b"foo bar baz".to_vec()] });
299bench_header!(basic, Authorization<Basic>, { vec![b"Basic QWxhZGRpbjpuIHNlc2FtZQ==".to_vec()] });
300bench_header!(bearer, Authorization<Bearer>, { vec![b"Bearer fpKL54jvWmEGVoRdCNjG".to_vec()] });