diff --git a/Cargo.toml b/Cargo.toml index 229cb6dce..911accbef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,9 @@ license = "MIT/Apache-2.0" exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"] edition = "2018" +[package.metadata.docs.rs] +features = ["ssl", "brotli", "flate2-zlib", "secure-cookies", "client", "rust-tls"] + [badges] travis-ci = { repository = "actix/actix-web", branch = "master" } codecov = { repository = "actix/actix-web", branch = "master", service = "github" } @@ -37,9 +40,6 @@ members = [ "test-server", ] -[package.metadata.docs.rs] -features = ["ssl", "brotli", "flate2-zlib", "secure-cookies", "client", "rust-tls"] - [features] default = ["brotli", "flate2-zlib", "secure-cookies", "client"] @@ -96,6 +96,7 @@ url = { version="1.7", features=["query_encoding"] } # ssl support openssl = { version="0.10", optional = true } rustls = { version = "^0.15", optional = true } +chrono = "0.4.6" [dev-dependencies] actix-http = { version = "0.1.0", features=["ssl", "brotli", "flate2-zlib"] } diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 575a08a0e..d5a65b7b5 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -93,6 +93,7 @@ flate2 = { version="1.0.7", optional = true, default-features = false } # optional deps failure = { version = "0.1.5", optional = true } openssl = { version="0.10", optional = true } +chrono = "0.4.6" [dev-dependencies] actix-rt = "0.2.2" diff --git a/actix-http/src/cookie/builder.rs b/actix-http/src/cookie/builder.rs index 2635572ab..71c9bd19a 100644 --- a/actix-http/src/cookie/builder.rs +++ b/actix-http/src/cookie/builder.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; -use time::{Duration, Tm}; +use time::Tm; +use chrono::Duration; use super::{Cookie, SameSite}; @@ -16,7 +17,7 @@ use super::{Cookie, SameSite}; /// /// ```rust /// use actix_http::cookie::Cookie; -/// use time::Duration; +/// use chrono::Duration; /// /// # fn main() { /// let cookie: Cookie = Cookie::build("name", "value") @@ -200,7 +201,7 @@ impl CookieBuilder { /// /// ```rust /// use actix_http::cookie::Cookie; - /// use time::Duration; + /// use chrono::Duration; /// /// # fn main() { /// let c = Cookie::build("foo", "bar") diff --git a/actix-http/src/cookie/jar.rs b/actix-http/src/cookie/jar.rs index b60d73fe6..8b67c37d8 100644 --- a/actix-http/src/cookie/jar.rs +++ b/actix-http/src/cookie/jar.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::mem::replace; -use time::{self, Duration}; +use chrono::Duration; use super::delta::DeltaCookie; use super::Cookie; @@ -188,7 +188,7 @@ impl CookieJar { /// /// ```rust /// use actix_http::cookie::{CookieJar, Cookie}; - /// use time::Duration; + /// use chrono::Duration; /// /// # fn main() { /// let mut jar = CookieJar::new(); @@ -241,7 +241,7 @@ impl CookieJar { /// /// ```rust /// use actix_http::cookie::{CookieJar, Cookie}; - /// use time::Duration; + /// use chrono::Duration; /// /// # fn main() { /// let mut jar = CookieJar::new(); @@ -538,7 +538,7 @@ mod test { #[cfg(feature = "secure-cookies")] fn delta() { use std::collections::HashMap; - use time::Duration; + use chrono::Duration; let mut c = CookieJar::new(); diff --git a/actix-http/src/cookie/mod.rs b/actix-http/src/cookie/mod.rs index 0f5f45488..eef41a121 100644 --- a/actix-http/src/cookie/mod.rs +++ b/actix-http/src/cookie/mod.rs @@ -66,7 +66,8 @@ use std::fmt; use std::str::FromStr; use percent_encoding::{percent_encode, USERINFO_ENCODE_SET}; -use time::{Duration, Tm}; +use time::Tm; +use chrono::Duration; pub use self::builder::CookieBuilder; pub use self::draft::*; @@ -624,7 +625,7 @@ impl<'c> Cookie<'c> { /// /// ```rust /// use actix_http::cookie::Cookie; - /// use time::Duration; + /// use chrono::Duration; /// /// # fn main() { /// let mut c = Cookie::new("name", "value"); @@ -703,7 +704,7 @@ impl<'c> Cookie<'c> { /// /// ```rust /// use actix_http::cookie::Cookie; - /// use time::Duration; + /// use chrono::Duration; /// /// # fn main() { /// let mut c = Cookie::new("foo", "bar"); @@ -977,7 +978,8 @@ impl<'a, 'b> PartialEq> for Cookie<'a> { #[cfg(test)] mod tests { use super::{Cookie, SameSite}; - use time::{strptime, Duration}; + use time::strptime; + use chrono::Duration; #[test] fn format() { diff --git a/actix-http/src/cookie/parse.rs b/actix-http/src/cookie/parse.rs index ebbd6ffc9..cc042733e 100644 --- a/actix-http/src/cookie/parse.rs +++ b/actix-http/src/cookie/parse.rs @@ -6,7 +6,7 @@ use std::fmt; use std::str::Utf8Error; use percent_encoding::percent_decode; -use time::{self, Duration}; +use chrono::Duration; use super::{Cookie, CookieStr, SameSite}; @@ -220,7 +220,8 @@ where #[cfg(test)] mod tests { use super::{Cookie, SameSite}; - use time::{strptime, Duration}; + use time::strptime; + use chrono::Duration; macro_rules! assert_eq_parse { ($string:expr, $expected:expr) => { diff --git a/src/middleware/identity.rs b/src/middleware/identity.rs index 6027aaa7d..bf739636f 100644 --- a/src/middleware/identity.rs +++ b/src/middleware/identity.rs @@ -53,7 +53,7 @@ use std::rc::Rc; use actix_service::{Service, Transform}; use futures::future::{ok, Either, FutureResult}; use futures::{Future, IntoFuture, Poll}; -use time::Duration; +use chrono::Duration; use crate::cookie::{Cookie, CookieJar, Key, SameSite}; use crate::error::{Error, Result}; @@ -427,11 +427,16 @@ impl CookieIdentityPolicy { self } - /// Sets the `max-age` field in the session cookie being built. - pub fn max_age(mut self, value: Duration) -> CookieIdentityPolicy { + /// Sets the `max-age` field in the session cookie being built with `chrono::Duration`. + pub fn max_age_time(mut self, value: Duration) -> CookieIdentityPolicy { Rc::get_mut(&mut self.0).unwrap().max_age = Some(value); self } + /// Sets the `max-age` field in the session cookie being built with given number of seconds. + pub fn max_age(mut self, seconds: isize) -> CookieIdentityPolicy { + Rc::get_mut(&mut self.0).unwrap().max_age = Some(Duration::seconds(seconds as i64)); + self + } /// Sets the `same_site` field in the session cookie being built. pub fn same_site(mut self, same_site: SameSite) -> Self { @@ -525,4 +530,56 @@ mod tests { assert_eq!(resp.status(), StatusCode::OK); assert!(resp.headers().contains_key(header::SET_COOKIE)) } + + #[test] + fn test_identity_max_age_time() { + let duration = Duration::days(1); + let mut srv = test::init_service( + App::new() + .wrap(IdentityService::new( + CookieIdentityPolicy::new(&[0; 32]) + .domain("www.rust-lang.org") + .name("actix_auth") + .path("/") + .max_age_time(duration) + .secure(true), + )) + .service(web::resource("/login").to(|id: Identity| { + id.remember("test".to_string()); + HttpResponse::Ok() + })) + ); + let resp = + test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()); + assert_eq!(resp.status(), StatusCode::OK); + assert!(resp.headers().contains_key(header::SET_COOKIE)); + let c = resp.response().cookies().next().unwrap().to_owned(); + assert_eq!(duration, c.max_age().unwrap()); + } + + #[test] + fn test_identity_max_age() { + let seconds = 60isize; + let mut srv = test::init_service( + App::new() + .wrap(IdentityService::new( + CookieIdentityPolicy::new(&[0; 32]) + .domain("www.rust-lang.org") + .name("actix_auth") + .path("/") + .max_age(seconds) + .secure(true), + )) + .service(web::resource("/login").to(|id: Identity| { + id.remember("test".to_string()); + HttpResponse::Ok() + })) + ); + let resp = + test::call_service(&mut srv, TestRequest::with_uri("/login").to_request()); + assert_eq!(resp.status(), StatusCode::OK); + assert!(resp.headers().contains_key(header::SET_COOKIE)); + let c = resp.response().cookies().next().unwrap().to_owned(); + assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap()); + } }