| @@ -1,4 +1,4 @@ | |||||||
| #![feature(core, io, test)] | #![feature(core, old_io, test)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| extern crate test; | extern crate test; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #![feature(collections, io, test)] | #![feature(collections, old_io, test)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| extern crate test; | extern crate test; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #![feature(io, test)] | #![feature(old_io, test)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
| extern crate test; | extern crate test; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #![feature(env, io)] | #![feature(env, old_io)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| use std::env; | use std::env; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #![feature(io)] | #![feature(old_io)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
|  |  | ||||||
| use std::old_io::net::ip::Ipv4Addr; | use std::old_io::net::ip::Ipv4Addr; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #![feature(io)] | #![feature(old_io)] | ||||||
| extern crate hyper; | extern crate hyper; | ||||||
| #[macro_use] extern crate log; | #[macro_use] extern crate log; | ||||||
|  |  | ||||||
| @@ -21,7 +21,7 @@ macro_rules! try_return( | |||||||
|  |  | ||||||
| fn echo(mut req: Request, mut res: Response) { | fn echo(mut req: Request, mut res: Response) { | ||||||
|     match req.uri { |     match req.uri { | ||||||
|         AbsolutePath(ref path) => match (&req.method, &path[]) { |         AbsolutePath(ref path) => match (&req.method, &path[..]) { | ||||||
|             (&Get, "/") | (&Get, "/echo") => { |             (&Get, "/") | (&Get, "/echo") => { | ||||||
|                 let out = b"Try POST /echo"; |                 let out = b"Try POST /echo"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -197,7 +197,7 @@ impl<'a, U: IntoUrl, C: NetworkConnector> RequestBuilder<'a, U, C> { | |||||||
|                 // punching borrowck here |                 // punching borrowck here | ||||||
|                 let loc = match res.headers.get::<Location>() { |                 let loc = match res.headers.get::<Location>() { | ||||||
|                     Some(&Location(ref loc)) => { |                     Some(&Location(ref loc)) => { | ||||||
|                         Some(UrlParser::new().base_url(&url).parse(&loc[])) |                         Some(UrlParser::new().base_url(&url).parse(&loc[..])) | ||||||
|                     } |                     } | ||||||
|                     None => { |                     None => { | ||||||
|                         debug!("no Location header"); |                         debug!("no Location header"); | ||||||
| @@ -394,7 +394,7 @@ mod tests { | |||||||
|     #[test] |     #[test] | ||||||
|     fn test_redirect_followif() { |     fn test_redirect_followif() { | ||||||
|         fn follow_if(url: &Url) -> bool { |         fn follow_if(url: &Url) -> bool { | ||||||
|             !url.serialize()[].contains("127.0.0.3") |             !url.serialize().contains("127.0.0.3") | ||||||
|         } |         } | ||||||
|         let mut client = Client::with_connector(MockRedirectPolicy); |         let mut client = Client::with_connector(MockRedirectPolicy); | ||||||
|         client.set_redirect_policy(RedirectPolicy::FollowIf(follow_if)); |         client.set_redirect_policy(RedirectPolicy::FollowIf(follow_if)); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| //! Client Requests | //! Client Requests | ||||||
| use std::old_io::{BufferedWriter, IoResult}; | use std::old_io::{BufferedWriter, IoResult}; | ||||||
|  | use std::marker::PhantomData; | ||||||
|  |  | ||||||
| use url::Url; | use url::Url; | ||||||
|  |  | ||||||
| @@ -25,8 +26,13 @@ pub struct Request<W> { | |||||||
|     body: HttpWriter<BufferedWriter<Box<NetworkStream + Send>>>, |     body: HttpWriter<BufferedWriter<Box<NetworkStream + Send>>>, | ||||||
|     headers: Headers, |     headers: Headers, | ||||||
|     method: method::Method, |     method: method::Method, | ||||||
|  |  | ||||||
|  |     _marker: PhantomData<W>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //FIXME: remove once https://github.com/rust-lang/issues/22629 is fixed | ||||||
|  | unsafe impl<W> Send for Request<W> {} | ||||||
|  |  | ||||||
| impl<W> Request<W> { | impl<W> Request<W> { | ||||||
|     /// Read the Request headers. |     /// Read the Request headers. | ||||||
|     #[inline] |     #[inline] | ||||||
| @@ -66,7 +72,8 @@ impl Request<Fresh> { | |||||||
|             headers: headers, |             headers: headers, | ||||||
|             url: url, |             url: url, | ||||||
|             version: version::HttpVersion::Http11, |             version: version::HttpVersion::Http11, | ||||||
|             body: stream |             body: stream, | ||||||
|  |             _marker: PhantomData, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -77,7 +84,7 @@ impl Request<Fresh> { | |||||||
|         //TODO: this needs a test |         //TODO: this needs a test | ||||||
|         if let Some(ref q) = self.url.query { |         if let Some(ref q) = self.url.query { | ||||||
|             uri.push('?'); |             uri.push('?'); | ||||||
|             uri.push_str(&q[]); |             uri.push_str(&q[..]); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         debug!("writing head: {:?} {:?} {:?}", self.method, uri, self.version); |         debug!("writing head: {:?} {:?} {:?}", self.method, uri, self.version); | ||||||
| @@ -136,7 +143,8 @@ impl Request<Fresh> { | |||||||
|             headers: self.headers, |             headers: self.headers, | ||||||
|             url: self.url, |             url: self.url, | ||||||
|             version: self.version, |             version: self.version, | ||||||
|             body: stream |             body: stream, | ||||||
|  |             _marker: PhantomData, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -185,7 +193,7 @@ mod tests { | |||||||
|         let stream = *req.body.end().unwrap() |         let stream = *req.body.end().unwrap() | ||||||
|             .into_inner().downcast::<MockStream>().ok().unwrap(); |             .into_inner().downcast::<MockStream>().ok().unwrap(); | ||||||
|         let bytes = stream.write.into_inner(); |         let bytes = stream.write.into_inner(); | ||||||
|         let s = from_utf8(&bytes[]).unwrap(); |         let s = from_utf8(&bytes[..]).unwrap(); | ||||||
|         assert!(!s.contains("Content-Length:")); |         assert!(!s.contains("Content-Length:")); | ||||||
|         assert!(!s.contains("Transfer-Encoding:")); |         assert!(!s.contains("Transfer-Encoding:")); | ||||||
|     } |     } | ||||||
| @@ -199,7 +207,7 @@ mod tests { | |||||||
|         let stream = *req.body.end().unwrap() |         let stream = *req.body.end().unwrap() | ||||||
|             .into_inner().downcast::<MockStream>().ok().unwrap(); |             .into_inner().downcast::<MockStream>().ok().unwrap(); | ||||||
|         let bytes = stream.write.into_inner(); |         let bytes = stream.write.into_inner(); | ||||||
|         let s = from_utf8(&bytes[]).unwrap(); |         let s = from_utf8(&bytes[..]).unwrap(); | ||||||
|         assert!(!s.contains("Content-Length:")); |         assert!(!s.contains("Content-Length:")); | ||||||
|         assert!(!s.contains("Transfer-Encoding:")); |         assert!(!s.contains("Transfer-Encoding:")); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| //! Client Responses | //! Client Responses | ||||||
| use std::num::FromPrimitive; | use std::num::FromPrimitive; | ||||||
| use std::old_io::{BufferedReader, IoResult}; | use std::old_io::{BufferedReader, IoResult}; | ||||||
|  | use std::marker::PhantomData; | ||||||
|  |  | ||||||
| use header; | use header; | ||||||
| use header::{ContentLength, TransferEncoding}; | use header::{ContentLength, TransferEncoding}; | ||||||
| @@ -23,8 +24,13 @@ pub struct Response<S = HttpStream> { | |||||||
|     pub version: version::HttpVersion, |     pub version: version::HttpVersion, | ||||||
|     status_raw: RawStatus, |     status_raw: RawStatus, | ||||||
|     body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>, |     body: HttpReader<BufferedReader<Box<NetworkStream + Send>>>, | ||||||
|  |  | ||||||
|  |     _marker: PhantomData<S>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //FIXME: remove once https://github.com/rust-lang/issues/22629 is fixed | ||||||
|  | unsafe impl<S: Send> Send for Response<S> {} | ||||||
|  |  | ||||||
| impl Response { | impl Response { | ||||||
|  |  | ||||||
|     /// Creates a new response from a server. |     /// Creates a new response from a server. | ||||||
| @@ -72,6 +78,7 @@ impl Response { | |||||||
|             headers: headers, |             headers: headers, | ||||||
|             body: body, |             body: body, | ||||||
|             status_raw: raw_status, |             status_raw: raw_status, | ||||||
|  |             _marker: PhantomData, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -98,6 +105,7 @@ mod tests { | |||||||
|     use std::borrow::Cow::Borrowed; |     use std::borrow::Cow::Borrowed; | ||||||
|     use std::boxed::BoxAny; |     use std::boxed::BoxAny; | ||||||
|     use std::old_io::BufferedReader; |     use std::old_io::BufferedReader; | ||||||
|  |     use std::marker::PhantomData; | ||||||
|  |  | ||||||
|     use header::Headers; |     use header::Headers; | ||||||
|     use header::TransferEncoding; |     use header::TransferEncoding; | ||||||
| @@ -119,7 +127,8 @@ mod tests { | |||||||
|             headers: Headers::new(), |             headers: Headers::new(), | ||||||
|             version: version::HttpVersion::Http11, |             version: version::HttpVersion::Http11, | ||||||
|             body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)), |             body: EofReader(BufferedReader::new(box MockStream::new() as Box<NetworkStream + Send>)), | ||||||
|             status_raw: RawStatus(200, Borrowed("OK")) |             status_raw: RawStatus(200, Borrowed("OK")), | ||||||
|  |             _marker: PhantomData, | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let b = res.into_inner().downcast::<MockStream>().ok().unwrap(); |         let b = res.into_inner().downcast::<MockStream>().ok().unwrap(); | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ impl header::Header for AccessControlAllowOrigin { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> { | ||||||
|         if raw.len() == 1 { |         if raw.len() == 1 { | ||||||
|             match str::from_utf8(unsafe { &raw[].get_unchecked(0)[] }) { |             match str::from_utf8(unsafe { &raw.get_unchecked(0)[..] }) { | ||||||
|                 Ok(s) => { |                 Ok(s) => { | ||||||
|                     if s == "*" { |                     if s == "*" { | ||||||
|                         Some(AccessControlAllowOrigin::AllowStar) |                         Some(AccessControlAllowOrigin::AllowStar) | ||||||
|   | |||||||
| @@ -22,14 +22,14 @@ impl<S: Scheme> DerefMut for Authorization<S> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<S: Scheme> Header for Authorization<S> { | impl<S: Scheme + 'static> Header for Authorization<S> where <S as FromStr>::Err: 'static { | ||||||
|     fn header_name() -> &'static str { |     fn header_name() -> &'static str { | ||||||
|         "Authorization" |         "Authorization" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Authorization<S>> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<Authorization<S>> { | ||||||
|         if raw.len() == 1 { |         if raw.len() == 1 { | ||||||
|             match (from_utf8(unsafe { &raw[].get_unchecked(0)[] }), Scheme::scheme(None::<S>)) { |             match (from_utf8(unsafe { &raw.get_unchecked(0)[..] }), Scheme::scheme(None::<S>)) { | ||||||
|                 (Ok(header), Some(scheme)) |                 (Ok(header), Some(scheme)) | ||||||
|                     if header.starts_with(scheme) && header.len() > scheme.len() + 1 => { |                     if header.starts_with(scheme) && header.len() > scheme.len() + 1 => { | ||||||
|                     header[scheme.len() + 1..].parse::<S>().map(|s| Authorization(s)).ok() |                     header[scheme.len() + 1..].parse::<S>().map(|s| Authorization(s)).ok() | ||||||
| @@ -43,7 +43,7 @@ impl<S: Scheme> Header for Authorization<S> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<S: Scheme> HeaderFormat for Authorization<S> { | impl<S: Scheme + 'static> HeaderFormat for Authorization<S> where <S as FromStr>::Err: 'static { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         match Scheme::scheme(None::<S>) { |         match Scheme::scheme(None::<S>) { | ||||||
|             Some(scheme) => try!(write!(fmt, "{} ", scheme)), |             Some(scheme) => try!(write!(fmt, "{} ", scheme)), | ||||||
| @@ -96,7 +96,7 @@ impl Scheme for Basic { | |||||||
|         let mut text = self.username.clone(); |         let mut text = self.username.clone(); | ||||||
|         text.push(':'); |         text.push(':'); | ||||||
|         if let Some(ref pass) = self.password { |         if let Some(ref pass) = self.password { | ||||||
|             text.push_str(&pass[]); |             text.push_str(&pass[..]); | ||||||
|         } |         } | ||||||
|         write!(f, "{}", text.as_bytes().to_base64(Config { |         write!(f, "{}", text.as_bytes().to_base64(Config { | ||||||
|             char_set: Standard, |             char_set: Standard, | ||||||
| @@ -113,7 +113,7 @@ impl FromStr for Basic { | |||||||
|         match s.from_base64() { |         match s.from_base64() { | ||||||
|             Ok(decoded) => match String::from_utf8(decoded) { |             Ok(decoded) => match String::from_utf8(decoded) { | ||||||
|                 Ok(text) => { |                 Ok(text) => { | ||||||
|                     let mut parts = &mut text[].split(':'); |                     let mut parts = &mut text.split(':'); | ||||||
|                     let user = match parts.next() { |                     let user = match parts.next() { | ||||||
|                         Some(part) => part.to_string(), |                         Some(part) => part.to_string(), | ||||||
|                         None => return Err(()) |                         None => return Err(()) | ||||||
| @@ -160,7 +160,7 @@ mod tests { | |||||||
|     #[test] |     #[test] | ||||||
|     fn test_raw_auth_parse() { |     fn test_raw_auth_parse() { | ||||||
|         let headers = Headers::from_raw(&mut mem("Authorization: foo bar baz\r\n\r\n")).unwrap(); |         let headers = Headers::from_raw(&mut mem("Authorization: foo bar baz\r\n\r\n")).unwrap(); | ||||||
|         assert_eq!(&headers.get::<Authorization<String>>().unwrap().0[], "foo bar baz"); |         assert_eq!(&headers.get::<Authorization<String>>().unwrap().0[..], "foo bar baz"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
| @@ -181,7 +181,7 @@ mod tests { | |||||||
|     fn test_basic_auth_parse() { |     fn test_basic_auth_parse() { | ||||||
|         let headers = Headers::from_raw(&mut mem("Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n\r\n")).unwrap(); |         let headers = Headers::from_raw(&mut mem("Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n\r\n")).unwrap(); | ||||||
|         let auth = headers.get::<Authorization<Basic>>().unwrap(); |         let auth = headers.get::<Authorization<Basic>>().unwrap(); | ||||||
|         assert_eq!(&auth.0.username[], "Aladdin"); |         assert_eq!(&auth.0.username[..], "Aladdin"); | ||||||
|         assert_eq!(auth.0.password, Some("open sesame".to_string())); |         assert_eq!(auth.0.password, Some("open sesame".to_string())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ impl Header for CacheControl { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<CacheControl> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<CacheControl> { | ||||||
|         let directives = raw.iter() |         let directives = raw.iter() | ||||||
|             .filter_map(|line| from_one_comma_delimited(&line[])) |             .filter_map(|line| from_one_comma_delimited(&line[..])) | ||||||
|             .collect::<Vec<Vec<CacheDirective>>>() |             .collect::<Vec<Vec<CacheDirective>>>() | ||||||
|             .concat(); |             .concat(); | ||||||
|         if directives.len() > 0 { |         if directives.len() > 0 { | ||||||
| @@ -29,7 +29,7 @@ impl Header for CacheControl { | |||||||
|  |  | ||||||
| impl HeaderFormat for CacheControl { | impl HeaderFormat for CacheControl { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         fmt_comma_delimited(fmt, &self[]) |         fmt_comma_delimited(fmt, &self[..]) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -88,7 +88,7 @@ impl fmt::Display for CacheDirective { | |||||||
|             ProxyRevalidate => "proxy-revalidate", |             ProxyRevalidate => "proxy-revalidate", | ||||||
|             SMaxAge(secs) => return write!(f, "s-maxage={}", secs), |             SMaxAge(secs) => return write!(f, "s-maxage={}", secs), | ||||||
|  |  | ||||||
|             Extension(ref name, None) => &name[], |             Extension(ref name, None) => &name[..], | ||||||
|             Extension(ref name, Some(ref arg)) => return write!(f, "{}={}", name, arg), |             Extension(ref name, Some(ref arg)) => return write!(f, "{}={}", name, arg), | ||||||
|  |  | ||||||
|         }, f) |         }, f) | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ impl Header for Connection { | |||||||
| impl HeaderFormat for Connection { | impl HeaderFormat for Connection { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         let Connection(ref parts) = *self; |         let Connection(ref parts) = *self; | ||||||
|         fmt_comma_delimited(fmt, &parts[]) |         fmt_comma_delimited(fmt, &parts[..]) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ impl Header for Cookie { | |||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Cookie> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<Cookie> { | ||||||
|         let mut cookies = Vec::with_capacity(raw.len()); |         let mut cookies = Vec::with_capacity(raw.len()); | ||||||
|         for cookies_raw in raw.iter() { |         for cookies_raw in raw.iter() { | ||||||
|             match from_utf8(&cookies_raw[]) { |             match from_utf8(&cookies_raw[..]) { | ||||||
|                 Ok(cookies_str) => { |                 Ok(cookies_str) => { | ||||||
|                     for cookie_str in cookies_str.split(';') { |                     for cookie_str in cookies_str.split(';') { | ||||||
|                         match cookie_str.trim().parse() { |                         match cookie_str.trim().parse() { | ||||||
| @@ -82,7 +82,7 @@ impl Cookie { | |||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
| fn test_parse() { | fn test_parse() { | ||||||
|     let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][]); |     let h = Header::parse_header(&[b"foo=bar; baz=quux".to_vec()][..]); | ||||||
|     let c1 = CookiePair::new("foo".to_string(), "bar".to_string()); |     let c1 = CookiePair::new("foo".to_string(), "bar".to_string()); | ||||||
|     let c2 = CookiePair::new("baz".to_string(), "quux".to_string()); |     let c2 = CookiePair::new("baz".to_string(), "quux".to_string()); | ||||||
|     assert_eq!(h, Some(Cookie(vec![c1, c2]))); |     assert_eq!(h, Some(Cookie(vec![c1, c2]))); | ||||||
| @@ -99,7 +99,7 @@ fn test_fmt() { | |||||||
|     let mut headers = Headers::new(); |     let mut headers = Headers::new(); | ||||||
|     headers.set(cookie_header); |     headers.set(cookie_header); | ||||||
|  |  | ||||||
|     assert_eq!(&headers.to_string()[], "Cookie: foo=bar; baz=quux\r\n"); |     assert_eq!(&headers.to_string()[..], "Cookie: foo=bar; baz=quux\r\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ impl Header for Host { | |||||||
|             // FIXME: use rust-url to parse this |             // FIXME: use rust-url to parse this | ||||||
|             // https://github.com/servo/rust-url/issues/42 |             // https://github.com/servo/rust-url/issues/42 | ||||||
|             let idx = { |             let idx = { | ||||||
|                 let slice = &s[]; |                 let slice = &s[..]; | ||||||
|                 if slice.char_at(1) == '[' { |                 if slice.char_at(1) == '[' { | ||||||
|                     match slice.rfind(']') { |                     match slice.rfind(']') { | ||||||
|                         Some(idx) => { |                         Some(idx) => { | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ impl Header for IfMatch { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<IfMatch> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<IfMatch> { | ||||||
|         from_one_raw_str(raw).and_then(|s: String| { |         from_one_raw_str(raw).and_then(|s: String| { | ||||||
|             let slice = &s[]; |             let slice = &s[..]; | ||||||
|             match slice { |             match slice { | ||||||
|                 "" => None, |                 "" => None, | ||||||
|                 "*" => Some(IfMatch::Any), |                 "*" => Some(IfMatch::Any), | ||||||
| @@ -39,7 +39,7 @@ impl HeaderFormat for IfMatch { | |||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         match *self { |         match *self { | ||||||
|             IfMatch::Any => write!(fmt, "*"), |             IfMatch::Any => write!(fmt, "*"), | ||||||
|             IfMatch::EntityTags(ref fields) => fmt_comma_delimited(fmt, &fields[]) |             IfMatch::EntityTags(ref fields) => fmt_comma_delimited(fmt, &fields[..]) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ impl Header for IfNoneMatch { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<IfNoneMatch> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<IfNoneMatch> { | ||||||
|         from_one_raw_str(raw).and_then(|s: String| { |         from_one_raw_str(raw).and_then(|s: String| { | ||||||
|             let slice = &s[]; |             let slice = &s[..]; | ||||||
|             match slice { |             match slice { | ||||||
|                 "" => None, |                 "" => None, | ||||||
|                 "*" => Some(IfNoneMatch::Any), |                 "*" => Some(IfNoneMatch::Any), | ||||||
| @@ -47,7 +47,7 @@ impl HeaderFormat for IfNoneMatch { | |||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         match *self { |         match *self { | ||||||
|             IfNoneMatch::Any => { write!(fmt, "*") } |             IfNoneMatch::Any => { write!(fmt, "*") } | ||||||
|             IfNoneMatch::EntityTags(ref fields) => { fmt_comma_delimited(fmt, &fields[]) } |             IfNoneMatch::EntityTags(ref fields) => { fmt_comma_delimited(fmt, &fields[..]) } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,13 +50,13 @@ macro_rules! bench_header( | |||||||
|             fn bench_parse(b: &mut Bencher) { |             fn bench_parse(b: &mut Bencher) { | ||||||
|                 let val = $value; |                 let val = $value; | ||||||
|                 b.iter(|| { |                 b.iter(|| { | ||||||
|                     let _: $ty = Header::parse_header(&val[]).unwrap(); |                     let _: $ty = Header::parse_header(&val[..]).unwrap(); | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             #[bench] |             #[bench] | ||||||
|             fn bench_format(b: &mut Bencher) { |             fn bench_format(b: &mut Bencher) { | ||||||
|                 let val: $ty = Header::parse_header(&$value[]).unwrap(); |                 let val: $ty = Header::parse_header(&$value[..]).unwrap(); | ||||||
|                 let fmt = HeaderFormatter(&val); |                 let fmt = HeaderFormatter(&val); | ||||||
|                 b.iter(|| { |                 b.iter(|| { | ||||||
|                     format!("{}", fmt); |                     format!("{}", fmt); | ||||||
| @@ -102,7 +102,7 @@ macro_rules! impl_list_header( | |||||||
|  |  | ||||||
|         impl $crate::header::HeaderFormat for $from { |         impl $crate::header::HeaderFormat for $from { | ||||||
|             fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { |             fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||||||
|                 $crate::header::parsing::fmt_comma_delimited(fmt, &self[]) |                 $crate::header::parsing::fmt_comma_delimited(fmt, &self[..]) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ impl Header for Pragma { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Pragma> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<Pragma> { | ||||||
|         parsing::from_one_raw_str(raw).and_then(|s: String| { |         parsing::from_one_raw_str(raw).and_then(|s: String| { | ||||||
|             let slice = &s.to_ascii_lowercase()[]; |             let slice = &s.to_ascii_lowercase()[..]; | ||||||
|             match slice { |             match slice { | ||||||
|                 "" => None, |                 "" => None, | ||||||
|                 "no-cache" => Some(Pragma::NoCache), |                 "no-cache" => Some(Pragma::NoCache), | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ impl Header for SetCookie { | |||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<SetCookie> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<SetCookie> { | ||||||
|         let mut set_cookies = Vec::with_capacity(raw.len()); |         let mut set_cookies = Vec::with_capacity(raw.len()); | ||||||
|         for set_cookies_raw in raw.iter() { |         for set_cookies_raw in raw.iter() { | ||||||
|             match from_utf8(&set_cookies_raw[]) { |             match from_utf8(&set_cookies_raw[..]) { | ||||||
|                 Ok(s) if !s.is_empty() => { |                 Ok(s) if !s.is_empty() => { | ||||||
|                     match s.parse() { |                     match s.parse() { | ||||||
|                         Ok(cookie) => set_cookies.push(cookie), |                         Ok(cookie) => set_cookies.push(cookie), | ||||||
| @@ -76,7 +76,7 @@ impl SetCookie { | |||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
| fn test_parse() { | fn test_parse() { | ||||||
|     let h = Header::parse_header(&[b"foo=bar; HttpOnly".to_vec()][]); |     let h = Header::parse_header(&[b"foo=bar; HttpOnly".to_vec()][..]); | ||||||
|     let mut c1 = Cookie::new("foo".to_string(), "bar".to_string()); |     let mut c1 = Cookie::new("foo".to_string(), "bar".to_string()); | ||||||
|     c1.httponly = true; |     c1.httponly = true; | ||||||
|  |  | ||||||
| @@ -94,7 +94,7 @@ fn test_fmt() { | |||||||
|     let mut headers = Headers::new(); |     let mut headers = Headers::new(); | ||||||
|     headers.set(cookies); |     headers.set(cookies); | ||||||
|  |  | ||||||
|     assert_eq!(&headers.to_string()[], "Set-Cookie: foo=bar; HttpOnly; Path=/p\r\nSet-Cookie: baz=quux; Path=/\r\n"); |     assert_eq!(&headers.to_string()[..], "Set-Cookie: foo=bar; HttpOnly; Path=/p\r\nSet-Cookie: baz=quux; Path=/\r\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ impl Header for Upgrade { | |||||||
| impl HeaderFormat for Upgrade { | impl HeaderFormat for Upgrade { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         let Upgrade(ref parts) = *self; |         let Upgrade(ref parts) = *self; | ||||||
|         fmt_comma_delimited(fmt, &parts[]) |         fmt_comma_delimited(fmt, &parts[..]) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ impl Header for Vary { | |||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Vary> { |     fn parse_header(raw: &[Vec<u8>]) -> Option<Vary> { | ||||||
|         from_one_raw_str(raw).and_then(|s: String| { |         from_one_raw_str(raw).and_then(|s: String| { | ||||||
|             let slice = &s[]; |             let slice = &s[..]; | ||||||
|             match slice { |             match slice { | ||||||
|                 "" => None, |                 "" => None, | ||||||
|                 "*" => Some(Vary::Any), |                 "*" => Some(Vary::Any), | ||||||
| @@ -35,7 +35,7 @@ impl HeaderFormat for Vary { | |||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         match *self { |         match *self { | ||||||
|             Vary::Any => { write!(fmt, "*") } |             Vary::Any => { write!(fmt, "*") } | ||||||
|             Vary::Headers(ref fields) => { fmt_comma_delimited(fmt, &fields[]) } |             Vary::Headers(ref fields) => { fmt_comma_delimited(fmt, &fields[..]) } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,11 +9,10 @@ use std::borrow::Cow::{Borrowed, Owned}; | |||||||
| use std::fmt; | use std::fmt; | ||||||
| use std::raw::TraitObject; | use std::raw::TraitObject; | ||||||
| use std::str::from_utf8; | use std::str::from_utf8; | ||||||
| use std::string::CowString; |  | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::collections::hash_map::{Iter, Entry}; | use std::collections::hash_map::{Iter, Entry}; | ||||||
| use std::iter::FromIterator; | use std::iter::{FromIterator, IntoIterator}; | ||||||
| use std::borrow::IntoCow; | use std::borrow::{Cow, IntoCow}; | ||||||
| use std::{mem, raw}; | use std::{mem, raw}; | ||||||
|  |  | ||||||
| use uany::{UnsafeAnyExt}; | use uany::{UnsafeAnyExt}; | ||||||
| @@ -30,7 +29,7 @@ mod common; | |||||||
| mod shared; | mod shared; | ||||||
| pub mod parsing; | pub mod parsing; | ||||||
|  |  | ||||||
| type HeaderName = UniCase<CowString<'static>>; | type HeaderName = UniCase<Cow<'static, str>>; | ||||||
|  |  | ||||||
| /// A trait for any object that will represent a header field and value. | /// A trait for any object that will represent a header field and value. | ||||||
| /// | /// | ||||||
| @@ -139,7 +138,7 @@ impl Headers { | |||||||
|         loop { |         loop { | ||||||
|             match try!(http::read_header(rdr)) { |             match try!(http::read_header(rdr)) { | ||||||
|                 Some((name, value)) => { |                 Some((name, value)) => { | ||||||
|                     debug!("raw header: {:?}={:?}", name, &value[]); |                     debug!("raw header: {:?}={:?}", name, &value[..]); | ||||||
|                     count += (name.len() + value.len()) as u32; |                     count += (name.len() + value.len()) as u32; | ||||||
|                     if count > MAX_HEADERS_LENGTH { |                     if count > MAX_HEADERS_LENGTH { | ||||||
|                         debug!("Max header size reached, aborting"); |                         debug!("Max header size reached, aborting"); | ||||||
| @@ -183,14 +182,14 @@ impl Headers { | |||||||
|             .get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) |             .get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) }))) | ||||||
|             .and_then(|item| { |             .and_then(|item| { | ||||||
|                 if let Some(ref raw) = *item.raw { |                 if let Some(ref raw) = *item.raw { | ||||||
|                     return Some(&raw[]); |                     return Some(&raw[..]); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 let raw = vec![item.typed.as_ref().unwrap().to_string().into_bytes()]; |                 let raw = vec![item.typed.as_ref().unwrap().to_string().into_bytes()]; | ||||||
|                 item.raw.set(raw); |                 item.raw.set(raw); | ||||||
|  |  | ||||||
|                 let raw = item.raw.as_ref().unwrap(); |                 let raw = item.raw.as_ref().unwrap(); | ||||||
|                 Some(&raw[]) |                 Some(&raw[..]) | ||||||
|             }) |             }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -203,7 +202,7 @@ impl Headers { | |||||||
|     /// # let mut headers = Headers::new(); |     /// # let mut headers = Headers::new(); | ||||||
|     /// headers.set_raw("content-length", vec![b"5".to_vec()]); |     /// headers.set_raw("content-length", vec![b"5".to_vec()]); | ||||||
|     /// ``` |     /// ``` | ||||||
|     pub fn set_raw<K: IntoCow<'static, String, str>>(&mut self, name: K, value: Vec<Vec<u8>>) { |     pub fn set_raw<K: IntoCow<'static, str>>(&mut self, name: K, value: Vec<Vec<u8>>) { | ||||||
|         self.data.insert(UniCase(name.into_cow()), Item::new_raw(value)); |         self.data.insert(UniCase(name.into_cow()), Item::new_raw(value)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -351,7 +350,7 @@ impl<'a> fmt::Debug for HeaderView<'a> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> Extend<HeaderView<'a>> for Headers { | impl<'a> Extend<HeaderView<'a>> for Headers { | ||||||
|     fn extend<I: Iterator<Item=HeaderView<'a>>>(&mut self, iter: I) { |     fn extend<I: IntoIterator<Item=HeaderView<'a>>>(&mut self, iter: I) { | ||||||
|         for header in iter { |         for header in iter { | ||||||
|             self.data.insert((*header.0).clone(), (*header.1).clone()); |             self.data.insert((*header.0).clone(), (*header.1).clone()); | ||||||
|         } |         } | ||||||
| @@ -359,7 +358,7 @@ impl<'a> Extend<HeaderView<'a>> for Headers { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> FromIterator<HeaderView<'a>> for Headers { | impl<'a> FromIterator<HeaderView<'a>> for Headers { | ||||||
|     fn from_iter<I: Iterator<Item=HeaderView<'a>>>(iter: I) -> Headers { |     fn from_iter<I: IntoIterator<Item=HeaderView<'a>>>(iter: I) -> Headers { | ||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|         headers.extend(iter); |         headers.extend(iter); | ||||||
|         headers |         headers | ||||||
| @@ -451,7 +450,7 @@ fn get_or_parse_mut<H: Header + HeaderFormat>(item: &mut Item) -> Option<&mut It | |||||||
|  |  | ||||||
| fn parse<H: Header + HeaderFormat>(item: &Item) { | fn parse<H: Header + HeaderFormat>(item: &Item) { | ||||||
|     match *item.raw { |     match *item.raw { | ||||||
|         Some(ref raw) => match Header::parse_header(&raw[]) { |         Some(ref raw) => match Header::parse_header(&raw[..]) { | ||||||
|             Some::<H>(h) => item.typed.set(box h as Box<HeaderFormat + Send + Sync>), |             Some::<H>(h) => item.typed.set(box h as Box<HeaderFormat + Send + Sync>), | ||||||
|             None => () |             None => () | ||||||
|         }, |         }, | ||||||
| @@ -476,7 +475,7 @@ impl fmt::Display for Item { | |||||||
|             None => match *self.raw { |             None => match *self.raw { | ||||||
|                 Some(ref raw) => { |                 Some(ref raw) => { | ||||||
|                     for part in raw.iter() { |                     for part in raw.iter() { | ||||||
|                         match from_utf8(&part[]) { |                         match from_utf8(&part[..]) { | ||||||
|                             Ok(s) => try!(fmt.write_str(s)), |                             Ok(s) => try!(fmt.write_str(s)), | ||||||
|                             Err(e) => { |                             Err(e) => { | ||||||
|                                 error!("raw header value is not utf8. header={:?}, error={:?}", part, e); |                                 error!("raw header value is not utf8. header={:?}, error={:?}", part, e); | ||||||
| @@ -532,12 +531,9 @@ impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> { | |||||||
| mod tests { | mod tests { | ||||||
|     use std::old_io::MemReader; |     use std::old_io::MemReader; | ||||||
|     use std::fmt; |     use std::fmt; | ||||||
|     use std::borrow::Cow::Borrowed; |  | ||||||
|     use std::hash::{SipHasher, hash}; |  | ||||||
|     use mime::Mime; |     use mime::Mime; | ||||||
|     use mime::TopLevel::Text; |     use mime::TopLevel::Text; | ||||||
|     use mime::SubLevel::Plain; |     use mime::SubLevel::Plain; | ||||||
|     use unicase::UniCase; |  | ||||||
|     use super::{Headers, Header, HeaderFormat, ContentLength, ContentType, |     use super::{Headers, Header, HeaderFormat, ContentLength, ContentType, | ||||||
|                 Accept, Host, QualityItem}; |                 Accept, Host, QualityItem}; | ||||||
|  |  | ||||||
| @@ -547,15 +543,6 @@ mod tests { | |||||||
|         MemReader::new(s.as_bytes().to_vec()) |         MemReader::new(s.as_bytes().to_vec()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_case_insensitive() { |  | ||||||
|         let a = UniCase(Borrowed("foobar")); |  | ||||||
|         let b = UniCase(Borrowed("FOOBAR")); |  | ||||||
|  |  | ||||||
|         assert_eq!(a, b); |  | ||||||
|         assert_eq!(hash::<_, SipHasher>(&a), hash::<_, SipHasher>(&b)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_from_raw() { |     fn test_from_raw() { | ||||||
|         let headers = Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap(); |         let headers = Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap(); | ||||||
| @@ -595,7 +582,7 @@ mod tests { | |||||||
|                 return None; |                 return None; | ||||||
|             } |             } | ||||||
|             // we JUST checked that raw.len() == 1, so raw[0] WILL exist. |             // we JUST checked that raw.len() == 1, so raw[0] WILL exist. | ||||||
|             match from_utf8(unsafe { &raw[].get_unchecked(0)[] }) { |             match from_utf8(unsafe { &raw.get_unchecked(0)[..] }) { | ||||||
|                 Ok(s) => FromStr::from_str(s).ok(), |                 Ok(s) => FromStr::from_str(s).ok(), | ||||||
|                 Err(_) => None |                 Err(_) => None | ||||||
|             }.map(|u| CrazyLength(Some(false), u)) |             }.map(|u| CrazyLength(Some(false), u)) | ||||||
| @@ -671,7 +658,7 @@ mod tests { | |||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|         headers.set(ContentLength(10)); |         headers.set(ContentLength(10)); | ||||||
|         headers.set_raw("content-LENGTH", vec![b"20".to_vec()]); |         headers.set_raw("content-LENGTH", vec![b"20".to_vec()]); | ||||||
|         assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"20".to_vec()][]); |         assert_eq!(headers.get_raw("Content-length").unwrap(), &[b"20".to_vec()][..]); | ||||||
|         assert_eq!(headers.get(), Some(&ContentLength(20))); |         assert_eq!(headers.get(), Some(&ContentLength(20))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<T> { | |||||||
|         return None; |         return None; | ||||||
|     } |     } | ||||||
|     // we JUST checked that raw.len() == 1, so raw[0] WILL exist. |     // we JUST checked that raw.len() == 1, so raw[0] WILL exist. | ||||||
|     match str::from_utf8(&raw[0][]) { |     match str::from_utf8(&raw[0][..]) { | ||||||
|         Ok(s) => str::FromStr::from_str(s).ok(), |         Ok(s) => str::FromStr::from_str(s).ok(), | ||||||
|         Err(_) => None |         Err(_) => None | ||||||
|     } |     } | ||||||
| @@ -24,7 +24,7 @@ pub fn from_comma_delimited<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<Vec<T>> | |||||||
|         return None; |         return None; | ||||||
|     } |     } | ||||||
|     // we JUST checked that raw.len() == 1, so raw[0] WILL exist. |     // we JUST checked that raw.len() == 1, so raw[0] WILL exist. | ||||||
|     from_one_comma_delimited(&raw[0][]) |     from_one_comma_delimited(&raw[0][..]) | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Reads a comma-delimited raw string into a Vec. | /// Reads a comma-delimited raw string into a Vec. | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ impl FromStr for EntityTag { | |||||||
|     type Err = (); |     type Err = (); | ||||||
|     fn from_str(s: &str) -> Result<EntityTag, ()> { |     fn from_str(s: &str) -> Result<EntityTag, ()> { | ||||||
|         let length: usize = s.len(); |         let length: usize = s.len(); | ||||||
|         let slice = &s[]; |         let slice = &s[..]; | ||||||
|  |  | ||||||
|         // Early exits: |         // Early exits: | ||||||
|         // 1. The string is empty, or, |         // 1. The string is empty, or, | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ impl<T: fmt::Display> fmt::Display for QualityItem<T> { | |||||||
|             write!(f, "{}", self.item) |             write!(f, "{}", self.item) | ||||||
|         } else { |         } else { | ||||||
|             write!(f, "{}; q={}", self.item, |             write!(f, "{}; q={}", self.item, | ||||||
|                    format!("{:.3}", self.quality).trim_right_matches(&['0', '.'][])) |                    format!("{:.3}", self.quality).trim_right_matches(&['0', '.'][..])) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,11 +1,10 @@ | |||||||
| //! Pieces pertaining to the HTTP message protocol. | //! Pieces pertaining to the HTTP message protocol. | ||||||
| use std::borrow::Cow::{Borrowed, Owned}; | use std::borrow::Cow::{self, Borrowed, Owned}; | ||||||
| use std::borrow::IntoCow; | use std::borrow::IntoCow; | ||||||
| use std::cmp::min; | use std::cmp::min; | ||||||
| use std::old_io::{self, Reader, IoResult, BufWriter}; | use std::old_io::{self, Reader, IoResult, BufWriter}; | ||||||
| use std::num::from_u16; | use std::num::from_u16; | ||||||
| use std::str; | use std::str; | ||||||
| use std::string::CowString; |  | ||||||
|  |  | ||||||
| use url::Url; | use url::Url; | ||||||
| use url::ParseError as UrlError; | use url::ParseError as UrlError; | ||||||
| @@ -395,7 +394,7 @@ pub fn read_method<R: Reader>(stream: &mut R) -> HttpResult<method::Method> { | |||||||
|  |  | ||||||
|     debug!("maybe_method = {:?}", maybe_method); |     debug!("maybe_method = {:?}", maybe_method); | ||||||
|  |  | ||||||
|     match (maybe_method, &buf[]) { |     match (maybe_method, &buf[..]) { | ||||||
|         (Some(method), _) => Ok(method), |         (Some(method), _) => Ok(method), | ||||||
|         (None, ext) => { |         (None, ext) => { | ||||||
|             // We already checked that the buffer is ASCII |             // We already checked that the buffer is ASCII | ||||||
| @@ -587,7 +586,7 @@ pub type StatusLine = (HttpVersion, RawStatus); | |||||||
|  |  | ||||||
| /// The raw status code and reason-phrase. | /// The raw status code and reason-phrase. | ||||||
| #[derive(PartialEq, Debug)] | #[derive(PartialEq, Debug)] | ||||||
| pub struct RawStatus(pub u16, pub CowString<'static>); | pub struct RawStatus(pub u16, pub Cow<'static, str>); | ||||||
|  |  | ||||||
| impl Clone for RawStatus { | impl Clone for RawStatus { | ||||||
|     fn clone(&self) -> RawStatus { |     fn clone(&self) -> RawStatus { | ||||||
| @@ -664,7 +663,7 @@ pub fn read_status<R: Reader>(stream: &mut R) -> HttpResult<RawStatus> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let reason = match str::from_utf8(&buf[]) { |     let reason = match str::from_utf8(&buf[..]) { | ||||||
|         Ok(s) => s.trim(), |         Ok(s) => s.trim(), | ||||||
|         Err(_) => return Err(HttpStatusError) |         Err(_) => return Err(HttpStatusError) | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #![feature(core, collections, hash, io, os, path, std_misc, | #![feature(core, collections, io, old_io, os, old_path, | ||||||
|            slicing_syntax, box_syntax, unsafe_destructor)] |            std_misc, box_syntax, unsafe_destructor)] | ||||||
| #![deny(missing_docs)] | #![deny(missing_docs)] | ||||||
| #![cfg_attr(test, deny(warnings))] | #![cfg_attr(test, deny(warnings))] | ||||||
| #![cfg_attr(test, feature(alloc, test))] | #![cfg_attr(test, feature(alloc, test))] | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ pub trait NetworkAcceptor: Clone + Send { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// An iterator wrapper over a NetworkAcceptor. | /// An iterator wrapper over a NetworkAcceptor. | ||||||
| pub struct NetworkConnections<'a, N: NetworkAcceptor>(&'a mut N); | pub struct NetworkConnections<'a, N: NetworkAcceptor + 'a>(&'a mut N); | ||||||
|  |  | ||||||
| impl<'a, N: NetworkAcceptor> Iterator for NetworkConnections<'a, N> { | impl<'a, N: NetworkAcceptor> Iterator for NetworkConnections<'a, N> { | ||||||
|     type Item = IoResult<N::Stream>; |     type Item = IoResult<N::Stream>; | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| use std::thread::{Thread, JoinGuard}; | use std::thread::{self, JoinGuard}; | ||||||
| use std::sync::Arc; |  | ||||||
| use std::sync::mpsc; | use std::sync::mpsc; | ||||||
|  | use std::collections::VecMap; | ||||||
| use net::NetworkAcceptor; | use net::NetworkAcceptor; | ||||||
|  |  | ||||||
| pub struct AcceptorPool<A: NetworkAcceptor> { | pub struct AcceptorPool<A: NetworkAcceptor> { | ||||||
|     acceptor: A |     acceptor: A | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<A: NetworkAcceptor> AcceptorPool<A> { | impl<'a, A: NetworkAcceptor + 'a> AcceptorPool<A> { | ||||||
|     /// Create a thread pool to manage the acceptor. |     /// Create a thread pool to manage the acceptor. | ||||||
|     pub fn new(acceptor: A) -> AcceptorPool<A> { |     pub fn new(acceptor: A) -> AcceptorPool<A> { | ||||||
|         AcceptorPool { acceptor: acceptor } |         AcceptorPool { acceptor: acceptor } | ||||||
| @@ -18,34 +18,39 @@ impl<A: NetworkAcceptor> AcceptorPool<A> { | |||||||
|     /// ## Panics |     /// ## Panics | ||||||
|     /// |     /// | ||||||
|     /// Panics if threads == 0. |     /// Panics if threads == 0. | ||||||
|     pub fn accept<F: Fn(A::Stream) + Send + Sync>(self, |     pub fn accept<F>(self, work: F, threads: usize) | ||||||
|                                                   work: F, |         where F: Fn(A::Stream) + Send + Sync + 'a { | ||||||
|                                                   threads: usize) -> JoinGuard<'static, ()> { |  | ||||||
|         assert!(threads != 0, "Can't accept on 0 threads."); |         assert!(threads != 0, "Can't accept on 0 threads."); | ||||||
|  |  | ||||||
|         // Replace with &F when Send changes land. |  | ||||||
|         let work = Arc::new(work); |  | ||||||
|  |  | ||||||
|         let (super_tx, supervisor_rx) = mpsc::channel(); |         let (super_tx, supervisor_rx) = mpsc::channel(); | ||||||
|  |  | ||||||
|         let spawn = |         let counter = &mut 0; | ||||||
|             move || spawn_with(super_tx.clone(), work.clone(), self.acceptor.clone()); |         let work = &work; | ||||||
|  |         let mut spawn = move || { | ||||||
|  |             let id = *counter; | ||||||
|  |             let guard = spawn_with(super_tx.clone(), work, self.acceptor.clone(), id); | ||||||
|  |             *counter += 1; | ||||||
|  |             (id, guard) | ||||||
|  |         }; | ||||||
|  |  | ||||||
|         // Go |         // Go | ||||||
|         for _ in 0..threads { spawn() } |         let mut guards: VecMap<_> = (0..threads).map(|_| spawn()).collect(); | ||||||
|  |  | ||||||
|         // Spawn the supervisor |         for id in supervisor_rx.iter() { | ||||||
|         Thread::scoped(move || for () in supervisor_rx.iter() { spawn() }) |             guards.remove(&id); | ||||||
|  |             let (id, guard) = spawn(); | ||||||
|  |             guards.insert(id, guard); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| fn spawn_with<A, F>(supervisor: mpsc::Sender<()>, work: Arc<F>, mut acceptor: A) | fn spawn_with<'a, A, F>(supervisor: mpsc::Sender<usize>, work: &'a F, mut acceptor: A, id: usize) -> JoinGuard<'a, ()> | ||||||
| where A: NetworkAcceptor, | where A: NetworkAcceptor + 'a, | ||||||
|       F: Fn(<A as NetworkAcceptor>::Stream) + Send + Sync { |       F: Fn(<A as NetworkAcceptor>::Stream) + Send + Sync + 'a { | ||||||
|     use std::old_io::EndOfFile; |     use std::old_io::EndOfFile; | ||||||
|  |  | ||||||
|     Thread::spawn(move || { |     thread::scoped(move || { | ||||||
|         let sentinel = Sentinel::new(supervisor, ()); |         let sentinel = Sentinel::new(supervisor, id); | ||||||
|  |  | ||||||
|         loop { |         loop { | ||||||
|             match acceptor.accept() { |             match acceptor.accept() { | ||||||
| @@ -61,7 +66,7 @@ where A: NetworkAcceptor, | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }); |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
| struct Sentinel<T: Send> { | struct Sentinel<T: Send> { | ||||||
| @@ -83,7 +88,7 @@ impl<T: Send> Sentinel<T> { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[unsafe_destructor] | #[unsafe_destructor] | ||||||
| impl<T: Send> Drop for Sentinel<T> { | impl<T: Send + 'static> Drop for Sentinel<T> { | ||||||
|     fn drop(&mut self) { |     fn drop(&mut self) { | ||||||
|         // If we were cancelled, get out of here. |         // If we were cancelled, get out of here. | ||||||
|         if !self.active { return; } |         if !self.active { return; } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| use std::old_io::{Listener, BufferedReader, BufferedWriter}; | use std::old_io::{Listener, BufferedReader, BufferedWriter}; | ||||||
| use std::old_io::net::ip::{IpAddr, Port, SocketAddr}; | use std::old_io::net::ip::{IpAddr, Port, SocketAddr}; | ||||||
| use std::os; | use std::os; | ||||||
| use std::thread::JoinGuard; | use std::thread::{self, JoinGuard}; | ||||||
|  |  | ||||||
| pub use self::request::Request; | pub use self::request::Request; | ||||||
| pub use self::response::Response; | pub use self::response::Response; | ||||||
| @@ -56,7 +56,7 @@ impl Server<HttpListener> { | |||||||
|  |  | ||||||
| impl< | impl< | ||||||
| L: NetworkListener<Acceptor=A> + Send, | L: NetworkListener<Acceptor=A> + Send, | ||||||
| A: NetworkAcceptor<Stream=S> + Send, | A: NetworkAcceptor<Stream=S> + Send + 'static, | ||||||
| S: NetworkStream + Clone + Send> Server<L> { | S: NetworkStream + Clone + Send> Server<L> { | ||||||
|     /// Creates a new server that will handle `HttpStream`s. |     /// Creates a new server that will handle `HttpStream`s. | ||||||
|     pub fn with_listener(ip: IpAddr, port: Port, listener: L) -> Server<L> { |     pub fn with_listener(ip: IpAddr, port: Port, listener: L) -> Server<L> { | ||||||
| @@ -68,7 +68,7 @@ S: NetworkStream + Clone + Send> Server<L> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Binds to a socket, and starts handling connections using a task pool. |     /// Binds to a socket, and starts handling connections using a task pool. | ||||||
|     pub fn listen_threads<H: Handler>(mut self, handler: H, threads: usize) -> HttpResult<Listening<L::Acceptor>> { |     pub fn listen_threads<H: Handler + 'static>(mut self, handler: H, threads: usize) -> HttpResult<Listening<L::Acceptor>> { | ||||||
|         debug!("binding to {:?}:{:?}", self.ip, self.port); |         debug!("binding to {:?}:{:?}", self.ip, self.port); | ||||||
|         let acceptor = try!(self.listener.listen((self.ip, self.port))); |         let acceptor = try!(self.listener.listen((self.ip, self.port))); | ||||||
|         let socket = try!(acceptor.socket_name()); |         let socket = try!(acceptor.socket_name()); | ||||||
| @@ -77,15 +77,17 @@ S: NetworkStream + Clone + Send> Server<L> { | |||||||
|         let pool = AcceptorPool::new(acceptor.clone()); |         let pool = AcceptorPool::new(acceptor.clone()); | ||||||
|         let work = move |stream| handle_connection(stream, &handler); |         let work = move |stream| handle_connection(stream, &handler); | ||||||
|  |  | ||||||
|  |         let guard = thread::scoped(move || pool.accept(work, threads)); | ||||||
|  |  | ||||||
|         Ok(Listening { |         Ok(Listening { | ||||||
|             _guard: pool.accept(work, threads), |             _guard: guard, | ||||||
|             socket: socket, |             socket: socket, | ||||||
|             acceptor: acceptor |             acceptor: acceptor | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Binds to a socket and starts handling connections. |     /// Binds to a socket and starts handling connections. | ||||||
|     pub fn listen<H: Handler>(self, handler: H) -> HttpResult<Listening<L::Acceptor>> { |     pub fn listen<H: Handler + 'static>(self, handler: H) -> HttpResult<Listening<L::Acceptor>> { | ||||||
|         self.listen_threads(handler, os::num_cpus() * 5 / 4) |         self.listen_threads(handler, os::num_cpus() * 5 / 4) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| //! These are responses sent by a `hyper::Server` to clients, after | //! These are responses sent by a `hyper::Server` to clients, after | ||||||
| //! receiving a request. | //! receiving a request. | ||||||
| use std::old_io::IoResult; | use std::old_io::IoResult; | ||||||
|  | use std::marker::PhantomData; | ||||||
|  |  | ||||||
| use time::now_utc; | use time::now_utc; | ||||||
|  |  | ||||||
| @@ -22,7 +23,9 @@ pub struct Response<'a, W = Fresh> { | |||||||
|     // The status code for the request. |     // The status code for the request. | ||||||
|     status: status::StatusCode, |     status: status::StatusCode, | ||||||
|     // The outgoing headers on this response. |     // The outgoing headers on this response. | ||||||
|     headers: header::Headers |     headers: header::Headers, | ||||||
|  |  | ||||||
|  |     _marker: PhantomData<W> | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a, W> Response<'a, W> { | impl<'a, W> Response<'a, W> { | ||||||
| @@ -42,7 +45,8 @@ impl<'a, W> Response<'a, W> { | |||||||
|             status: status, |             status: status, | ||||||
|             version: version, |             version: version, | ||||||
|             body: body, |             body: body, | ||||||
|             headers: headers |             headers: headers, | ||||||
|  |             _marker: PhantomData, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -60,7 +64,8 @@ impl<'a> Response<'a, Fresh> { | |||||||
|             status: status::StatusCode::Ok, |             status: status::StatusCode::Ok, | ||||||
|             version: version::HttpVersion::Http11, |             version: version::HttpVersion::Http11, | ||||||
|             headers: header::Headers::new(), |             headers: header::Headers::new(), | ||||||
|             body: ThroughWriter(stream) |             body: ThroughWriter(stream), | ||||||
|  |             _marker: PhantomData, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -119,7 +124,8 @@ impl<'a> Response<'a, Fresh> { | |||||||
|             version: self.version, |             version: self.version, | ||||||
|             body: stream, |             body: stream, | ||||||
|             status: self.status, |             status: self.status, | ||||||
|             headers: self.headers |             headers: self.headers, | ||||||
|  |             _marker: PhantomData, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user