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