From a85cc476e1258838560f2478eef20a23cf3e8413 Mon Sep 17 00:00:00 2001 From: Stanislav Panferov Date: Tue, 7 Oct 2014 22:37:58 +0400 Subject: [PATCH 1/7] Basic Cookie and Set-Cookie (only parsing) headers implementation. --- src/header/common/cookie.rs | 46 +++++++++++++++++++++++++++++++++ src/header/common/mod.rs | 17 ++++++++---- src/header/common/set_cookie.rs | 42 ++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 src/header/common/cookie.rs create mode 100644 src/header/common/set_cookie.rs diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs new file mode 100644 index 00000000..71dbf1dc --- /dev/null +++ b/src/header/common/cookie.rs @@ -0,0 +1,46 @@ +use header::Header; +use std::fmt::{mod, Show}; +use std::str::from_utf8; + +/// The `Cookie` header +/// +/// If the user agent does attach a Cookie header field to an HTTP +/// request, the user agent must send the cookie-string +/// as the value of the header field. +/// +/// When the user agent generates an HTTP request, the user agent MUST NOT +/// attach more than one Cookie header field. +#[deriving(Clone, PartialEq, Show)] +pub struct Cookie(pub Vec); + +impl Header for Cookie { + fn header_name(_: Option) -> &'static str { + "Cookie" + } + + fn parse_header(raw: &[Vec]) -> Option { + let mut cookies: Vec = vec![]; + for cookies_raw in raw.iter() { + match from_utf8(cookies_raw.as_slice()) { + Some(cookies_str) => { + for cookie in cookies_str.split(';') { + cookies.push(cookie.to_string()) + } + }, + None => return None + }; + } + + if !cookies.is_empty() { + Some(Cookie(cookies)) + } else { + None + } + } + + fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let Cookie(ref value) = *self; + value.connect("; ").fmt(fmt) + } +} + diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index d177903a..c98f9db9 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -25,6 +25,11 @@ use std::str::from_utf8; /// Exposes the Accept header. pub mod accept; +/// Exposes the Authorization header. +pub mod authorization; + +/// Exposes the Cookie header. +pub mod cookie; /// Exposes the Connection header. pub mod connection; @@ -41,9 +46,15 @@ pub mod date; /// Exposes the Host header. pub mod host; +/// Exposes the Location header. +pub mod location; + /// Exposes the Server header. pub mod server; +/// Exposes the Set-Cookie header. +pub mod set_cookie; + /// Exposes the TransferEncoding header. pub mod transfer_encoding; @@ -54,11 +65,8 @@ pub mod upgrade; pub mod user_agent; -/// Exposes the Location header. -pub mod location; +pub mod util; -/// Exposes the Authorization header. -pub mod authorization; fn from_comma_delimited(raw: &[Vec]) -> Option> { if raw.len() != 1 { @@ -86,4 +94,3 @@ fn fmt_comma_delimited(fmt: &mut fmt::Formatter, parts: &[T]) -> fmt::R } Ok(()) } -pub mod util; diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs new file mode 100644 index 00000000..63614de9 --- /dev/null +++ b/src/header/common/set_cookie.rs @@ -0,0 +1,42 @@ +use header::Header; +use std::fmt; +use std::str::from_utf8; + +/// The `Set-Cookie` header +/// +/// 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)] +pub struct SetCookie(pub Vec); + +impl Header for SetCookie { + fn header_name(_: Option) -> &'static str { + "Set-Cookie" + } + + fn parse_header(raw: &[Vec]) -> Option { + let mut set_cookies: Vec = vec![]; + for set_cookies_raw in raw.iter() { + match from_utf8(set_cookies_raw.as_slice()) { + Some(set_cookies_str) => { + if !set_cookies_str.is_empty() { + set_cookies.push(set_cookies_str.to_string()); + } + }, + None => () + }; + } + + if !set_cookies.is_empty() { + Some(SetCookie(set_cookies)) + } else { + None + } + } + + fn fmt_header(&self, _: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + From 0a624b10e01d61975465e6f6bbbc4ce8fa481539 Mon Sep 17 00:00:00 2001 From: Stanislav Panferov Date: Wed, 8 Oct 2014 10:35:10 +0400 Subject: [PATCH 2/7] Add cookie-rs and use `cookie::Cookie` in `Cookie` header. --- Cargo.toml | 2 ++ src/header/common/cookie.rs | 37 ++++++++++++++++++++++++++++++++----- src/lib.rs | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e8994c2b..9b8777d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,3 +31,5 @@ git = "https://github.com/carllerche/curl-rust" [dev-dependencies.http] git = "https://github.com/chris-morgan/rust-http" +[dependencies.cookie] +git = "https://github.com/alexcrichton/cookie-rs" \ No newline at end of file diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index 71dbf1dc..a8d710c0 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -1,6 +1,8 @@ use header::Header; use std::fmt::{mod, Show}; use std::str::from_utf8; +use cookie::Cookie as CookieRs; +use cookie::CookieJar; /// The `Cookie` header /// @@ -11,7 +13,7 @@ use std::str::from_utf8; /// When the user agent generates an HTTP request, the user agent MUST NOT /// attach more than one Cookie header field. #[deriving(Clone, PartialEq, Show)] -pub struct Cookie(pub Vec); +pub struct Cookie(pub Vec); impl Header for Cookie { fn header_name(_: Option) -> &'static str { @@ -19,12 +21,15 @@ impl Header for Cookie { } fn parse_header(raw: &[Vec]) -> Option { - let mut cookies: Vec = vec![]; + let mut cookies: Vec = vec![]; for cookies_raw in raw.iter() { match from_utf8(cookies_raw.as_slice()) { Some(cookies_str) => { - for cookie in cookies_str.split(';') { - cookies.push(cookie.to_string()) + for cookie_str in cookies_str.split(';') { + match CookieRs::parse(cookie_str.trim()) { + Ok(cookie) => cookies.push(cookie), + Err(_) => return None + } } }, None => return None @@ -40,7 +45,29 @@ impl Header for Cookie { fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let Cookie(ref value) = *self; - value.connect("; ").fmt(fmt) + let last = value.len() - 1; + for (i, cookie) in value.iter().enumerate() { + try!(cookie.fmt(fmt)); + if i < last { + try!("; ".fmt(fmt)); + } + } + Ok(()) + } +} + +impl Cookie { + /// This method can be used to crate CookieJar that can be used + /// to manipulate cookies and create corresponding `SetCookie` header afterwards. + #[allow(dead_code)] + fn to_cookie_jar(&self, key: &[u8]) -> CookieJar { + let mut jar = CookieJar::new(key); + let &Cookie(ref cookies) = self; + for cookie in cookies.iter() { + jar.add_original(cookie.clone()); + } + + jar } } diff --git a/src/lib.rs b/src/lib.rs index f174a4b8..3e9c8f47 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,6 +136,7 @@ extern crate "unsafe-any" as uany; extern crate "move-acceptor" as macceptor; extern crate intertwine; extern crate typeable; +extern crate cookie; pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port}; pub use mimewrapper::mime; From 20f156c592743f8b4f4dc0e432cb1a4618e60517 Mon Sep 17 00:00:00 2001 From: Stanislav Panferov Date: Wed, 8 Oct 2014 10:47:09 +0400 Subject: [PATCH 3/7] Build SetCookie from CookieJar --- src/header/common/set_cookie.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index 63614de9..55528e82 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -1,6 +1,7 @@ use header::Header; use std::fmt; use std::str::from_utf8; +use cookie::CookieJar; /// The `Set-Cookie` header /// @@ -40,3 +41,12 @@ impl Header for SetCookie { } } +impl SetCookie { + /// Use this to crate SetCookie header from CookieJar using + /// calculated delta. + #[allow(dead_code)] + fn from_cookie_jar(jar: &CookieJar) -> SetCookie { + SetCookie(jar.delta()) + } +} + From a3fc51611f31182190bef36d8df38c4df70a93b0 Mon Sep 17 00:00:00 2001 From: Stanislav Panferov Date: Wed, 8 Oct 2014 11:38:01 +0400 Subject: [PATCH 4/7] Add cookie_rs as default feature and implement conditional compilation. --- Cargo.toml | 7 ++++++- src/header/common/cookie.rs | 35 ++++++++++++++++++++++----------- src/header/common/set_cookie.rs | 3 +++ src/lib.rs | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9b8777d5..e3fd45e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,10 @@ name = "hyper" version = "0.0.1" authors = ["Sean McArthur "] +[features] +cookie_rs = ["cookie"] +default = ["cookie_rs"] + [dependencies.url] git = "https://github.com/servo/rust-url" @@ -32,4 +36,5 @@ git = "https://github.com/carllerche/curl-rust" git = "https://github.com/chris-morgan/rust-http" [dependencies.cookie] -git = "https://github.com/alexcrichton/cookie-rs" \ No newline at end of file +git = "https://github.com/alexcrichton/cookie-rs" +optional = true diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index a8d710c0..1781c894 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -1,7 +1,11 @@ use header::Header; use std::fmt::{mod, Show}; use std::str::from_utf8; +use std::from_str::FromStr; + +#[cfg(feature = "cookie_rs")] use cookie::Cookie as CookieRs; +#[cfg(feature = "cookie_rs")] use cookie::CookieJar; /// The `Cookie` header @@ -13,22 +17,22 @@ 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)] -pub struct Cookie(pub Vec); +pub struct TypedCookie(pub Vec); -impl Header for Cookie { - fn header_name(_: Option) -> &'static str { +impl Header for TypedCookie { + fn header_name(_: Option>) -> &'static str { "Cookie" } - fn parse_header(raw: &[Vec]) -> Option { - let mut cookies: Vec = vec![]; + fn parse_header(raw: &[Vec]) -> Option> { + let mut cookies: Vec = vec![]; for cookies_raw in raw.iter() { match from_utf8(cookies_raw.as_slice()) { Some(cookies_str) => { for cookie_str in cookies_str.split(';') { - match CookieRs::parse(cookie_str.trim()) { - Ok(cookie) => cookies.push(cookie), - Err(_) => return None + match from_str(cookie_str.trim()) { + Some(cookie) => cookies.push(cookie), + None => return None } } }, @@ -37,14 +41,14 @@ impl Header for Cookie { } if !cookies.is_empty() { - Some(Cookie(cookies)) + Some(TypedCookie(cookies)) } else { None } } fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let Cookie(ref value) = *self; + let TypedCookie(ref value) = *self; let last = value.len() - 1; for (i, cookie) in value.iter().enumerate() { try!(cookie.fmt(fmt)); @@ -56,15 +60,22 @@ impl Header for Cookie { } } +#[cfg(not(feature = "cookie_rs"))] +pub type Cookie = TypedCookie; + +#[cfg(feature = "cookie_rs")] +pub type Cookie = TypedCookie; + +#[cfg(feature = "cookie_rs")] impl Cookie { /// This method can be used to crate CookieJar that can be used /// to manipulate cookies and create corresponding `SetCookie` header afterwards. #[allow(dead_code)] fn to_cookie_jar(&self, key: &[u8]) -> CookieJar { let mut jar = CookieJar::new(key); - let &Cookie(ref cookies) = self; + let &TypedCookie(ref cookies) = self; for cookie in cookies.iter() { - jar.add_original(cookie.clone()); + jar.add_original((*cookie).clone()); } jar diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index 55528e82..a8f13f3e 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -1,6 +1,8 @@ use header::Header; use std::fmt; use std::str::from_utf8; + +#[cfg(feature = "cookie_rs")] use cookie::CookieJar; /// The `Set-Cookie` header @@ -45,6 +47,7 @@ impl SetCookie { /// Use this to crate SetCookie header from CookieJar using /// calculated delta. #[allow(dead_code)] + #[cfg(feature = "cookie_rs")] fn from_cookie_jar(jar: &CookieJar) -> SetCookie { SetCookie(jar.delta()) } diff --git a/src/lib.rs b/src/lib.rs index 3e9c8f47..b736e543 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,7 +136,7 @@ extern crate "unsafe-any" as uany; extern crate "move-acceptor" as macceptor; extern crate intertwine; extern crate typeable; -extern crate cookie; +#[cfg(feature = "cookie_rs")] extern crate cookie; pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port}; pub use mimewrapper::mime; From 5c224289ec1b49d9550765b4b23e6bdd84bcb416 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 7 Nov 2014 21:29:17 -0800 Subject: [PATCH 5/7] adjustments to Cookie and SetCookie --- Cargo.toml | 5 -- src/header/common/cookie.rs | 89 +++++++++++++++++++-------------- src/header/common/mod.rs | 10 +++- src/header/common/set_cookie.rs | 68 ++++++++++++++++++------- src/lib.rs | 2 +- 5 files changed, 111 insertions(+), 63 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e3fd45e7..3e02adda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,6 @@ name = "hyper" version = "0.0.1" authors = ["Sean McArthur "] -[features] -cookie_rs = ["cookie"] -default = ["cookie_rs"] - [dependencies.url] git = "https://github.com/servo/rust-url" @@ -37,4 +33,3 @@ git = "https://github.com/chris-morgan/rust-http" [dependencies.cookie] git = "https://github.com/alexcrichton/cookie-rs" -optional = true diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index 1781c894..6e275446 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -1,33 +1,31 @@ -use header::Header; +use header::{Header, HeaderFormat}; use std::fmt::{mod, Show}; use std::str::from_utf8; -use std::from_str::FromStr; +use std::from_str::from_str; -#[cfg(feature = "cookie_rs")] -use cookie::Cookie as CookieRs; -#[cfg(feature = "cookie_rs")] +use cookie::Cookie; use cookie::CookieJar; -/// The `Cookie` header +/// The `Cookie` header. Defined in [RFC6265](tools.ietf.org/html/rfc6265#section-5.4): /// -/// If the user agent does attach a Cookie header field to an HTTP -/// request, the user agent must send the cookie-string -/// as the value of the header field. +/// > If the user agent does attach a Cookie header field to an HTTP +/// > request, the user agent must send the cookie-string +/// > as the value of the header field. /// -/// When the user agent generates an HTTP request, the user agent MUST NOT -/// attach more than one Cookie header field. +/// > When the user agent generates an HTTP request, the user agent MUST NOT +/// > attach more than one Cookie header field. #[deriving(Clone, PartialEq, Show)] -pub struct TypedCookie(pub Vec); +pub struct Cookies(pub Vec); -impl Header for TypedCookie { - fn header_name(_: Option>) -> &'static str { +impl Header for Cookies { + fn header_name(_: Option) -> &'static str { "Cookie" } - fn parse_header(raw: &[Vec]) -> Option> { - let mut cookies: Vec = vec![]; + fn parse_header(raw: &[Vec]) -> Option { + let mut cookies = vec![]; for cookies_raw in raw.iter() { - match from_utf8(cookies_raw.as_slice()) { + match from_utf8(cookies_raw[]) { Some(cookies_str) => { for cookie_str in cookies_str.split(';') { match from_str(cookie_str.trim()) { @@ -41,17 +39,20 @@ impl Header for TypedCookie { } if !cookies.is_empty() { - Some(TypedCookie(cookies)) + Some(Cookies(cookies)) } else { None } } +} + +impl HeaderFormat for Cookies { fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let TypedCookie(ref value) = *self; - let last = value.len() - 1; - for (i, cookie) in value.iter().enumerate() { - try!(cookie.fmt(fmt)); + let cookies = &self.0; + let last = cookies.len() - 1; + for (i, cookie) in cookies.iter().enumerate() { + try!(write!(fmt, "{}={}", cookie.name, cookie.value)); if i < last { try!("; ".fmt(fmt)); } @@ -60,25 +61,37 @@ impl Header for TypedCookie { } } -#[cfg(not(feature = "cookie_rs"))] -pub type Cookie = TypedCookie; - -#[cfg(feature = "cookie_rs")] -pub type Cookie = TypedCookie; - -#[cfg(feature = "cookie_rs")] -impl Cookie { - /// This method can be used to crate CookieJar that can be used - /// to manipulate cookies and create corresponding `SetCookie` header afterwards. - #[allow(dead_code)] - fn to_cookie_jar(&self, key: &[u8]) -> CookieJar { +impl Cookies { + /// This method can be used to create CookieJar that can be used + /// to manipulate cookies and create a corresponding `SetCookie` header afterwards. + pub fn to_cookie_jar(&self, key: &[u8]) -> CookieJar<'static> { let mut jar = CookieJar::new(key); - let &TypedCookie(ref cookies) = self; - for cookie in cookies.iter() { + for cookie in self.0.iter() { jar.add_original((*cookie).clone()); } - - jar + jar } } + +#[test] +fn test_parse() { + let h = Header::parse_header([b"foo=bar; baz=quux".to_vec()][]); + let c1 = Cookie::new("foo".to_string(), "bar".to_string()); + let c2 = Cookie::new("baz".to_string(), "quux".to_string()); + assert_eq!(h, Some(Cookies(vec![c1, c2]))); +} + +#[test] +fn test_fmt() { + use header::Headers; + + let mut cookie = Cookie::new("foo".to_string(), "bar".to_string()); + cookie.httponly = true; + cookie.path = Some("/p".to_string()); + let cookies = Cookies(vec![cookie, Cookie::new("baz".to_string(), "quux".to_string())]); + let mut headers = Headers::new(); + headers.set(cookies); + + assert_eq!(headers.to_string()[], "Cookie: foo=bar; baz=quux\r\n"); +} diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index c98f9db9..f8b9b84d 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -8,6 +8,7 @@ pub use self::accept::Accept; pub use self::authorization::Authorization; +pub use self::cookie::Cookies; pub use self::connection::Connection; pub use self::content_length::ContentLength; pub use self::content_type::ContentType; @@ -18,6 +19,7 @@ pub use self::transfer_encoding::TransferEncoding; pub use self::upgrade::Upgrade; pub use self::user_agent::UserAgent; pub use self::server::Server; +pub use self::set_cookie::SetCookie; use std::fmt::{mod, Show}; use std::from_str::FromStr; @@ -31,6 +33,12 @@ pub mod authorization; /// Exposes the Cookie header. pub mod cookie; +/// Exposes the Cookie header. +pub mod cookie; + +/// Exposes the Set-Cookie header. +pub mod set_cookie; + /// Exposes the Connection header. pub mod connection; @@ -64,10 +72,8 @@ pub mod upgrade; /// Exposes the UserAgent header. pub mod user_agent; - pub mod util; - fn from_comma_delimited(raw: &[Vec]) -> Option> { if raw.len() != 1 { return None; diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index a8f13f3e..93ec2b50 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -1,8 +1,8 @@ -use header::Header; -use std::fmt; +use header::{Header, HeaderFormat}; +use std::fmt::{mod, Show}; use std::str::from_utf8; -#[cfg(feature = "cookie_rs")] +use cookie::Cookie; use cookie::CookieJar; /// The `Set-Cookie` header @@ -11,7 +11,7 @@ use cookie::CookieJar; /// "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)] -pub struct SetCookie(pub Vec); +pub struct SetCookie(pub Vec); impl Header for SetCookie { fn header_name(_: Option) -> &'static str { @@ -19,15 +19,16 @@ impl Header for SetCookie { } fn parse_header(raw: &[Vec]) -> Option { - let mut set_cookies: Vec = vec![]; + let mut set_cookies = vec![]; for set_cookies_raw in raw.iter() { - match from_utf8(set_cookies_raw.as_slice()) { - Some(set_cookies_str) => { - if !set_cookies_str.is_empty() { - set_cookies.push(set_cookies_str.to_string()); + match from_utf8(set_cookies_raw[]) { + Some(s) if !s.is_empty() => { + match from_str(s) { + Some(cookie) => set_cookies.push(cookie), + None => () } }, - None => () + _ => () }; } @@ -38,18 +39,51 @@ impl Header for SetCookie { } } - fn fmt_header(&self, _: &mut fmt::Formatter) -> fmt::Result { - unimplemented!() +} + +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!(cookie.fmt(f)); + } + Ok(()) } } + impl SetCookie { - /// Use this to crate SetCookie header from CookieJar using + /// Use this to create SetCookie header from CookieJar using /// calculated delta. - #[allow(dead_code)] - #[cfg(feature = "cookie_rs")] - fn from_cookie_jar(jar: &CookieJar) -> SetCookie { - SetCookie(jar.delta()) + pub fn from_cookie_jar(jar: &CookieJar) -> SetCookie { + //FIXME: https://github.com/alexcrichton/cookie-rs/issues/2 + SetCookie(jar.delta().into_iter().map(|s| from_str(s[]).unwrap()).collect()) } } + +#[test] +fn test_parse() { + let h = Header::parse_header([b"foo=bar; HttpOnly".to_vec()][]); + let mut c1 = Cookie::new("foo".to_string(), "bar".to_string()); + c1.httponly = true; + + assert_eq!(h, Some(SetCookie(vec![c1]))); +} + +#[test] +fn test_fmt() { + use header::Headers; + + let mut cookie = Cookie::new("foo".to_string(), "bar".to_string()); + cookie.httponly = true; + cookie.path = Some("/p".to_string()); + let cookies = SetCookie(vec![cookie, Cookie::new("baz".to_string(), "quux".to_string())]); + let mut headers = Headers::new(); + headers.set(cookies); + + assert_eq!(headers.to_string()[], "Set-Cookie: foo=bar; HttpOnly; Path=/p\r\nSet-Cookie: baz=quux; Path=/\r\n"); +} diff --git a/src/lib.rs b/src/lib.rs index b736e543..3e9c8f47 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,7 +136,7 @@ extern crate "unsafe-any" as uany; extern crate "move-acceptor" as macceptor; extern crate intertwine; extern crate typeable; -#[cfg(feature = "cookie_rs")] extern crate cookie; +extern crate cookie; pub use std::io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port}; pub use mimewrapper::mime; From 33210641f72ba1a77a32133a8fe92505b0641f77 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Nov 2014 09:32:18 -0800 Subject: [PATCH 6/7] use Vec::with_capacity(raw.len()) for Cookies --- src/header/common/cookie.rs | 3 +-- src/header/common/set_cookie.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index 6e275446..70f241d1 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -23,7 +23,7 @@ impl Header for Cookies { } fn parse_header(raw: &[Vec]) -> Option { - let mut cookies = vec![]; + let mut cookies = Vec::with_capacity(raw.len()); for cookies_raw in raw.iter() { match from_utf8(cookies_raw[]) { Some(cookies_str) => { @@ -44,7 +44,6 @@ impl Header for Cookies { None } } - } impl HeaderFormat for Cookies { diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index 93ec2b50..0db48a27 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -19,7 +19,7 @@ impl Header for SetCookie { } fn parse_header(raw: &[Vec]) -> Option { - let mut set_cookies = vec![]; + let mut set_cookies = Vec::with_capacity(raw.len()); for set_cookies_raw in raw.iter() { match from_utf8(set_cookies_raw[]) { Some(s) if !s.is_empty() => { From fcfb0505dd4f96468f721bf31451468ee6fb3ef2 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Nov 2014 11:13:20 -0800 Subject: [PATCH 7/7] update to newest cookie-rs --- src/header/common/cookie.rs | 2 +- src/header/common/mod.rs | 6 ------ src/header/common/set_cookie.rs | 3 +-- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/header/common/cookie.rs b/src/header/common/cookie.rs index 70f241d1..53228131 100644 --- a/src/header/common/cookie.rs +++ b/src/header/common/cookie.rs @@ -51,7 +51,7 @@ impl HeaderFormat for Cookies { let cookies = &self.0; let last = cookies.len() - 1; for (i, cookie) in cookies.iter().enumerate() { - try!(write!(fmt, "{}={}", cookie.name, cookie.value)); + try!(cookie.pair().fmt(fmt)); if i < last { try!("; ".fmt(fmt)); } diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index f8b9b84d..0120a776 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -33,12 +33,6 @@ pub mod authorization; /// Exposes the Cookie header. pub mod cookie; -/// Exposes the Cookie header. -pub mod cookie; - -/// Exposes the Set-Cookie header. -pub mod set_cookie; - /// Exposes the Connection header. pub mod connection; diff --git a/src/header/common/set_cookie.rs b/src/header/common/set_cookie.rs index 0db48a27..77f18a3e 100644 --- a/src/header/common/set_cookie.rs +++ b/src/header/common/set_cookie.rs @@ -59,8 +59,7 @@ impl SetCookie { /// Use this to create SetCookie header from CookieJar using /// calculated delta. pub fn from_cookie_jar(jar: &CookieJar) -> SetCookie { - //FIXME: https://github.com/alexcrichton/cookie-rs/issues/2 - SetCookie(jar.delta().into_iter().map(|s| from_str(s[]).unwrap()).collect()) + SetCookie(jar.delta()) } }