| @@ -4,7 +4,7 @@ extern crate hyper; | |||||||
|  |  | ||||||
| extern crate test; | extern crate test; | ||||||
|  |  | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::io::net::ip::Ipv4Addr; | use std::io::net::ip::Ipv4Addr; | ||||||
| use hyper::server::{Request, Response, Server}; | use hyper::server::{Request, Response, Server}; | ||||||
| use hyper::header::Headers; | use hyper::header::Headers; | ||||||
| @@ -46,7 +46,7 @@ fn bench_curl(b: &mut test::Bencher) { | |||||||
|     listening.close().unwrap(); |     listening.close().unwrap(); | ||||||
| } | } | ||||||
|  |  | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| struct Foo; | struct Foo; | ||||||
|  |  | ||||||
| impl hyper::header::Header for Foo { | impl hyper::header::Header for Foo { | ||||||
|   | |||||||
| @@ -4,8 +4,7 @@ extern crate hyper; | |||||||
|  |  | ||||||
| extern crate test; | extern crate test; | ||||||
|  |  | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::from_str; |  | ||||||
| use std::io::{IoResult, MemReader}; | use std::io::{IoResult, MemReader}; | ||||||
| use std::io::net::ip::SocketAddr; | use std::io::net::ip::SocketAddr; | ||||||
| use std::os; | use std::os; | ||||||
| @@ -65,7 +64,7 @@ fn bench_mock_curl(b: &mut test::Bencher) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| struct Foo; | struct Foo; | ||||||
|  |  | ||||||
| impl hyper::header::Header for Foo { | impl hyper::header::Header for Foo { | ||||||
| @@ -85,7 +84,7 @@ impl hyper::header::HeaderFormat for Foo { | |||||||
|  |  | ||||||
| impl net::NetworkStream for MockStream { | impl net::NetworkStream for MockStream { | ||||||
|     fn peer_name(&mut self) -> IoResult<SocketAddr> { |     fn peer_name(&mut self) -> IoResult<SocketAddr> { | ||||||
|         Ok(from_str("127.0.0.1:1337").unwrap()) |         Ok("127.0.0.1:1337".parse().unwrap()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -315,7 +315,7 @@ impl<'a> IntoUrl for &'a str { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// Behavior regarding how to handle redirects within a Client. | /// Behavior regarding how to handle redirects within a Client. | ||||||
| #[deriving(Copy)] | #[derive(Copy)] | ||||||
| pub enum RedirectPolicy { | pub enum RedirectPolicy { | ||||||
|     /// Don't follow any redirects. |     /// Don't follow any redirects. | ||||||
|     FollowNone, |     FollowNone, | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ use url::Url; | |||||||
| use method; | use method; | ||||||
| use method::Method::{Get, Post, Delete, Put, Patch, Head, Options}; | use method::Method::{Get, Post, Delete, Put, Patch, Head, Options}; | ||||||
| use header::Headers; | use header::Headers; | ||||||
| use header::common::{mod, Host}; | use header::common::{self, Host}; | ||||||
| use net::{NetworkStream, NetworkConnector, HttpConnector, Fresh, Streaming}; | use net::{NetworkStream, NetworkConnector, HttpConnector, Fresh, Streaming}; | ||||||
| use http::{HttpWriter, LINE_ENDING}; | use http::{HttpWriter, LINE_ENDING}; | ||||||
| use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter}; | use http::HttpWriter::{ThroughWriter, ChunkedWriter, SizedWriter, EmptyWriter}; | ||||||
| @@ -114,15 +114,14 @@ impl Request<Fresh> { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         debug!("writing head: {} {} {}", self.method, uri, self.version); |         debug!("writing head: {} {} {}", self.method, uri, self.version); | ||||||
|         try!(write!(&mut self.body, "{} {} {}", self.method, uri, self.version)); |         try!(write!(&mut self.body, "{} {} {}{}", | ||||||
|         try!(self.body.write(LINE_ENDING)); |                     self.method, uri, self.version, LINE_ENDING)); | ||||||
|  |  | ||||||
|  |  | ||||||
|         let stream = match self.method { |         let stream = match self.method { | ||||||
|             Get | Head => { |             Get | Head => { | ||||||
|                 debug!("headers [\n{}]", self.headers); |                 debug!("headers [\n{}]", self.headers); | ||||||
|                 try!(write!(&mut self.body, "{}", self.headers)); |                 try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING)); | ||||||
|                 try!(self.body.write(LINE_ENDING)); |  | ||||||
|                 EmptyWriter(self.body.unwrap()) |                 EmptyWriter(self.body.unwrap()) | ||||||
|             }, |             }, | ||||||
|             _ => { |             _ => { | ||||||
| @@ -155,8 +154,7 @@ impl Request<Fresh> { | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 debug!("headers [\n{}]", self.headers); |                 debug!("headers [\n{}]", self.headers); | ||||||
|                 try!(write!(&mut self.body, "{}", self.headers)); |                 try!(write!(&mut self.body, "{}{}", self.headers, LINE_ENDING)); | ||||||
|                 try!(self.body.write(LINE_ENDING)); |  | ||||||
|  |  | ||||||
|                 if chunked { |                 if chunked { | ||||||
|                     ChunkedWriter(self.body.unwrap()) |                     ChunkedWriter(self.body.unwrap()) | ||||||
| @@ -217,7 +215,8 @@ mod tests { | |||||||
|             Get, Url::parse("http://example.dom").unwrap(), &mut MockConnector |             Get, Url::parse("http://example.dom").unwrap(), &mut MockConnector | ||||||
|         ).unwrap(); |         ).unwrap(); | ||||||
|         let req = req.start().unwrap(); |         let req = req.start().unwrap(); | ||||||
|         let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap(); |         let stream = *req.body.end().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:")); | ||||||
| @@ -230,7 +229,8 @@ mod tests { | |||||||
|             Head, Url::parse("http://example.dom").unwrap(), &mut MockConnector |             Head, Url::parse("http://example.dom").unwrap(), &mut MockConnector | ||||||
|         ).unwrap(); |         ).unwrap(); | ||||||
|         let req = req.start().unwrap(); |         let req = req.start().unwrap(); | ||||||
|         let stream = *req.body.end().unwrap().into_inner().downcast::<MockStream>().unwrap(); |         let stream = *req.body.end().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:")); | ||||||
|   | |||||||
| @@ -120,7 +120,7 @@ mod tests { | |||||||
|             status_raw: RawStatus(200, Borrowed("OK")) |             status_raw: RawStatus(200, Borrowed("OK")) | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let b = res.into_inner().downcast::<MockStream>().unwrap(); |         let b = res.into_inner().downcast::<MockStream>().ok().unwrap(); | ||||||
|         assert_eq!(b, box MockStream::new()); |         assert_eq!(b, box MockStream::new()); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ use mime; | |||||||
| ///     qitem(Mime(Text, Html, vec![])), | ///     qitem(Mime(Text, Html, vec![])), | ||||||
| ///     qitem(Mime(Text, Xml, vec![])) ])); | ///     qitem(Mime(Text, Xml, vec![])) ])); | ||||||
| /// ``` | /// ``` | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Accept(pub Vec<shared::QualityItem<mime::Mime>>); | pub struct Accept(pub Vec<shared::QualityItem<mime::Mime>>); | ||||||
|  |  | ||||||
| deref!(Accept -> Vec<shared::QualityItem<mime::Mime>>); | deref!(Accept -> Vec<shared::QualityItem<mime::Mime>>); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ use header::shared; | |||||||
| /// | /// | ||||||
| /// The `Accept-Encoding` header can be used by clients to indicate what | /// The `Accept-Encoding` header can be used by clients to indicate what | ||||||
| /// response encodings they accept. | /// response encodings they accept. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>); | pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>); | ||||||
|  |  | ||||||
| deref!(AcceptEncoding -> Vec<shared::QualityItem<shared::Encoding>>); | deref!(AcceptEncoding -> Vec<shared::QualityItem<shared::Encoding>>); | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use method::Method; | use method::Method; | ||||||
| use std::fmt::{mod}; | use std::fmt::{self}; | ||||||
| use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | ||||||
|  |  | ||||||
| /// The `Allow` header. | /// The `Allow` header. | ||||||
| /// See also https://tools.ietf.org/html/rfc7231#section-7.4.1 | /// See also https://tools.ietf.org/html/rfc7231#section-7.4.1 | ||||||
|  |  | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Allow(pub Vec<Method>); | pub struct Allow(pub Vec<Method>); | ||||||
|  |  | ||||||
| deref!(Allow -> Vec<Method>); | deref!(Allow -> Vec<Method>); | ||||||
| @@ -31,7 +31,7 @@ impl HeaderFormat for Allow { | |||||||
| mod tests { | mod tests { | ||||||
|     use super::Allow; |     use super::Allow; | ||||||
|     use header::Header; |     use header::Header; | ||||||
|     use method::Method::{mod, Options, Get, Put, Post, Delete, Head, Trace, Connect, Patch, Extension}; |     use method::Method::{self, Options, Get, Put, Post, Delete, Head, Trace, Connect, Patch, Extension}; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_allow() { |     fn test_allow() { | ||||||
|   | |||||||
| @@ -1,19 +1,22 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::{FromStr, from_utf8}; | use std::str::{FromStr, from_utf8}; | ||||||
|  | use std::ops::{Deref, DerefMut}; | ||||||
| use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline}; | use serialize::base64::{ToBase64, FromBase64, Standard, Config, Newline}; | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
|  |  | ||||||
| /// The `Authorization` header field. | /// The `Authorization` header field. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Authorization<S: Scheme>(pub S); | pub struct Authorization<S: Scheme>(pub S); | ||||||
|  |  | ||||||
| impl<S: Scheme> Deref<S> for Authorization<S> { | impl<S: Scheme> Deref for Authorization<S> { | ||||||
|  |     type Target = S; | ||||||
|  |  | ||||||
|     fn deref<'a>(&'a self) -> &'a S { |     fn deref<'a>(&'a self) -> &'a S { | ||||||
|         &self.0 |         &self.0 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<S: Scheme> DerefMut<S> for Authorization<S> { | impl<S: Scheme> DerefMut for Authorization<S> { | ||||||
|     fn deref_mut<'a>(&'a mut self) -> &'a mut S { |     fn deref_mut<'a>(&'a mut self) -> &'a mut S { | ||||||
|         &mut self.0 |         &mut self.0 | ||||||
|     } |     } | ||||||
| @@ -72,7 +75,7 @@ impl Scheme for String { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// Credential holder for Basic Authentication | /// Credential holder for Basic Authentication | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Basic { | pub struct Basic { | ||||||
|     /// The username as a possibly empty string |     /// The username as a possibly empty string | ||||||
|     pub username: String, |     pub username: String, | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ use header::{Header, HeaderFormat}; | |||||||
| use header::shared::util::{from_one_comma_delimited, fmt_comma_delimited}; | use header::shared::util::{from_one_comma_delimited, fmt_comma_delimited}; | ||||||
|  |  | ||||||
| /// The Cache-Control header. | /// The Cache-Control header. | ||||||
| #[deriving(PartialEq, Clone, Show)] | #[derive(PartialEq, Clone, Show)] | ||||||
| pub struct CacheControl(pub Vec<CacheDirective>); | pub struct CacheControl(pub Vec<CacheDirective>); | ||||||
|  |  | ||||||
| deref!(CacheControl -> Vec<CacheDirective>); | deref!(CacheControl -> Vec<CacheDirective>); | ||||||
| @@ -34,7 +34,7 @@ impl HeaderFormat for CacheControl { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// CacheControl contains a list of these directives. | /// CacheControl contains a list of these directives. | ||||||
| #[deriving(PartialEq, Clone)] | #[derive(PartialEq, Clone)] | ||||||
| pub enum CacheDirective { | pub enum CacheDirective { | ||||||
|     /// "no-cache" |     /// "no-cache" | ||||||
|     NoCache, |     NoCache, | ||||||
|   | |||||||
| @@ -1,18 +1,18 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | ||||||
|  |  | ||||||
| pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader}; | pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader}; | ||||||
|  |  | ||||||
| /// The `Connection` header. | /// The `Connection` header. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Connection(pub Vec<ConnectionOption>); | pub struct Connection(pub Vec<ConnectionOption>); | ||||||
|  |  | ||||||
| deref!(Connection -> Vec<ConnectionOption>); | deref!(Connection -> Vec<ConnectionOption>); | ||||||
|  |  | ||||||
| /// Values that can be in the `Connection` header. | /// Values that can be in the `Connection` header. | ||||||
| #[deriving(Clone, PartialEq)] | #[derive(Clone, PartialEq)] | ||||||
| pub enum ConnectionOption { | pub enum ConnectionOption { | ||||||
|     /// The `keep-alive` connection value. |     /// The `keep-alive` connection value. | ||||||
|     KeepAlive, |     KeepAlive, | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
|  |  | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
| @@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| /// The `Content-Length` header. | /// The `Content-Length` header. | ||||||
| /// | /// | ||||||
| /// Simply a wrapper around a `uint`. | /// Simply a wrapper around a `uint`. | ||||||
| #[deriving(Copy, Clone, PartialEq, Show)] | #[derive(Copy, Clone, PartialEq, Show)] | ||||||
| pub struct ContentLength(pub uint); | pub struct ContentLength(pub uint); | ||||||
|  |  | ||||||
| deref!(ContentLength -> uint); | deref!(ContentLength -> uint); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
| use mime::Mime; | use mime::Mime; | ||||||
|  |  | ||||||
| @@ -7,7 +7,7 @@ use mime::Mime; | |||||||
| /// | /// | ||||||
| /// Used to describe the MIME type of message body. Can be used with both | /// Used to describe the MIME type of message body. Can be used with both | ||||||
| /// requests and responses. | /// requests and responses. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct ContentType(pub Mime); | pub struct ContentType(pub Mime); | ||||||
|  |  | ||||||
| deref!(ContentType -> Mime); | deref!(ContentType -> Mime); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::from_utf8; | use std::str::from_utf8; | ||||||
|  |  | ||||||
| use cookie::Cookie; | use cookie::Cookie; | ||||||
| @@ -13,7 +13,7 @@ use cookie::CookieJar; | |||||||
| /// | /// | ||||||
| /// > When the user agent generates an HTTP request, the user agent MUST NOT | /// > When the user agent generates an HTTP request, the user agent MUST NOT | ||||||
| /// > attach more than one Cookie header field. | /// > attach more than one Cookie header field. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Cookies(pub Vec<Cookie>); | pub struct Cookies(pub Vec<Cookie>); | ||||||
|  |  | ||||||
| //TODO: remove when fixed in libstd | //TODO: remove when fixed in libstd | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use time::Tm; | use time::Tm; | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| @@ -7,7 +7,7 @@ use header::shared::time::tm_from_str; | |||||||
|  |  | ||||||
| // Egh, replace as soon as something better than time::Tm exists. | // Egh, replace as soon as something better than time::Tm exists. | ||||||
| /// The `Date` header field. | /// The `Date` header field. | ||||||
| #[deriving(Copy, PartialEq, Clone)] | #[derive(Copy, PartialEq, Clone)] | ||||||
| pub struct Date(pub Tm); | pub struct Date(pub Tm); | ||||||
|  |  | ||||||
| deref!(Date -> Tm); | deref!(Date -> Tm); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod}; | use std::fmt::{self}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
|  |  | ||||||
| /// The `Etag` header. | /// The `Etag` header. | ||||||
| @@ -8,7 +8,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| /// Preceding the first double quote is an optional weakness indicator, | /// Preceding the first double quote is an optional weakness indicator, | ||||||
| /// which always looks like this: W/ | /// which always looks like this: W/ | ||||||
| /// See also: https://tools.ietf.org/html/rfc7232#section-2.3 | /// See also: https://tools.ietf.org/html/rfc7232#section-2.3 | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Etag { | pub struct Etag { | ||||||
|     /// Weakness indicator for the tag |     /// Weakness indicator for the tag | ||||||
|     pub weak: bool, |     pub weak: bool, | ||||||
| @@ -81,7 +81,7 @@ impl Header for Etag { | |||||||
| impl HeaderFormat for Etag { | impl HeaderFormat for Etag { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         if self.weak { |         if self.weak { | ||||||
|             try!(fmt.write(b"W/")); |             try!(fmt.write_str("W/")); | ||||||
|         } |         } | ||||||
|         write!(fmt, "\"{}\"", self.tag) |         write!(fmt, "\"{}\"", self.tag) | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use time::Tm; | use time::Tm; | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| @@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| use header::shared::time::tm_from_str; | use header::shared::time::tm_from_str; | ||||||
|  |  | ||||||
| /// The `Expires` header field. | /// The `Expires` header field. | ||||||
| #[deriving(Copy, PartialEq, Clone)] | #[derive(Copy, PartialEq, Clone)] | ||||||
| pub struct Expires(pub Tm); | pub struct Expires(pub Tm); | ||||||
|  |  | ||||||
| deref!(Expires -> Tm); | deref!(Expires -> Tm); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use Port; | use Port; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
|  |  | ||||||
| /// The `Host` header. | /// The `Host` header. | ||||||
| @@ -10,7 +10,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| /// | /// | ||||||
| /// Currently is just a String, but it should probably become a better type, | /// Currently is just a String, but it should probably become a better type, | ||||||
| /// like url::Host or something. | /// like url::Host or something. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Host { | pub struct Host { | ||||||
|     /// The hostname, such a example.domain. |     /// The hostname, such a example.domain. | ||||||
|     pub hostname: String, |     pub hostname: String, | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use time::Tm; | use time::Tm; | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| @@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| use header::shared::time::tm_from_str; | use header::shared::time::tm_from_str; | ||||||
|  |  | ||||||
| /// The `If-Modified-Since` header field. | /// The `If-Modified-Since` header field. | ||||||
| #[deriving(Copy, PartialEq, Clone)] | #[derive(Copy, PartialEq, Clone)] | ||||||
| pub struct IfModifiedSince(pub Tm); | pub struct IfModifiedSince(pub Tm); | ||||||
|  |  | ||||||
| deref!(IfModifiedSince -> Tm); | deref!(IfModifiedSince -> Tm); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use time::Tm; | use time::Tm; | ||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| @@ -6,7 +6,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| use header::shared::time::tm_from_str; | use header::shared::time::tm_from_str; | ||||||
|  |  | ||||||
| /// The `LastModified` header field. | /// The `LastModified` header field. | ||||||
| #[deriving(Copy, PartialEq, Clone)] | #[derive(Copy, PartialEq, Clone)] | ||||||
| pub struct LastModified(pub Tm); | pub struct LastModified(pub Tm); | ||||||
|  |  | ||||||
| deref!(LastModified -> Tm); | deref!(LastModified -> Tm); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
|  |  | ||||||
| /// The `Location` header. | /// The `Location` header. | ||||||
| @@ -13,7 +13,7 @@ use header::shared::util::from_one_raw_str; | |||||||
| /// | /// | ||||||
| /// Currently is just a String, but it should probably become a better type, | /// Currently is just a String, but it should probably become a better type, | ||||||
| /// like url::Url or something. | /// like url::Url or something. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Location(pub String); | pub struct Location(pub String); | ||||||
|  |  | ||||||
| deref!(Location -> String); | deref!(Location -> String); | ||||||
|   | |||||||
| @@ -60,13 +60,15 @@ macro_rules! bench_header( | |||||||
|  |  | ||||||
| macro_rules! deref( | macro_rules! deref( | ||||||
|     ($from:ty -> $to:ty) => { |     ($from:ty -> $to:ty) => { | ||||||
|         impl Deref<$to> for $from { |         impl ::std::ops::Deref for $from { | ||||||
|  |             type Target = $to; | ||||||
|  |  | ||||||
|             fn deref<'a>(&'a self) -> &'a $to { |             fn deref<'a>(&'a self) -> &'a $to { | ||||||
|                 &self.0 |                 &self.0 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         impl DerefMut<$to> for $from { |         impl ::std::ops::DerefMut for $from { | ||||||
|             fn deref_mut<'a>(&'a mut self) -> &'a mut $to { |             fn deref_mut<'a>(&'a mut self) -> &'a mut $to { | ||||||
|                 &mut self.0 |                 &mut self.0 | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
|  |  | ||||||
| /// The `Server` header field. | /// The `Server` header field. | ||||||
| /// | /// | ||||||
| /// They can contain any value, so it just wraps a `String`. | /// They can contain any value, so it just wraps a `String`. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Server(pub String); | pub struct Server(pub String); | ||||||
|  |  | ||||||
| deref!(Server -> String); | deref!(Server -> String); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::from_utf8; | use std::str::from_utf8; | ||||||
|  |  | ||||||
| use cookie::Cookie; | use cookie::Cookie; | ||||||
| @@ -10,7 +10,7 @@ use cookie::CookieJar; | |||||||
| /// Informally, the Set-Cookie response header contains the header name | /// Informally, the Set-Cookie response header contains the header name | ||||||
| /// "Set-Cookie" followed by a ":" and a cookie.  Each cookie begins with | /// "Set-Cookie" followed by a ":" and a cookie.  Each cookie begins with | ||||||
| /// a name-value-pair, followed by zero or more attribute-value pairs. | /// a name-value-pair, followed by zero or more attribute-value pairs. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct SetCookie(pub Vec<Cookie>); | pub struct SetCookie(pub Vec<Cookie>); | ||||||
|  |  | ||||||
| //TODO: remove when fixed in libstd | //TODO: remove when fixed in libstd | ||||||
| @@ -52,7 +52,7 @@ impl HeaderFormat for SetCookie { | |||||||
|     fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         for (i, cookie) in self.0.iter().enumerate() { |         for (i, cookie) in self.0.iter().enumerate() { | ||||||
|             if i != 0 { |             if i != 0 { | ||||||
|                 try!(f.write(b"\r\nSet-Cookie: ")); |                 try!(f.write_str("\r\nSet-Cookie: ")); | ||||||
|             } |             } | ||||||
|             try!(cookie.fmt(f)); |             try!(cookie.fmt(f)); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ use self::Encoding::{Chunked, Gzip, Deflate, Compress, EncodingExt}; | |||||||
| /// this header should include `chunked` as the last encoding. | /// this header should include `chunked` as the last encoding. | ||||||
| /// | /// | ||||||
| /// The implementation uses a vector of `Encoding` values. | /// The implementation uses a vector of `Encoding` values. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct TransferEncoding(pub Vec<Encoding>); | pub struct TransferEncoding(pub Vec<Encoding>); | ||||||
|  |  | ||||||
| deref!(TransferEncoding -> Vec<Encoding>); | deref!(TransferEncoding -> Vec<Encoding>); | ||||||
| @@ -33,7 +33,7 @@ deref!(TransferEncoding -> Vec<Encoding>); | |||||||
| /// # use hyper::header::Headers; | /// # use hyper::header::Headers; | ||||||
| /// # let mut headers = Headers::new(); | /// # let mut headers = Headers::new(); | ||||||
| /// headers.set(TransferEncoding(vec![Gzip, Chunked])); | /// headers.set(TransferEncoding(vec![Gzip, Chunked])); | ||||||
| #[deriving(Clone, PartialEq)] | #[derive(Clone, PartialEq)] | ||||||
| pub enum Encoding { | pub enum Encoding { | ||||||
|     /// The `chunked` encoding. |     /// The `chunked` encoding. | ||||||
|     Chunked, |     Chunked, | ||||||
|   | |||||||
| @@ -1,18 +1,18 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | use header::shared::util::{from_comma_delimited, fmt_comma_delimited}; | ||||||
|  |  | ||||||
| use self::Protocol::{WebSocket, ProtocolExt}; | use self::Protocol::{WebSocket, ProtocolExt}; | ||||||
|  |  | ||||||
| /// The `Upgrade` header. | /// The `Upgrade` header. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct Upgrade(pub Vec<Protocol>); | pub struct Upgrade(pub Vec<Protocol>); | ||||||
|  |  | ||||||
| deref!(Upgrade -> Vec<Protocol>); | deref!(Upgrade -> Vec<Protocol>); | ||||||
|  |  | ||||||
| /// Protocol values that can appear in the Upgrade header. | /// Protocol values that can appear in the Upgrade header. | ||||||
| #[deriving(Clone, PartialEq)] | #[derive(Clone, PartialEq)] | ||||||
| pub enum Protocol { | pub enum Protocol { | ||||||
|     /// The websocket protocol. |     /// The websocket protocol. | ||||||
|     WebSocket, |     WebSocket, | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| use header::{Header, HeaderFormat}; | use header::{Header, HeaderFormat}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use header::shared::util::from_one_raw_str; | use header::shared::util::from_one_raw_str; | ||||||
|  |  | ||||||
| /// The `User-Agent` header field. | /// The `User-Agent` header field. | ||||||
| /// | /// | ||||||
| /// They can contain any value, so it just wraps a `String`. | /// They can contain any value, so it just wraps a `String`. | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub struct UserAgent(pub String); | pub struct UserAgent(pub String); | ||||||
|  |  | ||||||
| deref!(UserAgent -> String); | deref!(UserAgent -> String); | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| use header::{Header, HeaderFormat, CaseInsensitive}; | use header::{Header, HeaderFormat, CaseInsensitive}; | ||||||
| use std::fmt::{mod}; | use std::fmt::{self}; | ||||||
| use header::shared::util::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str}; | use header::shared::util::{from_comma_delimited, fmt_comma_delimited, from_one_raw_str}; | ||||||
|  |  | ||||||
| /// The `Allow` header. | /// The `Allow` header. | ||||||
| /// See also https://tools.ietf.org/html/rfc7231#section-7.1.4 | /// See also https://tools.ietf.org/html/rfc7231#section-7.1.4 | ||||||
|  |  | ||||||
| #[deriving(Clone, PartialEq, Show)] | #[derive(Clone, PartialEq, Show)] | ||||||
| pub enum Vary { | pub enum Vary { | ||||||
|     /// This corresponds to '*'. |     /// This corresponds to '*'. | ||||||
|     Any, |     Any, | ||||||
|   | |||||||
| @@ -7,18 +7,21 @@ | |||||||
| use std::any::Any; | use std::any::Any; | ||||||
| use std::ascii::AsciiExt; | use std::ascii::AsciiExt; | ||||||
| use std::borrow::Cow::{Borrowed, Owned}; | use std::borrow::Cow::{Borrowed, Owned}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{self, Show}; | ||||||
| use std::intrinsics::TypeId; | use std::intrinsics::TypeId; | ||||||
| use std::raw::TraitObject; | use std::raw::TraitObject; | ||||||
| use std::str::{SendStr, FromStr}; | use std::str::{FromStr, 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::{hash, mem}; | use std::iter::FromIterator; | ||||||
|  | use std::borrow::IntoCow; | ||||||
|  | use std::{hash, mem, raw}; | ||||||
|  |  | ||||||
| use mucell::MuCell; | use mucell::MuCell; | ||||||
| use uany::{UncheckedAnyDowncast, UncheckedAnyMutDowncast}; | use uany::{UnsafeAnyExt}; | ||||||
|  |  | ||||||
| use http::{mod, LineEnding}; | use http::{self, LineEnding}; | ||||||
| use {HttpResult}; | use {HttpResult}; | ||||||
|  |  | ||||||
| pub use self::common::*; | pub use self::common::*; | ||||||
| @@ -81,19 +84,20 @@ impl HeaderFormat { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> UncheckedAnyDowncast<'a> for &'a HeaderFormat { | impl UnsafeAnyExt for HeaderFormat { | ||||||
|     #[inline] |     #[inline] | ||||||
|     unsafe fn downcast_ref_unchecked<T: 'static>(self) -> &'a T { |     unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T { | ||||||
|         let to: TraitObject = mem::transmute_copy(&self); |         mem::transmute(mem::transmute::<&HeaderFormat, raw::TraitObject>(self).data) | ||||||
|         mem::transmute(to.data) |  | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| impl<'a> UncheckedAnyMutDowncast<'a> for &'a mut HeaderFormat { |  | ||||||
|     #[inline] |     #[inline] | ||||||
|     unsafe fn downcast_mut_unchecked<T: 'static>(self) -> &'a mut T { |     unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { | ||||||
|         let to: TraitObject = mem::transmute_copy(&self); |         mem::transmute(mem::transmute::<&mut HeaderFormat, raw::TraitObject>(self).data) | ||||||
|         mem::transmute(to.data) |     } | ||||||
|  |  | ||||||
|  |     #[inline] | ||||||
|  |     unsafe fn downcast_unchecked<T: 'static>(self: Box<HeaderFormat>) -> Box<T> { | ||||||
|  |         mem::transmute(mem::transmute::<Box<HeaderFormat>, raw::TraitObject>(self).data) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -110,7 +114,7 @@ fn header_name<T: Header>() -> &'static str { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// A map of header fields on requests and responses. | /// A map of header fields on requests and responses. | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| pub struct Headers { | pub struct Headers { | ||||||
|     data: HashMap<CaseInsensitive, MuCell<Item>> |     data: HashMap<CaseInsensitive, MuCell<Item>> | ||||||
| } | } | ||||||
| @@ -132,8 +136,8 @@ impl Headers { | |||||||
|                 Some((name, value)) => { |                 Some((name, value)) => { | ||||||
|                     debug!("raw header: {}={}", name, value[]); |                     debug!("raw header: {}={}", name, value[]); | ||||||
|                     let name = CaseInsensitive(Owned(name)); |                     let name = CaseInsensitive(Owned(name)); | ||||||
|                     let mut item = match headers.data.entry(name) { |                     let mut item = match headers.data.entry(&name) { | ||||||
|                         Entry::Vacant(entry) => entry.set(MuCell::new(Item::raw(vec![]))), |                         Entry::Vacant(entry) => entry.insert(MuCell::new(Item::raw(vec![]))), | ||||||
|                         Entry::Occupied(entry) => entry.into_mut() |                         Entry::Occupied(entry) => entry.into_mut() | ||||||
|                     }; |                     }; | ||||||
|  |  | ||||||
| @@ -278,7 +282,9 @@ pub struct HeadersItems<'a> { | |||||||
|     inner: Iter<'a, CaseInsensitive, MuCell<Item>> |     inner: Iter<'a, CaseInsensitive, MuCell<Item>> | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> Iterator<HeaderView<'a>> for HeadersItems<'a> { | impl<'a> Iterator for HeadersItems<'a> { | ||||||
|  |     type Item = HeaderView<'a>; | ||||||
|  |  | ||||||
|     fn next(&mut self) -> Option<HeaderView<'a>> { |     fn next(&mut self) -> Option<HeaderView<'a>> { | ||||||
|         match self.inner.next() { |         match self.inner.next() { | ||||||
|             Some((k, v)) => Some(HeaderView(k, v)), |             Some((k, v)) => Some(HeaderView(k, v)), | ||||||
| @@ -327,7 +333,7 @@ impl<'a> fmt::Show for HeaderView<'a> { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> Extend<HeaderView<'a>> for Headers { | impl<'a> Extend<HeaderView<'a>> for Headers { | ||||||
|     fn extend<I: Iterator<HeaderView<'a>>>(&mut self, mut iter: I) { |     fn extend<I: Iterator<Item=HeaderView<'a>>>(&mut self, mut 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()); | ||||||
|         } |         } | ||||||
| @@ -335,14 +341,14 @@ 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<HeaderView<'a>>>(iter: I) -> Headers { |     fn from_iter<I: Iterator<Item=HeaderView<'a>>>(iter: I) -> Headers { | ||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|         headers.extend(iter); |         headers.extend(iter); | ||||||
|         headers |         headers | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| struct Item { | struct Item { | ||||||
|     raw: Option<Vec<Vec<u8>>>, |     raw: Option<Vec<Vec<u8>>>, | ||||||
|     typed: Option<Box<HeaderFormat + Send + Sync>> |     typed: Option<Box<HeaderFormat + Send + Sync>> | ||||||
| @@ -433,7 +439,13 @@ impl fmt::Show 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() { | ||||||
|                         try!(fmt.write(part.as_slice())); |                         match from_utf8(part[]) { | ||||||
|  |                             Ok(s) => try!(fmt.write_str(s)), | ||||||
|  |                             Err(e) => { | ||||||
|  |                                 error!("raw header value is not utf8. header={}, error={}", part[], e); | ||||||
|  |                                 return Err(fmt::Error); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                     Ok(()) |                     Ok(()) | ||||||
|                 }, |                 }, | ||||||
| @@ -450,8 +462,7 @@ impl fmt::Show for Box<HeaderFormat + Send + Sync> { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// Case-insensitive string. | /// Case-insensitive string. | ||||||
| //#[deriving(Clone)] | pub struct CaseInsensitive(CowString<'static>); | ||||||
| pub struct CaseInsensitive(SendStr); |  | ||||||
|  |  | ||||||
| impl FromStr for CaseInsensitive { | impl FromStr for CaseInsensitive { | ||||||
|     fn from_str(s: &str) -> Option<CaseInsensitive> { |     fn from_str(s: &str) -> Option<CaseInsensitive> { | ||||||
| @@ -562,7 +573,7 @@ mod tests { | |||||||
|         assert_eq!(accept, Some(Accept(vec![application_vendor, text_plain]))); |         assert_eq!(accept, Some(Accept(vec![application_vendor, text_plain]))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[deriving(Clone, Show)] |     #[derive(Clone, Show)] | ||||||
|     struct CrazyLength(Option<bool>, uint); |     struct CrazyLength(Option<bool>, uint); | ||||||
|  |  | ||||||
|     impl Header for CrazyLength { |     impl Header for CrazyLength { | ||||||
| @@ -641,6 +652,13 @@ mod tests { | |||||||
|         assert_eq!(s[], "Host: foo.bar\r\nContent-Length: 15\r\n"); |         assert_eq!(s[], "Host: foo.bar\r\nContent-Length: 15\r\n"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_headers_show_raw() { | ||||||
|  |         let headers = Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap(); | ||||||
|  |         let s = headers.to_string(); | ||||||
|  |         assert_eq!(s, "Content-Length: 10\r\n"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_set_raw() { |     fn test_set_raw() { | ||||||
|         let mut headers = Headers::new(); |         let mut headers = Headers::new(); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ pub use self::Encoding::{Chunked, Gzip, Deflate, Compress, Identity, EncodingExt | |||||||
|  |  | ||||||
| /// A value to represent an encoding used in `Transfer-Encoding` | /// A value to represent an encoding used in `Transfer-Encoding` | ||||||
| /// or `Accept-Encoding` header. | /// or `Accept-Encoding` header. | ||||||
| #[deriving(Clone, PartialEq)] | #[derive(Clone, PartialEq)] | ||||||
| pub enum Encoding { | pub enum Encoding { | ||||||
|     /// The `chunked` encoding. |     /// The `chunked` encoding. | ||||||
|     Chunked, |     Chunked, | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ use std::str; | |||||||
|  |  | ||||||
| /// Represents an item with a quality value as defined in | /// Represents an item with a quality value as defined in | ||||||
| /// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.1). | /// [RFC7231](https://tools.ietf.org/html/rfc7231#section-5.3.1). | ||||||
| #[deriving(Clone, PartialEq)] | #[derive(Clone, PartialEq)] | ||||||
| pub struct QualityItem<T> { | pub struct QualityItem<T> { | ||||||
|     /// The actual contents of the field. |     /// The actual contents of the field. | ||||||
|     pub item: T, |     pub item: T, | ||||||
| @@ -79,7 +79,7 @@ pub fn qitem<T>(item: T) -> QualityItem<T> { | |||||||
| #[test] | #[test] | ||||||
| fn test_quality_item_show1() { | fn test_quality_item_show1() { | ||||||
|     let x = qitem(Chunked); |     let x = qitem(Chunked); | ||||||
|     assert_eq!(format!("{}", x), "chunked; q=1.000"); |     assert_eq!(format!("{}", x), "chunked; q=1"); | ||||||
| } | } | ||||||
| #[test] | #[test] | ||||||
| fn test_quality_item_show2() { | fn test_quality_item_show2() { | ||||||
| @@ -93,7 +93,7 @@ fn test_quality_item_show3() { | |||||||
|         item: EncodingExt("identity".to_string()), |         item: EncodingExt("identity".to_string()), | ||||||
|         quality: 0.5f32, |         quality: 0.5f32, | ||||||
|     }; |     }; | ||||||
|     assert_eq!(format!("{}", x), "identity; q=0.500"); |     assert_eq!(format!("{}", x), "identity; q=0.5"); | ||||||
| } | } | ||||||
|  |  | ||||||
| #[test] | #[test] | ||||||
|   | |||||||
| @@ -9,7 +9,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(unsafe { raw[].unsafe_get(0)[] }) { |     match str::from_utf8(raw[0][]) { | ||||||
|         Ok(s) => str::FromStr::from_str(s), |         Ok(s) => str::FromStr::from_str(s), | ||||||
|         Err(_) => None |         Err(_) => None | ||||||
|     } |     } | ||||||
| @@ -22,7 +22,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(unsafe { raw.as_slice().unsafe_get(0).as_slice() }) |     from_one_comma_delimited(raw[0][]) | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Reads a comma-delimited raw string into a Vec. | /// Reads a comma-delimited raw string into a Vec. | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								src/http.rs
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/http.rs
									
									
									
									
									
								
							| @@ -1,10 +1,12 @@ | |||||||
| //! Pieces pertaining to the HTTP message protocol. | //! Pieces pertaining to the HTTP message protocol. | ||||||
| use std::borrow::Cow::{Borrowed, Owned}; | use std::borrow::Cow::{Borrowed, Owned}; | ||||||
|  | use std::borrow::IntoCow; | ||||||
| use std::cmp::min; | use std::cmp::min; | ||||||
| use std::fmt; | use std::fmt; | ||||||
| use std::io::{mod, Reader, IoResult, BufWriter}; | use std::io::{self, Reader, IoResult, BufWriter}; | ||||||
| use std::num::from_u16; | use std::num::from_u16; | ||||||
| use std::str::{mod, SendStr, FromStr}; | use std::str::{self, FromStr}; | ||||||
|  | use std::string::CowString; | ||||||
|  |  | ||||||
| use url::Url; | use url::Url; | ||||||
| use url::ParseError as UrlError; | use url::ParseError as UrlError; | ||||||
| @@ -107,7 +109,7 @@ impl<R: Reader> Reader for HttpReader<R> { | |||||||
|                 *opt_remaining = if rem > 0 { |                 *opt_remaining = if rem > 0 { | ||||||
|                     Some(rem) |                     Some(rem) | ||||||
|                 } else { |                 } else { | ||||||
|                     try!(eat(body, LINE_ENDING)); |                     try!(eat(body, LINE_ENDING.as_bytes())); | ||||||
|                     None |                     None | ||||||
|                 }; |                 }; | ||||||
|                 Ok(count) |                 Ok(count) | ||||||
| @@ -236,9 +238,9 @@ impl<W: Writer> Writer for HttpWriter<W> { | |||||||
|             ChunkedWriter(ref mut w) => { |             ChunkedWriter(ref mut w) => { | ||||||
|                 let chunk_size = msg.len(); |                 let chunk_size = msg.len(); | ||||||
|                 debug!("chunked write, size = {}", chunk_size); |                 debug!("chunked write, size = {}", chunk_size); | ||||||
|                 try!(write!(w, "{:X}{}{}", chunk_size, CR as char, LF as char)); |                 try!(write!(w, "{:X}{}", chunk_size, LINE_ENDING)); | ||||||
|                 try!(w.write(msg)); |                 try!(w.write(msg)); | ||||||
|                 w.write(LINE_ENDING) |                 w.write_str(LINE_ENDING) | ||||||
|             }, |             }, | ||||||
|             SizedWriter(ref mut w, ref mut remaining) => { |             SizedWriter(ref mut w, ref mut remaining) => { | ||||||
|                 let len = msg.len(); |                 let len = msg.len(); | ||||||
| @@ -282,7 +284,7 @@ pub const SP: u8 = b' '; | |||||||
| pub const CR: u8 = b'\r'; | pub const CR: u8 = b'\r'; | ||||||
| pub const LF: u8 = b'\n'; | pub const LF: u8 = b'\n'; | ||||||
| pub const STAR: u8 = b'*'; | pub const STAR: u8 = b'*'; | ||||||
| pub const LINE_ENDING: &'static [u8] = &[CR, LF]; | pub const LINE_ENDING: &'static str = "\r\n"; | ||||||
|  |  | ||||||
| /// A `Show`able struct to easily write line endings to a formatter. | /// A `Show`able struct to easily write line endings to a formatter. | ||||||
| pub struct LineEnding; | pub struct LineEnding; | ||||||
| @@ -291,13 +293,7 @@ impl Copy for LineEnding {} | |||||||
|  |  | ||||||
| impl fmt::Show for LineEnding { | impl fmt::Show for LineEnding { | ||||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         fmt.write(LINE_ENDING) |         fmt.write_str(LINE_ENDING) | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl AsSlice<u8> for LineEnding { |  | ||||||
|     fn as_slice(&self) -> &[u8] { |  | ||||||
|         LINE_ENDING |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -582,8 +578,8 @@ pub fn read_request_line<R: Reader>(stream: &mut R) -> HttpResult<RequestLine> { | |||||||
| pub type StatusLine = (HttpVersion, RawStatus); | pub type StatusLine = (HttpVersion, RawStatus); | ||||||
|  |  | ||||||
| /// The raw status code and reason-phrase. | /// The raw status code and reason-phrase. | ||||||
| #[deriving(PartialEq, Show)] | #[derive(PartialEq, Show)] | ||||||
| pub struct RawStatus(pub u16, pub SendStr); | pub struct RawStatus(pub u16, pub CowString<'static>); | ||||||
|  |  | ||||||
| impl Clone for RawStatus { | impl Clone for RawStatus { | ||||||
|     fn clone(&self) -> RawStatus { |     fn clone(&self) -> RawStatus { | ||||||
| @@ -693,7 +689,7 @@ fn expect(r: IoResult<u8>, expected: u8) -> HttpResult<()> { | |||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use std::io::{mod, MemReader, MemWriter}; |     use std::io::{self, MemReader, MemWriter}; | ||||||
|     use std::borrow::Cow::{Borrowed, Owned}; |     use std::borrow::Cow::{Borrowed, Owned}; | ||||||
|     use test::Bencher; |     use test::Bencher; | ||||||
|     use uri::RequestUri; |     use uri::RequestUri; | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -1,4 +1,6 @@ | |||||||
| #![feature(macro_rules, phase, default_type_params, slicing_syntax, globs)] | #![feature(macro_rules, phase, default_type_params, | ||||||
|  |            slicing_syntax, globs, associated_types, | ||||||
|  |            old_orphan_check)] | ||||||
| #![deny(missing_docs)] | #![deny(missing_docs)] | ||||||
| #![deny(warnings)] | #![deny(warnings)] | ||||||
| #![experimental] | #![experimental] | ||||||
| @@ -143,12 +145,9 @@ pub use method::Method::{Get, Head, Post, Delete}; | |||||||
| pub use status::StatusCode::{Ok, BadRequest, NotFound}; | pub use status::StatusCode::{Ok, BadRequest, NotFound}; | ||||||
| pub use server::Server; | pub use server::Server; | ||||||
|  |  | ||||||
| use std::fmt; |  | ||||||
| use std::error::{Error, FromError}; | use std::error::{Error, FromError}; | ||||||
| use std::io::IoError; | use std::io::IoError; | ||||||
|  |  | ||||||
| use std::rt::backtrace; |  | ||||||
|  |  | ||||||
| use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError, | use self::HttpError::{HttpMethodError, HttpUriError, HttpVersionError, | ||||||
|                       HttpHeaderError, HttpStatusError, HttpIoError}; |                       HttpHeaderError, HttpStatusError, HttpIoError}; | ||||||
|  |  | ||||||
| @@ -158,22 +157,6 @@ macro_rules! todo( | |||||||
|     }) |     }) | ||||||
| ); | ); | ||||||
|  |  | ||||||
| #[allow(dead_code)] |  | ||||||
| struct Trace; |  | ||||||
|  |  | ||||||
| impl fmt::Show for Trace { |  | ||||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let _ = backtrace::write(fmt); |  | ||||||
|         Result::Ok(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| macro_rules! trace( |  | ||||||
|     ($($arg:tt)*) => (if cfg!(not(ndebug)) { |  | ||||||
|         log!(5, "{}\n{}", format_args!($($arg)*), ::Trace) |  | ||||||
|     }) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| macro_rules! inspect( | macro_rules! inspect( | ||||||
|     ($name:expr, $value:expr) => ({ |     ($name:expr, $value:expr) => ({ | ||||||
|         let v = $value; |         let v = $value; | ||||||
| @@ -207,7 +190,7 @@ mod mimewrapper { | |||||||
| pub type HttpResult<T> = Result<T, HttpError>; | pub type HttpResult<T> = Result<T, HttpError>; | ||||||
|  |  | ||||||
| /// A set of errors that can occur parsing HTTP streams. | /// A set of errors that can occur parsing HTTP streams. | ||||||
| #[deriving(Show, PartialEq, Clone)] | #[derive(Show, PartialEq, Clone)] | ||||||
| pub enum HttpError { | pub enum HttpError { | ||||||
|     /// An invalid `Method`, such as `GE,T`. |     /// An invalid `Method`, such as `GE,T`. | ||||||
|     HttpMethodError, |     HttpMethodError, | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ use self::Method::{Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch, | |||||||
| /// | /// | ||||||
| /// It may make sense to grow this to include all variants currently | /// It may make sense to grow this to include all variants currently | ||||||
| /// registered with IANA, if they are at all common to use. | /// registered with IANA, if they are at all common to use. | ||||||
| #[deriving(Clone, PartialEq, Eq, Hash)] | #[derive(Clone, PartialEq, Eq, Hash)] | ||||||
| pub enum Method { | pub enum Method { | ||||||
|     /// OPTIONS |     /// OPTIONS | ||||||
|     Options, |     Options, | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ macro_rules! mock_connector ( | |||||||
|  |  | ||||||
|                 let key = format!("{}://{}", scheme, host); |                 let key = format!("{}://{}", scheme, host); | ||||||
|                 // ignore port for now |                 // ignore port for now | ||||||
|                 match map.find(&&*key) { |                 match map.get(&&*key) { | ||||||
|                     Some(res) => Ok(::mock::MockStream { |                     Some(res) => Ok(::mock::MockStream { | ||||||
|                         write: ::std::io::MemWriter::new(), |                         write: ::std::io::MemWriter::new(), | ||||||
|                         read: ::std::io::MemReader::new(res.to_string().into_bytes()) |                         read: ::std::io::MemReader::new(res.to_string().into_bytes()) | ||||||
|   | |||||||
							
								
								
									
										69
									
								
								src/net.rs
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								src/net.rs
									
									
									
									
									
								
							| @@ -1,16 +1,15 @@ | |||||||
| //! A collection of traits abstracting over Listeners and Streams. | //! A collection of traits abstracting over Listeners and Streams. | ||||||
| use std::any::{Any, AnyRefExt}; | use std::any::Any; | ||||||
| use std::boxed::BoxAny; |  | ||||||
| use std::fmt; | use std::fmt; | ||||||
| use std::intrinsics::TypeId; | use std::intrinsics::TypeId; | ||||||
| use std::io::{IoResult, IoError, ConnectionAborted, InvalidInput, OtherIoError, | use std::io::{IoResult, IoError, ConnectionAborted, InvalidInput, OtherIoError, | ||||||
|               Stream, Listener, Acceptor}; |               Stream, Listener, Acceptor}; | ||||||
| use std::io::net::ip::{SocketAddr, ToSocketAddr, Port}; | use std::io::net::ip::{SocketAddr, ToSocketAddr, Port}; | ||||||
| use std::io::net::tcp::{TcpStream, TcpListener, TcpAcceptor}; | use std::io::net::tcp::{TcpStream, TcpListener, TcpAcceptor}; | ||||||
| use std::mem::{mod, transmute, transmute_copy}; | use std::mem; | ||||||
| use std::raw::{mod, TraitObject}; | use std::raw::{self, TraitObject}; | ||||||
|  |  | ||||||
| use uany::UncheckedBoxAnyDowncast; | use uany::UnsafeAnyExt; | ||||||
| use openssl::ssl::{Ssl, SslStream, SslContext, VerifyCallback}; | use openssl::ssl::{Ssl, SslStream, SslContext, VerifyCallback}; | ||||||
| use openssl::ssl::SslVerifyMode::SslVerifyPeer; | use openssl::ssl::SslVerifyMode::SslVerifyPeer; | ||||||
| use openssl::ssl::SslMethod::Sslv23; | use openssl::ssl::SslMethod::Sslv23; | ||||||
| @@ -105,38 +104,54 @@ impl<'a> Writer for &'a mut NetworkStream { | |||||||
|     fn flush(&mut self) -> IoResult<()> { (**self).flush() } |     fn flush(&mut self) -> IoResult<()> { (**self).flush() } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl UncheckedBoxAnyDowncast for Box<NetworkStream + Send> { | impl UnsafeAnyExt for NetworkStream { | ||||||
|     unsafe fn downcast_unchecked<T: 'static>(self) -> Box<T>  { |     unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T { | ||||||
|         let to = *mem::transmute::<&Box<NetworkStream + Send>, &raw::TraitObject>(&self); |         mem::transmute(mem::transmute::<&NetworkStream, | ||||||
|         // Prevent double-free. |                                         raw::TraitObject>(self).data) | ||||||
|         mem::forget(self); |     } | ||||||
|         mem::transmute(to.data) |  | ||||||
|  |     unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T { | ||||||
|  |         mem::transmute(mem::transmute::<&mut NetworkStream, | ||||||
|  |                                         raw::TraitObject>(self).data) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     unsafe fn downcast_unchecked<T: 'static>(self: Box<NetworkStream>) -> Box<T>  { | ||||||
|  |         mem::transmute(mem::transmute::<Box<NetworkStream>, | ||||||
|  |                                         raw::TraitObject>(self).data) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'a> AnyRefExt<'a> for &'a (NetworkStream + 'static) { | impl NetworkStream { | ||||||
|  |     /// Is the underlying type in this trait object a T? | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn is<T: 'static>(self) -> bool { |     pub fn is<T: 'static>(&self) -> bool { | ||||||
|         self.get_type_id() == TypeId::of::<T>() |         self.get_type_id() == TypeId::of::<T>() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// If the underlying type is T, get a reference to the contained data. | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn downcast_ref<T: 'static>(self) -> Option<&'a T> { |     pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { | ||||||
|         if self.is::<T>() { |         if self.is::<T>() { | ||||||
|             unsafe { |             Some(unsafe { self.downcast_ref_unchecked() }) | ||||||
|                 // Get the raw representation of the trait object |  | ||||||
|                 let to: TraitObject = transmute_copy(&self); |  | ||||||
|                 // Extract the data pointer |  | ||||||
|                 Some(transmute(to.data)) |  | ||||||
|             } |  | ||||||
|         } else { |         } else { | ||||||
|             None |             None | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } |  | ||||||
|  |  | ||||||
| impl BoxAny for Box<NetworkStream + Send> { |     /// If the underlying type is T, get a mutable reference to the contained | ||||||
|     fn downcast<T: 'static>(self) -> Result<Box<T>, Box<NetworkStream + Send>> { |     /// data. | ||||||
|  |     #[inline] | ||||||
|  |     pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> { | ||||||
|  |         if self.is::<T>() { | ||||||
|  |             Some(unsafe { self.downcast_mut_unchecked() }) | ||||||
|  |         } else { | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// If the underlying type is T, extract it. | ||||||
|  |     pub fn downcast<T: 'static>(self: Box<NetworkStream>) | ||||||
|  |             -> Result<Box<T>, Box<NetworkStream>> { | ||||||
|         if self.is::<T>() { |         if self.is::<T>() { | ||||||
|             Ok(unsafe { self.downcast_unchecked() }) |             Ok(unsafe { self.downcast_unchecked() }) | ||||||
|         } else { |         } else { | ||||||
| @@ -174,7 +189,7 @@ impl NetworkListener<HttpStream, HttpAcceptor> for HttpListener { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// A `NetworkAcceptor` for `HttpStream`s. | /// A `NetworkAcceptor` for `HttpStream`s. | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| pub struct HttpAcceptor { | pub struct HttpAcceptor { | ||||||
|     inner: TcpAcceptor |     inner: TcpAcceptor | ||||||
| } | } | ||||||
| @@ -194,7 +209,7 @@ impl NetworkAcceptor<HttpStream> for HttpAcceptor { | |||||||
| } | } | ||||||
|  |  | ||||||
| /// A wrapper around a TcpStream. | /// A wrapper around a TcpStream. | ||||||
| #[deriving(Clone)] | #[derive(Clone)] | ||||||
| pub enum HttpStream { | pub enum HttpStream { | ||||||
|     /// A stream over the HTTP protocol. |     /// A stream over the HTTP protocol. | ||||||
|     Http(TcpStream), |     Http(TcpStream), | ||||||
| @@ -293,7 +308,7 @@ fn lift_ssl_error(ssl: SslError) -> IoError { | |||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use std::boxed::BoxAny; |     use std::boxed::BoxAny; | ||||||
|     use uany::UncheckedBoxAnyDowncast; |     use uany::UnsafeAnyExt; | ||||||
|  |  | ||||||
|     use mock::MockStream; |     use mock::MockStream; | ||||||
|     use super::NetworkStream; |     use super::NetworkStream; | ||||||
| @@ -302,7 +317,7 @@ mod tests { | |||||||
|     fn test_downcast_box_stream() { |     fn test_downcast_box_stream() { | ||||||
|         let stream = box MockStream::new() as Box<NetworkStream + Send>; |         let stream = box MockStream::new() as Box<NetworkStream + Send>; | ||||||
|  |  | ||||||
|         let mock = stream.downcast::<MockStream>().unwrap(); |         let mock = stream.downcast::<MockStream>().ok().unwrap(); | ||||||
|         assert_eq!(mock, box MockStream::new()); |         assert_eq!(mock, box MockStream::new()); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ use std::io::net::ip::SocketAddr; | |||||||
|  |  | ||||||
| use {HttpResult}; | use {HttpResult}; | ||||||
| use version::{HttpVersion}; | use version::{HttpVersion}; | ||||||
| use method::Method::{mod, Get, Head}; | use method::Method::{self, Get, Head}; | ||||||
| use header::Headers; | use header::Headers; | ||||||
| use header::common::{ContentLength, TransferEncoding}; | use header::common::{ContentLength, TransferEncoding}; | ||||||
| use http::{read_request_line}; | use http::{read_request_line}; | ||||||
| @@ -78,9 +78,11 @@ mod tests { | |||||||
|     use mock::MockStream; |     use mock::MockStream; | ||||||
|     use super::Request; |     use super::Request; | ||||||
|  |  | ||||||
|     macro_rules! sock( |     use std::io::net::ip::SocketAddr; | ||||||
|         ($s:expr) => (::std::str::from_str::<::std::io::net::ip::SocketAddr>($s).unwrap()) |  | ||||||
|     ); |     fn sock(s: &str) -> SocketAddr { | ||||||
|  |         s.parse().unwrap() | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_get_empty_body() { |     fn test_get_empty_body() { | ||||||
| @@ -91,7 +93,7 @@ mod tests { | |||||||
|             I'm a bad request.\r\n\ |             I'm a bad request.\r\n\ | ||||||
|         "); |         "); | ||||||
|  |  | ||||||
|         let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); |         let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); | ||||||
|         assert_eq!(req.read_to_string(), Ok("".to_string())); |         assert_eq!(req.read_to_string(), Ok("".to_string())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -104,7 +106,7 @@ mod tests { | |||||||
|             I'm a bad request.\r\n\ |             I'm a bad request.\r\n\ | ||||||
|         "); |         "); | ||||||
|  |  | ||||||
|         let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); |         let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); | ||||||
|         assert_eq!(req.read_to_string(), Ok("".to_string())); |         assert_eq!(req.read_to_string(), Ok("".to_string())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -117,7 +119,7 @@ mod tests { | |||||||
|             I'm a bad request.\r\n\ |             I'm a bad request.\r\n\ | ||||||
|         "); |         "); | ||||||
|  |  | ||||||
|         let mut req = Request::new(&mut stream, sock!("127.0.0.1:80")).unwrap(); |         let mut req = Request::new(&mut stream, sock("127.0.0.1:80")).unwrap(); | ||||||
|         assert_eq!(req.read_to_string(), Ok("".to_string())); |         assert_eq!(req.read_to_string(), Ok("".to_string())); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -107,7 +107,7 @@ impl<'a> Response<'a, Fresh> { | |||||||
|         debug!("headers [\n{}]", self.headers); |         debug!("headers [\n{}]", self.headers); | ||||||
|         try!(write!(&mut self.body, "{}", self.headers)); |         try!(write!(&mut self.body, "{}", self.headers)); | ||||||
|  |  | ||||||
|         try!(self.body.write(LINE_ENDING)); |         try!(self.body.write_str(LINE_ENDING)); | ||||||
|  |  | ||||||
|         let stream = if chunked { |         let stream = if chunked { | ||||||
|             ChunkedWriter(self.body.unwrap()) |             ChunkedWriter(self.body.unwrap()) | ||||||
|   | |||||||
| @@ -1,7 +1,10 @@ | |||||||
| //! Status Codes | //! Status Codes | ||||||
| use std::fmt; | use std::fmt; | ||||||
|  | use std::num::{FromPrimitive, ToPrimitive}; | ||||||
| use std::mem::transmute; | use std::mem::transmute; | ||||||
|  |  | ||||||
|  | use std::cmp::Ordering::{self, Less, Equal, Greater}; | ||||||
|  |  | ||||||
| // shamelessly lifted from Teepee. I tried a few schemes, this really | // shamelessly lifted from Teepee. I tried a few schemes, this really | ||||||
| // does seem like the best. | // does seem like the best. | ||||||
|  |  | ||||||
| @@ -1038,7 +1041,7 @@ impl StatusCode { | |||||||
|     /// other times. |     /// other times. | ||||||
|     /// |     /// | ||||||
|     /// The reason phrase is defined as being exclusively for human readers. You should avoid |     /// The reason phrase is defined as being exclusively for human readers. You should avoid | ||||||
|     /// deriving any meaning from it at all costs. |     /// derive any meaning from it at all costs. | ||||||
|     /// |     /// | ||||||
|     /// Bear in mind also that in HTTP/2.0 the reason phrase is abolished from transmission, and so |     /// Bear in mind also that in HTTP/2.0 the reason phrase is abolished from transmission, and so | ||||||
|     /// this canonical reason phrase really is the only reason phrase you’ll find. |     /// this canonical reason phrase really is the only reason phrase you’ll find. | ||||||
| @@ -1600,7 +1603,7 @@ impl PartialEq for StatusCode { | |||||||
|  |  | ||||||
| impl Eq for StatusCode {} | impl Eq for StatusCode {} | ||||||
|  |  | ||||||
| // Ditto (though #[deriving(Clone)] only takes about 0.4 seconds). | // Ditto (though #[derive(Clone)] only takes about 0.4 seconds). | ||||||
| impl Clone for StatusCode { | impl Clone for StatusCode { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn clone(&self) -> StatusCode { |     fn clone(&self) -> StatusCode { | ||||||
| @@ -1686,7 +1689,7 @@ impl ToPrimitive for StatusCode { | |||||||
| /// to get the appropriate *category* of status. | /// to get the appropriate *category* of status. | ||||||
| /// | /// | ||||||
| /// For HTTP/2.0, the 1xx Informational class is invalid. | /// For HTTP/2.0, the 1xx Informational class is invalid. | ||||||
| #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] | ||||||
| pub enum StatusClass { | pub enum StatusClass { | ||||||
|     /// 1xx: Informational - Request received, continuing process |     /// 1xx: Informational - Request received, continuing process | ||||||
|     Informational = 100, |     Informational = 100, | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ use url::Url; | |||||||
| /// >                / authority-form | /// >                / authority-form | ||||||
| /// >                / asterisk-form | /// >                / asterisk-form | ||||||
| /// > ``` | /// > ``` | ||||||
| #[deriving(Show, PartialEq, Clone)] | #[derive(Show, PartialEq, Clone)] | ||||||
| pub enum RequestUri { | pub enum RequestUri { | ||||||
|     /// The most common request target, an absolute path and optional query. |     /// The most common request target, an absolute path and optional query. | ||||||
|     /// |     /// | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ use std::fmt; | |||||||
| use self::HttpVersion::{Http09, Http10, Http11, Http20}; | use self::HttpVersion::{Http09, Http10, Http11, Http20}; | ||||||
|  |  | ||||||
| /// Represents a version of the HTTP spec. | /// Represents a version of the HTTP spec. | ||||||
| #[deriving(PartialEq, PartialOrd, Copy)] | #[derive(PartialEq, PartialOrd, Copy)] | ||||||
| pub enum HttpVersion { | pub enum HttpVersion { | ||||||
|     /// `HTTP/0.9` |     /// `HTTP/0.9` | ||||||
|     Http09, |     Http09, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user