1 //! Headers container, and common header fields.
2 //!
3 //! hyper has the opinion that Headers should be strongly-typed, because that's
4 //! why we're using Rust in the first place. To set or get any header, an object
5 //! must implement the `Header` trait from this module. Several common headers
6 //! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
7 //!
8 //! # Why Typed?
9 //!
10 //! Or, why not stringly-typed? Types give the following advantages:
11 //!
12 //! - More difficult to typo, since typos in types should be caught by the compiler
13 //! - Parsing to a proper type by default
14 //!
15 //! # Defining Custom Headers
16 //!
17 //! Hyper provides many of the most commonly used headers in HTTP. If
18 //! you need to define a custom header, it's easy to do while still taking
19 //! advantage of the type system. Hyper includes a `header!` macro for defining
20 //! many wrapper-style headers.
21 //!
22 //! ```
23 //! #[macro_use] extern crate hyper;
24 //! use hyper::header::Headers;
25 //! header! { (XRequestGuid, "X-Request-Guid") => [String] }
26 //!
27 //! fn main () {
28 //!     let mut headers = Headers::new();
29 //!
30 //!     headers.set(XRequestGuid("a proper guid".to_owned()))
31 //! }
32 //! ```
33 //!
34 //! This works well for simple "string" headers.  If you need more control,
35 //! you can implement the trait directly.
36 //!
37 //! ## Implementing the `Header` trait
38 //!
39 //! Consider a Do Not Track header. It can be true or false, but it represents
40 //! that via the numerals `1` and `0`.
41 //!
42 //! ```
43 //! use std::fmt;
44 //! use hyper::header::{self, Header, Raw};
45 //!
46 //! #[derive(Debug, Clone, Copy)]
47 //! struct Dnt(bool);
48 //!
49 //! impl Header for Dnt {
50 //!     fn header_name() -> &'static str {
51 //!         "DNT"
52 //!     }
53 //!
54 //!     fn parse_header(raw: &Raw) -> hyper::Result<Dnt> {
55 //!         if raw.len() == 1 {
56 //!             let line = &raw[0];
57 //!             if line.len() == 1 {
58 //!                 let byte = line[0];
59 //!                 match byte {
60 //!                     b'0' => return Ok(Dnt(true)),
61 //!                     b'1' => return Ok(Dnt(false)),
62 //!                     _ => ()
63 //!                 }
64 //!             }
65 //!         }
66 //!         Err(hyper::Error::Header)
67 //!     }
68 //!
69 //!     fn fmt_header(&self, f: &mut header::Formatter) -> fmt::Result {
70 //!         let value = if self.0 {
71 //!             "1"
72 //!         } else {
73 //!             "0"
74 //!         };
75 //!         f.fmt_line(&value)
76 //!     }
77 //! }
78 //! ```
79 use std::borrow::{Cow, ToOwned};
80 #[cfg(feature = "compat")]
81 use std::convert::From;
82 use std::iter::{FromIterator, IntoIterator};
83 use std::{mem, fmt};
84 
85 #[cfg(feature = "compat")]
86 use http;
87 
88 use unicase::Ascii;
89 
90 use self::internals::{Item, VecMap, Entry};
91 use self::sealed::HeaderClone;
92 
93 pub use self::shared::*;
94 pub use self::common::*;
95 pub use self::raw::Raw;
96 use bytes::Bytes;
97 
98 mod common;
99 mod internals;
100 mod raw;
101 mod shared;
102 pub mod parsing;
103 
104 
105 /// A trait for any object that will represent a header field and value.
106 ///
107 /// This trait represents the construction and identification of headers,
108 /// and contains trait-object unsafe methods.
109 pub trait Header: 'static + HeaderClone + Send + Sync {
110     /// Returns the name of the header field this belongs to.
111     ///
112     /// This will become an associated constant once available.
header_name() -> &'static str where Self: Sized113     fn header_name() -> &'static str where Self: Sized;
114     /// Parse a header from a raw stream of bytes.
115     ///
116     /// It's possible that a request can include a header field more than once,
117     /// and in that case, the slice will have a length greater than 1. However,
118     /// it's not necessarily the case that a Header is *allowed* to have more
119     /// than one field value. If that's the case, you **should** return `None`
120     /// if `raw.len() > 1`.
parse_header(raw: &Raw) -> ::Result<Self> where Self: Sized121     fn parse_header(raw: &Raw) -> ::Result<Self> where Self: Sized;
122     /// Format a header to outgoing stream.
123     ///
124     /// Most headers should be formatted on one line, and so a common pattern
125     /// would be to implement `std::fmt::Display` for this type as well, and
126     /// then just call `f.fmt_line(self)`.
127     ///
128     /// ## Note
129     ///
130     /// This has the ability to format a header over multiple lines.
131     ///
132     /// The main example here is `Set-Cookie`, which requires that every
133     /// cookie being set be specified in a separate line. Almost every other
134     /// case should only format as 1 single line.
135     #[inline]
fmt_header(&self, f: &mut Formatter) -> fmt::Result136     fn fmt_header(&self, f: &mut Formatter) -> fmt::Result;
137 }
138 
139 mod sealed {
140     use super::Header;
141 
142     #[doc(hidden)]
143     pub trait HeaderClone {
clone_box(&self) -> Box<Header + Send + Sync>144         fn clone_box(&self) -> Box<Header + Send + Sync>;
145     }
146 
147     impl<T: Header + Clone> HeaderClone for T {
148         #[inline]
clone_box(&self) -> Box<Header + Send + Sync>149         fn clone_box(&self) -> Box<Header + Send + Sync> {
150             Box::new(self.clone())
151         }
152     }
153 }
154 
155 
156 /// A formatter used to serialize headers to an output stream.
157 #[allow(missing_debug_implementations)]
158 pub struct Formatter<'a, 'b: 'a>(Multi<'a, 'b>);
159 
160 enum Multi<'a, 'b: 'a> {
161     Line(&'a str, &'a mut fmt::Formatter<'b>),
162     Join(bool, &'a mut fmt::Formatter<'b>),
163     Raw(&'a mut Raw),
164 }
165 
166 impl<'a, 'b> Formatter<'a, 'b> {
167 
168     /// Format one 'line' of a header.
169     ///
170     /// This writes the header name plus the `Display` value as a single line.
171     ///
172     /// ## Note
173     ///
174     /// This has the ability to format a header over multiple lines.
175     ///
176     /// The main example here is `Set-Cookie`, which requires that every
177     /// cookie being set be specified in a separate line. Almost every other
178     /// case should only format as 1 single line.
fmt_line(&mut self, line: &fmt::Display) -> fmt::Result179     pub fn fmt_line(&mut self, line: &fmt::Display) -> fmt::Result {
180         use std::fmt::Write;
181         match self.0 {
182             Multi::Line(name, ref mut f) => {
183                 try!(f.write_str(name));
184                 try!(f.write_str(": "));
185                 try!(write!(NewlineReplacer(*f), "{}", line));
186                 f.write_str("\r\n")
187             },
188             Multi::Join(ref mut first, ref mut f) => {
189                 if !*first {
190                     try!(f.write_str(", "));
191                 } else {
192                     *first = false;
193                 }
194                 write!(NewlineReplacer(*f), "{}", line)
195             }
196             Multi::Raw(ref mut raw) => {
197                 let mut s = String::new();
198                 try!(write!(NewlineReplacer(&mut s), "{}", line));
199                 raw.push(s);
200                 Ok(())
201             }
202         }
203     }
204 
danger_fmt_line_without_newline_replacer<T: fmt::Display>(&mut self, line: &T) -> fmt::Result205     fn danger_fmt_line_without_newline_replacer<T: fmt::Display>(&mut self, line: &T) -> fmt::Result {
206         use std::fmt::Write;
207         match self.0 {
208             Multi::Line(name, ref mut f) => {
209                 try!(f.write_str(name));
210                 try!(f.write_str(": "));
211                 try!(fmt::Display::fmt(line, f));
212                 f.write_str("\r\n")
213             },
214             Multi::Join(ref mut first, ref mut f) => {
215                 if !*first {
216                     try!(f.write_str(", "));
217                 } else {
218                     *first = false;
219                 }
220                 fmt::Display::fmt(line, f)
221             }
222             Multi::Raw(ref mut raw) => {
223                 let mut s = String::new();
224                 try!(write!(s, "{}", line));
225                 raw.push(s);
226                 Ok(())
227             }
228         }
229     }
230 }
231 
232 struct ValueString<'a>(&'a Item);
233 
234 impl<'a> fmt::Debug for ValueString<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result235     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236         try!(f.write_str("\""));
237         try!(self.0.write_h1(&mut Formatter(Multi::Join(true, f))));
238         f.write_str("\"")
239     }
240 }
241 
242 impl<'a> fmt::Display for ValueString<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result243     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
244         self.0.write_h1(&mut Formatter(Multi::Join(true, f)))
245     }
246 }
247 
248 struct NewlineReplacer<'a, F: fmt::Write + 'a>(&'a mut F);
249 
250 impl<'a, F: fmt::Write + 'a> fmt::Write for NewlineReplacer<'a, F> {
251     #[inline]
write_str(&mut self, s: &str) -> fmt::Result252     fn write_str(&mut self, s: &str) -> fmt::Result {
253         let mut since = 0;
254         for (i, &byte) in s.as_bytes().iter().enumerate() {
255             if byte == b'\r' || byte == b'\n' {
256                 try!(self.0.write_str(&s[since..i]));
257                 try!(self.0.write_str(" "));
258                 since = i + 1;
259             }
260         }
261         if since < s.len() {
262             self.0.write_str(&s[since..])
263         } else {
264             Ok(())
265         }
266     }
267 
268     #[inline]
write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result269     fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
270         fmt::write(self, args)
271     }
272 }
273 
274 
275 impl Header + Send + Sync {
276     // A trait object looks like this:
277     //
278     // TraitObject { data: *mut (), vtable: *mut () }
279     //
280     // So, we transmute &Trait into a (*mut (), *mut ()). This depends on the
281     // order the compiler has chosen to represent a TraitObject.
282     //
283     // It has been assured that this order will be stable.
284     #[inline]
downcast_ref_unchecked<T: 'static>(&self) -> &T285     unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
286         &*(mem::transmute::<*const _, (*const (), *const ())>(self).0 as *const T)
287     }
288 
289     #[inline]
downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T290     unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
291         &mut *(mem::transmute::<*mut _, (*mut (), *mut ())>(self).0 as *mut T)
292     }
293 
294     #[inline]
downcast_unchecked<T: 'static>(self: Box<Self>) -> T295     unsafe fn downcast_unchecked<T: 'static>(self: Box<Self>) -> T {
296         *Box::from_raw(mem::transmute::<*mut _, (*mut (), *mut ())>(Box::into_raw(self)).0 as *mut T)
297     }
298 }
299 
300 impl Clone for Box<Header + Send + Sync> {
301     #[inline]
clone(&self) -> Box<Header + Send + Sync>302     fn clone(&self) -> Box<Header + Send + Sync> {
303         self.clone_box()
304     }
305 }
306 
307 #[inline]
header_name<T: Header>() -> &'static str308 fn header_name<T: Header>() -> &'static str {
309     <T as Header>::header_name()
310 }
311 
312 /// A map of header fields on requests and responses.
313 #[derive(Clone)]
314 pub struct Headers {
315     data: VecMap<HeaderName, Item>,
316 }
317 
318 impl Default for Headers {
default() -> Headers319     fn default() -> Headers {
320         Headers::new()
321     }
322 }
323 
324 macro_rules! literals {
325     ($($len:expr => $($header:path),+;)+) => (
326         fn maybe_literal(s: &str) -> Cow<'static, str> {
327             match s.len() {
328                 $($len => {
329                     $(
330                     if Ascii::new(<$header>::header_name()) == Ascii::new(s) {
331                         return Cow::Borrowed(<$header>::header_name());
332                     }
333                     )+
334                 })+
335 
336                 _ => ()
337             }
338 
339             trace!("maybe_literal not found, copying {:?}", s);
340             Cow::Owned(s.to_owned())
341         }
342 
343         #[test]
344         fn test_literal_lens() {
345             $(
346             $({
347                 let s = <$header>::header_name();
348                 assert!(s.len() == $len, "{:?} has len of {}, listed as {}", s, s.len(), $len);
349             })+
350             )+
351         }
352     );
353 }
354 
355 literals! {
356     4  => Host, Date, ETag;
357     5  => Allow, Range;
358     6  => Accept, Cookie, Server, Expect;
359     7  => Upgrade, Referer, Expires;
360     8  => Location, IfMatch, IfRange;
361     10 => UserAgent, Connection, SetCookie;
362     12 => ContentType;
363     13 => Authorization<String>, CacheControl, LastModified, IfNoneMatch, AcceptRanges, ContentRange;
364     14 => ContentLength, AcceptCharset;
365     15 => AcceptEncoding, AcceptLanguage;
366     17 => TransferEncoding;
367     25 => StrictTransportSecurity;
368     27 => AccessControlAllowOrigin;
369 }
370 
371 impl Headers {
372 
373     /// Creates a new, empty headers map.
374     #[inline]
new() -> Headers375     pub fn new() -> Headers {
376         Headers::with_capacity(0)
377     }
378 
379     /// Creates a new `Headers` struct with space reserved for `len` headers.
380     #[inline]
with_capacity(len: usize) -> Headers381     pub fn with_capacity(len: usize) -> Headers {
382         Headers {
383             data: VecMap::with_capacity(len)
384         }
385     }
386 
387     /// Set a header field to the corresponding value.
388     ///
389     /// The field is determined by the type of the value being set.
set<H: Header>(&mut self, value: H)390     pub fn set<H: Header>(&mut self, value: H) {
391         self.data.insert(HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))),
392                          Item::new_typed(value));
393     }
394 
set_pos<H: Header>(&mut self, pos: usize, value: H)395     pub(crate) fn set_pos<H: Header>(&mut self, pos: usize, value: H) {
396         self.data.insert_pos(
397             HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))),
398             Item::new_typed(value),
399             pos,
400         );
401     }
402 
403     /// Get a reference to the header field's value, if it exists.
get<H: Header>(&self) -> Option<&H>404     pub fn get<H: Header>(&self) -> Option<&H> {
405         self.data.get(&HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))))
406         .and_then(Item::typed::<H>)
407     }
408 
409     /// Get a mutable reference to the header field's value, if it exists.
get_mut<H: Header>(&mut self) -> Option<&mut H>410     pub fn get_mut<H: Header>(&mut self) -> Option<&mut H> {
411         self.data.get_mut(&HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))))
412         .and_then(Item::typed_mut::<H>)
413     }
414 
415     /// Returns a boolean of whether a certain header is in the map.
416     ///
417     /// Example:
418     ///
419     /// ```
420     /// # use hyper::header::Headers;
421     /// # use hyper::header::ContentType;
422     /// # let mut headers = Headers::new();
423     /// headers.set(ContentType::json());
424     /// assert!(headers.has::<ContentType>());
425     /// ```
has<H: Header>(&self) -> bool426     pub fn has<H: Header>(&self) -> bool {
427         self.data.contains_key(&HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))))
428     }
429 
430     /// Removes a header from the map, if one existed.
431     /// Returns the header, if one has been removed and could be parsed.
432     ///
433     /// Note that this function may return `None` even though a header was removed. If you want to
434     /// know whether a header exists, rather rely on `has`.
remove<H: Header>(&mut self) -> Option<H>435     pub fn remove<H: Header>(&mut self) -> Option<H> {
436         self.data.remove(&HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))))
437             .and_then(Item::into_typed::<H>)
438     }
439 
440     /// Returns an iterator over the header fields.
iter(&self) -> HeadersItems441     pub fn iter(&self) -> HeadersItems {
442         HeadersItems {
443             inner: self.data.iter()
444         }
445     }
446 
447     /// Returns the number of headers in the map.
len(&self) -> usize448     pub fn len(&self) -> usize {
449         self.data.len()
450     }
451 
452     /// Remove all headers from the map.
clear(&mut self)453     pub fn clear(&mut self) {
454         self.data.clear()
455     }
456 
457     /// Access the raw value of a header.
458     ///
459     /// Prefer to use the typed getters instead.
460     ///
461     /// Example:
462     ///
463     /// ```
464     /// # use hyper::header::Headers;
465     /// # let mut headers = Headers::new();
466     /// # headers.set_raw("content-type", "text/plain");
467     /// let raw = headers.get_raw("content-type").unwrap();
468     /// assert_eq!(raw, "text/plain");
469     /// ```
get_raw(&self, name: &str) -> Option<&Raw>470     pub fn get_raw(&self, name: &str) -> Option<&Raw> {
471         self.data
472             .get(name)
473             .map(Item::raw)
474     }
475 
476     /// Set the raw value of a header, bypassing any typed headers.
477     ///
478     /// Example:
479     ///
480     /// ```
481     /// # use hyper::header::Headers;
482     /// # let mut headers = Headers::new();
483     /// headers.set_raw("content-length", b"1".as_ref());
484     /// headers.set_raw("content-length", "2");
485     /// headers.set_raw("content-length", "3".to_string());
486     /// headers.set_raw("content-length", vec![vec![b'4']]);
487     /// ```
set_raw<K: Into<Cow<'static, str>>, V: Into<Raw>>(&mut self, name: K, value: V)488     pub fn set_raw<K: Into<Cow<'static, str>>, V: Into<Raw>>(&mut self, name: K, value: V) {
489         let name = name.into();
490         let value = value.into();
491         self.data.insert(HeaderName(Ascii::new(name)), Item::new_raw(value));
492     }
493 
494     /// Append a value to raw value of this header.
495     ///
496     /// If a header already contains a value, this will add another line to it.
497     ///
498     /// If a header does not exist for this name, a new one will be created with
499     /// the value.
500     ///
501     /// Example:
502     ///
503     /// ```
504     /// # use hyper::header::Headers;
505     /// # let mut headers = Headers::new();
506     /// headers.append_raw("x-foo", b"bar".to_vec());
507     /// headers.append_raw("x-foo", b"quux".to_vec());
508     /// ```
append_raw<K: Into<Cow<'static, str>>, V: Into<Raw>>(&mut self, name: K, value: V)509     pub fn append_raw<K: Into<Cow<'static, str>>, V: Into<Raw>>(&mut self, name: K, value: V) {
510         let name = name.into();
511         let value = value.into();
512         let name = HeaderName(Ascii::new(name));
513         if let Some(item) = self.data.get_mut(&name) {
514             item.raw_mut().push(value);
515             return;
516         }
517         self.data.insert(name, Item::new_raw(value));
518     }
519 
520     /// Remove a header by name.
remove_raw(&mut self, name: &str)521     pub fn remove_raw(&mut self, name: &str) {
522         self.data.remove(name);
523     }
524 
525 }
526 
527 impl PartialEq for Headers {
eq(&self, other: &Headers) -> bool528     fn eq(&self, other: &Headers) -> bool {
529         if self.len() != other.len() {
530             return false;
531         }
532 
533         for header in self.iter() {
534             match other.get_raw(header.name()) {
535                 Some(val) if val == self.get_raw(header.name()).unwrap() => {},
536                 _ => { return false; }
537             }
538         }
539         true
540     }
541 }
542 
543 impl fmt::Display for Headers {
544     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result545     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
546         for header in self.iter() {
547             try!(fmt::Display::fmt(&header, f));
548         }
549         Ok(())
550     }
551 }
552 
553 impl fmt::Debug for Headers {
554     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result555     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
556         f.debug_map()
557             .entries(self.iter().map(|view| (view.0.as_ref(), ValueString(view.1))))
558             .finish()
559     }
560 }
561 
562 #[cfg(feature = "compat")]
563 impl From<http::HeaderMap> for Headers {
from(mut header_map: http::HeaderMap) -> Headers564     fn from(mut header_map: http::HeaderMap) -> Headers {
565         let mut headers = Headers::new();
566         for (name, mut value_drain) in header_map.drain() {
567             if let Some(first_value) = value_drain.next() {
568                 let mut raw: Raw = first_value.as_bytes().into();
569                 for value in value_drain {
570                     raw.push(value.as_bytes());
571                 }
572                 headers.append_raw(name.as_str().to_string(), raw);
573             }
574         }
575         headers
576     }
577 }
578 
579 #[cfg(feature = "compat")]
580 impl From<Headers> for http::HeaderMap {
from(headers: Headers) -> http::HeaderMap581     fn from(headers: Headers) -> http::HeaderMap {
582         let mut header_map = http::HeaderMap::new();
583         for header in headers.iter() {
584             let entry = header_map.entry(header.name())
585                 .expect("attempted to convert invalid header name");
586             let mut value_iter = header.raw().iter().map(|line| {
587                 http::header::HeaderValue::from_bytes(line)
588                     .expect("attempted to convert invalid header value")
589             });
590             match entry {
591                 http::header::Entry::Occupied(mut  occupied) => {
592                     for value in value_iter {
593                         occupied.append(value);
594                     }
595                 },
596                 http::header::Entry::Vacant(vacant) => {
597                     if let Some(first_value) = value_iter.next() {
598                         let mut occupied = vacant.insert_entry(first_value);
599                         for value in value_iter {
600                             occupied.append(value);
601                         }
602                     }
603                 }
604             }
605         }
606         header_map
607     }
608 }
609 
610 /// An `Iterator` over the fields in a `Headers` map.
611 #[allow(missing_debug_implementations)]
612 pub struct HeadersItems<'a> {
613     inner: ::std::slice::Iter<'a, (HeaderName, Item)>
614 }
615 
616 impl<'a> Iterator for HeadersItems<'a> {
617     type Item = HeaderView<'a>;
618 
next(&mut self) -> Option<HeaderView<'a>>619     fn next(&mut self) -> Option<HeaderView<'a>> {
620         self.inner.next().map(|&(ref k, ref v)| HeaderView(k, v))
621     }
622 }
623 
624 /// Returned with the `HeadersItems` iterator.
625 pub struct HeaderView<'a>(&'a HeaderName, &'a Item);
626 
627 impl<'a> HeaderView<'a> {
628     /// Check if a HeaderView is a certain Header.
629     #[inline]
is<H: Header>(&self) -> bool630     pub fn is<H: Header>(&self) -> bool {
631         HeaderName(Ascii::new(Cow::Borrowed(header_name::<H>()))) == *self.0
632     }
633 
634     /// Get the Header name as a slice.
635     #[inline]
name(&self) -> &'a str636     pub fn name(&self) -> &'a str {
637         self.0.as_ref()
638     }
639 
640     /// Cast the value to a certain Header type.
641     #[inline]
value<H: Header>(&self) -> Option<&'a H>642     pub fn value<H: Header>(&self) -> Option<&'a H> {
643         self.1.typed::<H>()
644     }
645 
646     /// Get just the header value as a String.
647     ///
648     /// This will join multiple values of this header with a `, `.
649     ///
650     /// **Warning:** This may not be the format that should be used to send
651     /// a Request or Response.
652     #[inline]
value_string(&self) -> String653     pub fn value_string(&self) -> String {
654         ValueString(self.1).to_string()
655     }
656 
657     /// Access the raw value of the header.
658     #[inline]
raw(&self) -> &Raw659     pub fn raw(&self) -> &Raw {
660         self.1.raw()
661     }
662 }
663 
664 impl<'a> fmt::Display for HeaderView<'a> {
665     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result666     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
667         self.1.write_h1(&mut Formatter(Multi::Line(self.0.as_ref(), f)))
668     }
669 }
670 
671 impl<'a> fmt::Debug for HeaderView<'a> {
672     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result673     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
674         fmt::Display::fmt(self, f)
675     }
676 }
677 
678 impl<'a> Extend<HeaderView<'a>> for Headers {
extend<I: IntoIterator<Item=HeaderView<'a>>>(&mut self, iter: I)679     fn extend<I: IntoIterator<Item=HeaderView<'a>>>(&mut self, iter: I) {
680         for header in iter {
681             self.data.insert((*header.0).clone(), (*header.1).clone());
682         }
683     }
684 }
685 
686 impl<'a> Extend<(&'a str, Bytes)> for Headers {
extend<I: IntoIterator<Item=(&'a str, Bytes)>>(&mut self, iter: I)687     fn extend<I: IntoIterator<Item=(&'a str, Bytes)>>(&mut self, iter: I) {
688         for (name, value) in iter {
689             let name = HeaderName(Ascii::new(maybe_literal(name)));
690             //let trim = header.value.iter().rev().take_while(|&&x| x == b' ').count();
691 
692             match self.data.entry(name) {
693                 Entry::Vacant(entry) => {
694                     entry.insert(Item::new_raw(self::raw::parsed(value)));
695                 }
696                 Entry::Occupied(entry) => {
697                     self::raw::push(entry.into_mut().raw_mut(), value);
698                 }
699             };
700         }
701     }
702 }
703 
704 impl<'a> FromIterator<HeaderView<'a>> for Headers {
from_iter<I: IntoIterator<Item=HeaderView<'a>>>(iter: I) -> Headers705     fn from_iter<I: IntoIterator<Item=HeaderView<'a>>>(iter: I) -> Headers {
706         let mut headers = Headers::new();
707         headers.extend(iter);
708         headers
709     }
710 }
711 
712 #[derive(Clone, Debug)]
713 struct HeaderName(Ascii<Cow<'static, str>>);
714 
715 impl fmt::Display for HeaderName {
716     #[inline]
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result717     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
718         fmt::Display::fmt(self.0.as_ref(), f)
719     }
720 }
721 
722 impl AsRef<str> for HeaderName {
as_ref(&self) -> &str723     fn as_ref(&self) -> &str {
724         self.0.as_ref()
725     }
726 }
727 
728 impl PartialEq for HeaderName {
729     #[inline]
eq(&self, other: &HeaderName) -> bool730     fn eq(&self, other: &HeaderName) -> bool {
731         let s = self.as_ref();
732         let k = other.as_ref();
733         if s.as_ptr() == k.as_ptr() && s.len() == k.len() {
734             true
735         } else {
736             self.0 == other.0
737         }
738     }
739 }
740 
741 impl PartialEq<HeaderName> for str {
eq(&self, other: &HeaderName) -> bool742     fn eq(&self, other: &HeaderName) -> bool {
743         let k = other.as_ref();
744         if self.as_ptr() == k.as_ptr() && self.len() == k.len() {
745             true
746         } else {
747             other.0 == self
748         }
749     }
750 }
751 
752 #[cfg(test)]
753 mod tests {
754     use std::fmt;
755     use super::{Headers, Header, Raw, ContentLength, ContentType, Host, SetCookie};
756 
757     #[cfg(feature = "nightly")]
758     use test::Bencher;
759 
760     macro_rules! make_header {
761         ($name:expr, $value:expr) => ({
762             let mut headers = Headers::new();
763             headers.set_raw(String::from_utf8($name.to_vec()).unwrap(), $value.to_vec());
764             headers
765         });
766         ($text:expr) => ({
767             let bytes = $text;
768             let colon = bytes.iter().position(|&x| x == b':').unwrap();
769             make_header!(&bytes[..colon], &bytes[colon + 2..])
770         })
771     }
772     #[test]
test_from_raw()773     fn test_from_raw() {
774         let headers = make_header!(b"Content-Length", b"10");
775         assert_eq!(headers.get(), Some(&ContentLength(10)));
776     }
777 
778     #[derive(Clone, PartialEq, Debug)]
779     struct CrazyLength(Option<bool>, usize);
780 
781     impl Header for CrazyLength {
header_name() -> &'static str782         fn header_name() -> &'static str {
783             "content-length"
784         }
parse_header(raw: &Raw) -> ::Result<CrazyLength>785         fn parse_header(raw: &Raw) -> ::Result<CrazyLength> {
786             use std::str::from_utf8;
787             use std::str::FromStr;
788 
789             if let Some(line) = raw.one() {
790                 let s = try!(from_utf8(line).map(|s| FromStr::from_str(s).map_err(|_| ::Error::Header)));
791                 s.map(|u| CrazyLength(Some(false), u))
792             } else {
793                 Err(::Error::Header)
794             }
795         }
796 
fmt_header(&self, f: &mut super::Formatter) -> fmt::Result797         fn fmt_header(&self, f: &mut super::Formatter) -> fmt::Result {
798             f.fmt_line(self)
799         }
800     }
801 
802     impl fmt::Display for CrazyLength {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result803         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
804             let CrazyLength(ref opt, ref value) = *self;
805             write!(f, "{:?}, {:?}", opt, value)
806         }
807     }
808 
809     #[test]
test_different_structs_for_same_header()810     fn test_different_structs_for_same_header() {
811         let headers = make_header!(b"Content-Length: 10");
812         assert_eq!(headers.get::<ContentLength>(), Some(&ContentLength(10)));
813         assert_eq!(headers.get::<CrazyLength>(), Some(&CrazyLength(Some(false), 10)));
814     }
815 
816     #[test]
test_trailing_whitespace()817     fn test_trailing_whitespace() {
818         let headers = make_header!(b"Content-Length: 10   ");
819         assert_eq!(headers.get::<ContentLength>(), Some(&ContentLength(10)));
820     }
821 
822     #[test]
test_multiple_reads()823     fn test_multiple_reads() {
824         let headers = make_header!(b"Content-Length: 10");
825         let ContentLength(one) = *headers.get::<ContentLength>().unwrap();
826         let ContentLength(two) = *headers.get::<ContentLength>().unwrap();
827         assert_eq!(one, two);
828     }
829 
830     #[test]
test_different_reads()831     fn test_different_reads() {
832         let mut headers = Headers::new();
833         headers.set_raw("Content-Length", "10");
834         headers.set_raw("Content-Type", "text/plain");
835         let ContentLength(_) = *headers.get::<ContentLength>().unwrap();
836         let ContentType(_) = *headers.get::<ContentType>().unwrap();
837     }
838 
839     #[test]
test_typed_get_raw()840     fn test_typed_get_raw() {
841         let mut headers = Headers::new();
842         headers.set(ContentLength(15));
843         assert_eq!(headers.get_raw("content-length").unwrap(), "15");
844 
845         headers.set(SetCookie(vec![
846             "foo=bar".to_string(),
847             "baz=quux; Path=/path".to_string()
848         ]));
849         assert_eq!(headers.get_raw("set-cookie").unwrap(), &["foo=bar", "baz=quux; Path=/path"][..]);
850     }
851 
852     #[test]
test_get_mutable()853     fn test_get_mutable() {
854         let mut headers = make_header!(b"Content-Length: 10");
855         *headers.get_mut::<ContentLength>().unwrap() = ContentLength(20);
856         assert_eq!(headers.get_raw("content-length").unwrap(), &[b"20".to_vec()][..]);
857         assert_eq!(*headers.get::<ContentLength>().unwrap(), ContentLength(20));
858     }
859 
860     #[test]
test_headers_to_string()861     fn test_headers_to_string() {
862         let mut headers = Headers::new();
863         headers.set(ContentLength(15));
864         headers.set(Host::new("foo.bar", None));
865 
866         let s = headers.to_string();
867         assert!(s.contains("Host: foo.bar\r\n"));
868         assert!(s.contains("Content-Length: 15\r\n"));
869     }
870 
871     #[test]
test_headers_to_string_raw()872     fn test_headers_to_string_raw() {
873         let mut headers = make_header!(b"Content-Length: 10");
874         headers.set_raw("x-foo", vec![b"foo".to_vec(), b"bar".to_vec()]);
875         let s = headers.to_string();
876         assert_eq!(s, "Content-Length: 10\r\nx-foo: foo\r\nx-foo: bar\r\n");
877     }
878 
879     #[test]
test_set_raw()880     fn test_set_raw() {
881         let mut headers = Headers::new();
882         headers.set(ContentLength(10));
883         headers.set_raw("content-LENGTH", vec![b"20".to_vec()]);
884         assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"20".to_vec()][..]);
885         assert_eq!(headers.get(), Some(&ContentLength(20)));
886     }
887 
888     #[test]
test_append_raw()889     fn test_append_raw() {
890         let mut headers = Headers::new();
891         headers.set(ContentLength(10));
892         headers.append_raw("content-LENGTH", b"20".to_vec());
893         assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"10".to_vec(), b"20".to_vec()][..]);
894         headers.append_raw("x-foo", "bar");
895         assert_eq!(headers.get_raw("x-foo").unwrap(), &[b"bar".to_vec()][..]);
896     }
897 
898     #[test]
test_remove_raw()899     fn test_remove_raw() {
900         let mut headers = Headers::new();
901         headers.set_raw("content-LENGTH", vec![b"20".to_vec()]);
902         headers.remove_raw("content-LENGTH");
903         assert_eq!(headers.get_raw("Content-length"), None);
904     }
905 
906     #[test]
test_remove()907     fn test_remove() {
908         let mut headers = Headers::new();
909         headers.set(ContentLength(10));
910         assert_eq!(headers.remove(), Some(ContentLength(10)));
911         assert_eq!(headers.len(), 0);
912 
913         headers.set(ContentLength(9));
914         assert_eq!(headers.len(), 1);
915         assert!(headers.remove::<CrazyLength>().is_none());
916         assert_eq!(headers.len(), 0);
917     }
918 
919     #[test]
test_len()920     fn test_len() {
921         let mut headers = Headers::new();
922         headers.set(ContentLength(10));
923         assert_eq!(headers.len(), 1);
924         headers.set(ContentType::json());
925         assert_eq!(headers.len(), 2);
926         // Redundant, should not increase count.
927         headers.set(ContentLength(20));
928         assert_eq!(headers.len(), 2);
929     }
930 
931     #[test]
test_clear()932     fn test_clear() {
933         let mut headers = Headers::new();
934         headers.set(ContentLength(10));
935         headers.set(ContentType::json());
936         assert_eq!(headers.len(), 2);
937         headers.clear();
938         assert_eq!(headers.len(), 0);
939     }
940 
941     #[test]
test_iter()942     fn test_iter() {
943         let mut headers = Headers::new();
944         headers.set(ContentLength(11));
945         for header in headers.iter() {
946             assert!(header.is::<ContentLength>());
947             assert_eq!(header.name(), <ContentLength as Header>::header_name());
948             assert_eq!(header.value(), Some(&ContentLength(11)));
949             assert_eq!(header.value_string(), "11".to_owned());
950         }
951     }
952 
953     #[test]
test_header_view_value_string()954     fn test_header_view_value_string() {
955         let mut headers = Headers::new();
956         headers.set_raw("foo", vec![b"one".to_vec(), b"two".to_vec()]);
957         for header in headers.iter() {
958             assert_eq!(header.name(), "foo");
959             assert_eq!(header.value_string(), "one, two");
960         }
961     }
962 
963     #[test]
test_header_view_raw()964     fn test_header_view_raw() {
965         let mut headers = Headers::new();
966         headers.set_raw("foo", vec![b"one".to_vec(), b"two".to_vec()]);
967         for header in headers.iter() {
968             assert_eq!(header.name(), "foo");
969             let values: Vec<&[u8]> = header.raw().iter().collect();
970             assert_eq!(values, vec![b"one", b"two"]);
971         }
972     }
973 
974     #[test]
test_eq()975     fn test_eq() {
976         let mut headers1 = Headers::new();
977         let mut headers2 = Headers::new();
978 
979         assert_eq!(headers1, headers2);
980 
981         headers1.set(ContentLength(11));
982         headers2.set(Host::new("foo.bar", None));
983         assert_ne!(headers1, headers2);
984 
985         headers1 = Headers::new();
986         headers2 = Headers::new();
987 
988         headers1.set(ContentLength(11));
989         headers2.set(ContentLength(11));
990         assert_eq!(headers1, headers2);
991 
992         headers1.set(ContentLength(10));
993         assert_ne!(headers1, headers2);
994 
995         headers1 = Headers::new();
996         headers2 = Headers::new();
997 
998         headers1.set(Host::new("foo.bar", None));
999         headers1.set(ContentLength(11));
1000         headers2.set(ContentLength(11));
1001         assert_ne!(headers1, headers2);
1002     }
1003 
1004     #[test]
1005     #[cfg(feature = "compat")]
test_compat()1006     fn test_compat() {
1007         use http;
1008 
1009         let mut orig_hyper_headers = Headers::new();
1010         orig_hyper_headers.set(ContentLength(11));
1011         orig_hyper_headers.set(Host::new("foo.bar", None));
1012         orig_hyper_headers.append_raw("x-foo", b"bar".to_vec());
1013         orig_hyper_headers.append_raw("x-foo", b"quux".to_vec());
1014 
1015         let mut orig_http_headers = http::HeaderMap::new();
1016         orig_http_headers.insert(http::header::CONTENT_LENGTH, "11".parse().unwrap());
1017         orig_http_headers.insert(http::header::HOST, "foo.bar".parse().unwrap());
1018         orig_http_headers.append("x-foo", "bar".parse().unwrap());
1019         orig_http_headers.append("x-foo", "quux".parse().unwrap());
1020 
1021         let conv_hyper_headers: Headers = orig_http_headers.clone().into();
1022         let conv_http_headers: http::HeaderMap = orig_hyper_headers.clone().into();
1023         assert_eq!(orig_hyper_headers, conv_hyper_headers);
1024         assert_eq!(orig_http_headers, conv_http_headers);
1025     }
1026 
1027     #[cfg(feature = "nightly")]
1028     #[bench]
bench_headers_new(b: &mut Bencher)1029     fn bench_headers_new(b: &mut Bencher) {
1030         b.iter(|| {
1031             let mut h = Headers::new();
1032             h.set(ContentLength(11));
1033             h
1034         })
1035     }
1036 
1037     #[cfg(feature = "nightly")]
1038     #[bench]
bench_headers_get(b: &mut Bencher)1039     fn bench_headers_get(b: &mut Bencher) {
1040         let mut headers = Headers::new();
1041         headers.set(ContentLength(11));
1042         b.iter(|| assert_eq!(headers.get::<ContentLength>(), Some(&ContentLength(11))))
1043     }
1044 
1045     #[cfg(feature = "nightly")]
1046     #[bench]
bench_headers_get_miss(b: &mut Bencher)1047     fn bench_headers_get_miss(b: &mut Bencher) {
1048         let headers = Headers::new();
1049         b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
1050     }
1051 
1052     #[cfg(feature = "nightly")]
1053     #[bench]
bench_headers_get_miss_previous_10(b: &mut Bencher)1054     fn bench_headers_get_miss_previous_10(b: &mut Bencher) {
1055         let mut headers = Headers::new();
1056         for i in 0..10 {
1057             headers.set_raw(format!("non-standard-{}", i), "hi");
1058         }
1059         b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
1060     }
1061 
1062     #[cfg(feature = "nightly")]
1063     #[bench]
bench_headers_set(b: &mut Bencher)1064     fn bench_headers_set(b: &mut Bencher) {
1065         let mut headers = Headers::new();
1066         b.iter(|| headers.set(ContentLength(12)))
1067     }
1068 
1069     #[cfg(feature = "nightly")]
1070     #[bench]
bench_headers_set_previous_10(b: &mut Bencher)1071     fn bench_headers_set_previous_10(b: &mut Bencher) {
1072         let mut headers = Headers::new();
1073         for i in 0..10 {
1074             headers.set_raw(format!("non-standard-{}", i), "hi");
1075         }
1076         b.iter(|| headers.set(ContentLength(12)))
1077     }
1078 
1079     #[cfg(feature = "nightly")]
1080     #[bench]
bench_headers_set_raw(b: &mut Bencher)1081     fn bench_headers_set_raw(b: &mut Bencher) {
1082         let mut headers = Headers::new();
1083         b.iter(|| headers.set_raw("non-standard", "hello"))
1084     }
1085 
1086     #[cfg(feature = "nightly")]
1087     #[bench]
bench_headers_set_raw_previous_10(b: &mut Bencher)1088     fn bench_headers_set_raw_previous_10(b: &mut Bencher) {
1089         let mut headers = Headers::new();
1090         for i in 0..10 {
1091             headers.set_raw(format!("non-standard-{}", i), "hi");
1092         }
1093         b.iter(|| headers.set_raw("non-standard", "hello"))
1094     }
1095 
1096     #[cfg(feature = "nightly")]
1097     #[bench]
bench_headers_has(b: &mut Bencher)1098     fn bench_headers_has(b: &mut Bencher) {
1099         let mut headers = Headers::new();
1100         headers.set(ContentLength(11));
1101         b.iter(|| assert!(headers.has::<ContentLength>()))
1102     }
1103 
1104     #[cfg(feature = "nightly")]
1105     #[bench]
bench_headers_view_is(b: &mut Bencher)1106     fn bench_headers_view_is(b: &mut Bencher) {
1107         let mut headers = Headers::new();
1108         headers.set(ContentLength(11));
1109         let mut iter = headers.iter();
1110         let view = iter.next().unwrap();
1111         b.iter(|| assert!(view.is::<ContentLength>()))
1112     }
1113 
1114     #[cfg(feature = "nightly")]
1115     #[bench]
bench_headers_fmt(b: &mut Bencher)1116     fn bench_headers_fmt(b: &mut Bencher) {
1117         use std::fmt::Write;
1118         let mut buf = String::with_capacity(64);
1119         let mut headers = Headers::new();
1120         headers.set(ContentLength(11));
1121         headers.set(ContentType::json());
1122         b.bytes = headers.to_string().len() as u64;
1123         b.iter(|| {
1124             let _ = write!(buf, "{}", headers);
1125             ::test::black_box(&buf);
1126             unsafe { buf.as_mut_vec().set_len(0); }
1127         })
1128     }
1129 }
1130