diff --git a/Cargo.toml b/Cargo.toml index 8c6d461d6..0d1bb429c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ default = ["compress"] # content-encoding support compress = ["actix-http/compress", "awc/compress"] -# sessions feature, session require "ring" crate and c compiler +# sessions feature secure-cookies = ["actix-http/secure-cookies"] # openssl diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index d2ae7698e..3429d058b 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -34,7 +34,7 @@ rustls = ["actix-tls/rustls", "actix-connect/rustls"] compress = ["flate2", "brotli2"] # support for secure cookies -secure-cookies = ["ring"] +secure-cookies = ["cookie/secure"] # support for actix Actor messages actors = ["actix"] @@ -52,6 +52,7 @@ actix = { version = "0.10.0-alpha.1", optional = true } base64 = "0.12" bitflags = "1.2" bytes = "0.5.3" +cookie = { version = "0.14.1", features = ["percent-encode"] } copyless = "0.1.4" derive_more = "0.99.2" either = "1.5.3" @@ -69,7 +70,7 @@ lazy_static = "1.4" language-tags = "0.2" log = "0.4" mime = "0.3" -percent-encoding = "2.1" +percent-encoding = "2.1" # TODO: remove pin-project = "0.4.17" rand = "0.7" regex = "1.3" @@ -81,7 +82,7 @@ serde_urlencoded = "0.6.1" time = { version = "0.2.7", default-features = false, features = ["std"] } # for secure cookie -ring = { version = "0.16.9", optional = true } +ring = { version = "0.16.9", optional = true } # TODO: remove # compression brotli2 = { version="0.3.2", optional = true } diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index 9f615a129..dd8f5ee12 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -32,7 +32,7 @@ mod response; mod service; mod time_parser; -pub mod cookie; +pub use cookie; pub mod error; pub mod h1; pub mod h2; diff --git a/actix-http/src/response.rs b/actix-http/src/response.rs index 9086212f1..2def67168 100644 --- a/actix-http/src/response.rs +++ b/actix-http/src/response.rs @@ -877,7 +877,7 @@ mod tests { .domain("www.rust-lang.org") .path("/test") .http_only(true) - .max_age_time(time::Duration::days(1)) + .max_age(time::Duration::days(1)) .finish(), ) .del_cookie(&cookies[1]) diff --git a/actix-http/src/test.rs b/actix-http/src/test.rs index 061ba610f..58b9191a4 100644 --- a/actix-http/src/test.rs +++ b/actix-http/src/test.rs @@ -10,9 +10,8 @@ use actix_codec::{AsyncRead, AsyncWrite}; use bytes::{Bytes, BytesMut}; use http::header::{self, HeaderName, HeaderValue}; use http::{Error as HttpError, Method, Uri, Version}; -use percent_encoding::percent_encode; -use crate::cookie::{Cookie, CookieJar, USERINFO}; +use crate::cookie::{Cookie, CookieJar}; use crate::header::HeaderMap; use crate::header::{Header, IntoHeaderValue}; use crate::payload::Payload; @@ -165,9 +164,9 @@ impl TestRequest { let mut cookie = String::new(); for c in inner.cookies.delta() { - let name = percent_encode(c.name().as_bytes(), USERINFO); - let value = percent_encode(c.value().as_bytes(), USERINFO); - let _ = write!(&mut cookie, "; {}={}", name, value); + // ensure only name=value is written to cookie header + let c = Cookie::new(c.name(), c.value()); + let _ = write!(&mut cookie, "; {}", c.encoded()); } if !cookie.is_empty() { head.headers.insert( diff --git a/awc/src/request.rs b/awc/src/request.rs index 21a7cd911..27535786d 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -6,11 +6,10 @@ use std::{fmt, net}; use bytes::Bytes; use futures_core::Stream; -use percent_encoding::percent_encode; use serde::Serialize; use actix_http::body::Body; -use actix_http::cookie::{Cookie, CookieJar, USERINFO}; +use actix_http::cookie::{Cookie, CookieJar}; use actix_http::http::header::{self, Header, IntoHeaderValue}; use actix_http::http::{ uri, ConnectionType, Error as HttpError, HeaderMap, HeaderName, HeaderValue, Method, @@ -529,9 +528,9 @@ impl ClientRequest { if let Some(ref mut jar) = self.cookies { let mut cookie = String::new(); for c in jar.delta() { - let name = percent_encode(c.name().as_bytes(), USERINFO); - let value = percent_encode(c.value().as_bytes(), USERINFO); - let _ = write!(&mut cookie, "; {}={}", name, value); + // ensure only name=value is written to cookie header + let c = Cookie::new(c.name(), c.value()); + let _ = write!(&mut cookie, "; {}", c.encoded()); } self.head.headers.insert( header::COOKIE, diff --git a/awc/src/test.rs b/awc/src/test.rs index a6cbd03e6..34382f9a0 100644 --- a/awc/src/test.rs +++ b/awc/src/test.rs @@ -2,12 +2,11 @@ use std::convert::TryFrom; use std::fmt::Write as FmtWrite; -use actix_http::cookie::{Cookie, CookieJar, USERINFO}; +use actix_http::cookie::{Cookie, CookieJar}; use actix_http::http::header::{self, Header, HeaderValue, IntoHeaderValue}; use actix_http::http::{Error as HttpError, HeaderName, StatusCode, Version}; use actix_http::{h1, Payload, ResponseHead}; use bytes::Bytes; -use percent_encoding::percent_encode; use crate::ClientResponse; @@ -90,9 +89,8 @@ impl TestResponse { let mut cookie = String::new(); for c in self.cookies.delta() { - let name = percent_encode(c.name().as_bytes(), USERINFO); - let value = percent_encode(c.value().as_bytes(), USERINFO); - let _ = write!(&mut cookie, "; {}={}", name, value); + let c = Cookie::new(c.name(), c.value()); + let _ = write!(&mut cookie, "; {}", c.encoded()); } if !cookie.is_empty() { head.headers.insert( diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 89ca50b59..c733536ec 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -9,9 +9,7 @@ use actix_codec::Framed; use actix_http::cookie::{Cookie, CookieJar}; use actix_http::{ws, Payload, RequestHead}; use actix_rt::time::timeout; -use percent_encoding::percent_encode; -use actix_http::cookie::USERINFO; pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message}; use crate::connect::BoxedSocket; @@ -248,9 +246,9 @@ impl WebsocketsRequest { if let Some(ref mut jar) = self.cookies { let mut cookie = String::new(); for c in jar.delta() { - let name = percent_encode(c.name().as_bytes(), USERINFO); - let value = percent_encode(c.value().as_bytes(), USERINFO); - let _ = write!(&mut cookie, "; {}={}", name, value); + // ensure only name=value is written to cookie header + let c = Cookie::new(c.name(), c.value()); + let _ = write!(&mut cookie, "; {}", c.encoded()); } self.head.headers.insert( header::COOKIE,