change Host header to have hostname and port
This commit is contained in:
		| @@ -1,4 +1,5 @@ | ||||
| use header::Header; | ||||
| use Port; | ||||
| use std::fmt::{mod, Show}; | ||||
| use super::util::from_one_raw_str; | ||||
|  | ||||
| @@ -10,7 +11,12 @@ use super::util::from_one_raw_str; | ||||
| /// Currently is just a String, but it should probably become a better type, | ||||
| /// like url::Host or something. | ||||
| #[deriving(Clone, PartialEq, Show)] | ||||
| pub struct Host(pub String); | ||||
| pub struct Host { | ||||
|     /// The hostname, such a example.domain. | ||||
|     pub hostname: String, | ||||
|     /// An optional port number. | ||||
|     pub port: Option<Port> | ||||
| } | ||||
|  | ||||
| impl Header for Host { | ||||
|     fn header_name(_: Option<Host>) -> &'static str { | ||||
| @@ -18,12 +24,71 @@ impl Header for Host { | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Host> { | ||||
|         from_one_raw_str(raw).map(|s| Host(s)) | ||||
|         from_one_raw_str(raw).and_then(|mut s: String| { | ||||
|             // FIXME: use rust-url to parse this | ||||
|             // https://github.com/servo/rust-url/issues/42 | ||||
|             let idx = { | ||||
|                 let slice = s[]; | ||||
|                 if slice.char_at(1) == '[' { | ||||
|                     match slice.rfind(']') { | ||||
|                         Some(idx) => { | ||||
|                             if slice.len() > idx + 2 { | ||||
|                                 Some(idx + 1) | ||||
|                             } else { | ||||
|                                 None | ||||
|                             } | ||||
|                         } | ||||
|                         None => return None // this is a bad ipv6 address... | ||||
|                     } | ||||
|                 } else { | ||||
|                     slice.rfind(':') | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             let port = match idx { | ||||
|                 Some(idx) => from_str::<u16>(s[].slice_from(idx + 1)), | ||||
|                 None => None | ||||
|             }; | ||||
|  | ||||
|             match idx { | ||||
|                 Some(idx) => s.truncate(idx), | ||||
|                 None => () | ||||
|             } | ||||
|  | ||||
|             Some(Host { | ||||
|                 hostname: s, | ||||
|                 port: port | ||||
|             }) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         let Host(ref value) = *self; | ||||
|         value.fmt(fmt) | ||||
|         match self.port { | ||||
|             None | Some(80) | Some(443) => self.hostname.fmt(fmt), | ||||
|             Some(port) => write!(fmt, "{}:{}", self.hostname, port) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::Host; | ||||
|     use header::Header; | ||||
|  | ||||
|  | ||||
|     #[test] | ||||
|     fn test_host() { | ||||
|         let host = Header::parse_header([b"foo.com".to_vec()].as_slice()); | ||||
|         assert_eq!(host, Some(Host { | ||||
|             hostname: "foo.com".into_string(), | ||||
|             port: None | ||||
|         })); | ||||
|  | ||||
|  | ||||
|         let host = Header::parse_header([b"foo.com:8080".to_vec()].as_slice()); | ||||
|         assert_eq!(host, Some(Host { | ||||
|             hostname: "foo.com".into_string(), | ||||
|             port: Some(8080) | ||||
|         })); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user