mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
net: Stop using both versions of the time
crate in the cookie code (#33260)
`std::time` is good enough for us here. `cookie` is using `time 0.3`, but Servo can convert to standard library types when getting data from `cookie`. This reduces our direct dependencies and removes more use of the very old `time 0.1` series. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
1e9344cb5c
commit
6f333a8e29
9 changed files with 29 additions and 95 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1277,7 +1277,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2967,8 +2966,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"serde_test",
|
"serde_test",
|
||||||
"time 0.1.45",
|
|
||||||
"time 0.3.36",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4518,7 +4515,6 @@ dependencies = [
|
||||||
"servo_url",
|
"servo_url",
|
||||||
"sha2",
|
"sha2",
|
||||||
"time 0.1.45",
|
"time 0.1.45",
|
||||||
"time 0.3.36",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
|
|
|
@ -121,7 +121,6 @@ syn = { version = "2", default-features = false, features = ["clone-impls", "der
|
||||||
synstructure = "0.13"
|
synstructure = "0.13"
|
||||||
thin-vec = "0.2.13"
|
thin-vec = "0.2.13"
|
||||||
time = "0.1.41"
|
time = "0.1.41"
|
||||||
time_03 = { package = "time", version = "0.3", features = ["serde"] }
|
|
||||||
to_shmem = { git = "https://github.com/servo/stylo", branch = "2024-07-16" }
|
to_shmem = { git = "https://github.com/servo/stylo", branch = "2024-07-16" }
|
||||||
tokio = "1"
|
tokio = "1"
|
||||||
tokio-rustls = "0.24"
|
tokio-rustls = "0.24"
|
||||||
|
|
|
@ -23,8 +23,6 @@ hyper = { workspace = true }
|
||||||
mime = { workspace = true }
|
mime = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_bytes = { workspace = true }
|
serde_bytes = { workspace = true }
|
||||||
time = { workspace = true }
|
|
||||||
time_03 = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_test = "1.0"
|
serde_test = "1.0"
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
//! * `hyper::Method`
|
//! * `hyper::Method`
|
||||||
//! * `hyper::Uri`
|
//! * `hyper::Uri`
|
||||||
//! * `mime::Mime`
|
//! * `mime::Mime`
|
||||||
//! * `time::Tm`
|
|
||||||
//!
|
//!
|
||||||
//! # How do I use a data type with a `HeaderMap` member with Serde?
|
//! # How do I use a data type with a `HeaderMap` member with Serde?
|
||||||
//!
|
//!
|
||||||
|
@ -78,7 +77,6 @@ use serde::de::{self, Error, MapAccess, SeqAccess, Visitor};
|
||||||
use serde::ser::{SerializeMap, SerializeSeq};
|
use serde::ser::{SerializeMap, SerializeSeq};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use serde_bytes::{ByteBuf, Bytes};
|
use serde_bytes::{ByteBuf, Bytes};
|
||||||
use time::{strptime, Tm};
|
|
||||||
|
|
||||||
/// Deserialises a `T` value with a given deserializer.
|
/// Deserialises a `T` value with a given deserializer.
|
||||||
///
|
///
|
||||||
|
@ -604,43 +602,6 @@ impl<'de> Visitor<'de> for StatusVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for De<Tm> {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
struct TmVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for TmVisitor {
|
|
||||||
type Value = De<Tm>;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(formatter, "a date and time according to RFC 3339")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
strptime(v, "%Y-%m-%dT%H:%M:%SZ")
|
|
||||||
.map(De::new)
|
|
||||||
.map_err(|e| E::custom(e.to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_string(TmVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Serialize for Ser<'a, Tm> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
serializer.serialize_str(&self.v.rfc3339().to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for De<Uri> {
|
impl<'de> Deserialize<'de> for De<Uri> {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
|
|
|
@ -15,7 +15,6 @@ use hyper::{Method, StatusCode, Uri};
|
||||||
use hyper_serde::{De, Ser, Serde};
|
use hyper_serde::{De, Ser, Serde};
|
||||||
use mime::Mime;
|
use mime::Mime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use time::Tm;
|
|
||||||
|
|
||||||
fn is_supported<T>()
|
fn is_supported<T>()
|
||||||
where
|
where
|
||||||
|
@ -33,6 +32,5 @@ fn supported() {
|
||||||
is_supported::<Method>();
|
is_supported::<Method>();
|
||||||
is_supported::<Mime>();
|
is_supported::<Mime>();
|
||||||
is_supported::<StatusCode>();
|
is_supported::<StatusCode>();
|
||||||
is_supported::<Tm>();
|
|
||||||
is_supported::<Uri>();
|
is_supported::<Uri>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use cookie::{Cookie, CookieBuilder};
|
use cookie::{Cookie, CookieBuilder};
|
||||||
use headers::ContentType;
|
use headers::ContentType;
|
||||||
use http::header::{self, HeaderMap, HeaderValue};
|
use http::header::{self, HeaderMap, HeaderValue};
|
||||||
|
@ -15,7 +17,6 @@ use http::StatusCode;
|
||||||
use hyper::{Method, Uri};
|
use hyper::{Method, Uri};
|
||||||
use hyper_serde::{De, Ser};
|
use hyper_serde::{De, Ser};
|
||||||
use serde_test::{assert_de_tokens, assert_ser_tokens, Token};
|
use serde_test::{assert_de_tokens, assert_ser_tokens, Token};
|
||||||
use time_03::Duration;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_content_type() {
|
fn test_content_type() {
|
||||||
|
@ -32,7 +33,7 @@ fn test_cookie() {
|
||||||
// string with a bunch of indices in it which apparently is different from the exact same
|
// string with a bunch of indices in it which apparently is different from the exact same
|
||||||
// cookie but parsed as a bunch of strings.
|
// cookie but parsed as a bunch of strings.
|
||||||
let cookie: Cookie = CookieBuilder::new("Hello", "World!")
|
let cookie: Cookie = CookieBuilder::new("Hello", "World!")
|
||||||
.max_age(Duration::seconds(42))
|
.max_age(Duration::from_secs(42).try_into().unwrap_or_default())
|
||||||
.domain("servo.org")
|
.domain("servo.org")
|
||||||
.path("/")
|
.path("/")
|
||||||
.secure(true)
|
.secure(true)
|
||||||
|
@ -111,17 +112,6 @@ fn test_raw_status() {
|
||||||
assert_de_tokens(&De::new(raw_status), tokens);
|
assert_de_tokens(&De::new(raw_status), tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_tm() {
|
|
||||||
use time::strptime;
|
|
||||||
|
|
||||||
let time = strptime("2017-02-22T12:03:31Z", "%Y-%m-%dT%H:%M:%SZ").unwrap();
|
|
||||||
let tokens = &[Token::Str("2017-02-22T12:03:31Z")];
|
|
||||||
|
|
||||||
assert_ser_tokens(&Ser::new(&time), tokens);
|
|
||||||
assert_de_tokens(&De::new(time), tokens);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_uri() {
|
fn test_uri() {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
|
@ -57,7 +57,6 @@ servo_config = { path = "../config" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
time = { workspace = true }
|
time = { workspace = true }
|
||||||
time_03 = { workspace = true }
|
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] }
|
tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] }
|
||||||
tokio-rustls = { workspace = true }
|
tokio-rustls = { workspace = true }
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
|
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use net_traits::pub_domains::is_pub_domain;
|
use net_traits::pub_domains::is_pub_domain;
|
||||||
use net_traits::CookieSource;
|
use net_traits::CookieSource;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use time::{now, Tm};
|
|
||||||
use time_03::OffsetDateTime;
|
|
||||||
|
|
||||||
/// A stored cookie that wraps the definition in cookie-rs. This is used to implement
|
/// A stored cookie that wraps the definition in cookie-rs. This is used to implement
|
||||||
/// various behaviours defined in the spec that rely on an associated request URL,
|
/// various behaviours defined in the spec that rely on an associated request URL,
|
||||||
|
@ -28,17 +27,9 @@ pub struct ServoCookie {
|
||||||
pub cookie: Cookie<'static>,
|
pub cookie: Cookie<'static>,
|
||||||
pub host_only: bool,
|
pub host_only: bool,
|
||||||
pub persistent: bool,
|
pub persistent: bool,
|
||||||
#[serde(
|
pub creation_time: SystemTime,
|
||||||
deserialize_with = "hyper_serde::deserialize",
|
pub last_access: SystemTime,
|
||||||
serialize_with = "hyper_serde::serialize"
|
pub expiry_time: Option<SystemTime>,
|
||||||
)]
|
|
||||||
pub creation_time: Tm,
|
|
||||||
#[serde(
|
|
||||||
deserialize_with = "hyper_serde::deserialize",
|
|
||||||
serialize_with = "hyper_serde::serialize"
|
|
||||||
)]
|
|
||||||
pub last_access: Tm,
|
|
||||||
pub expiry_time: Option<OffsetDateTime>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServoCookie {
|
impl ServoCookie {
|
||||||
|
@ -60,9 +51,11 @@ impl ServoCookie {
|
||||||
source: CookieSource,
|
source: CookieSource,
|
||||||
) -> Option<ServoCookie> {
|
) -> Option<ServoCookie> {
|
||||||
// Step 3
|
// Step 3
|
||||||
let (persistent, expiry_time) = match (cookie.max_age(), cookie.expires_datetime()) {
|
let max_age: Option<Duration> =
|
||||||
(Some(max_age), _) => (true, Some(time_03::OffsetDateTime::now_utc() + max_age)),
|
cookie.max_age().and_then(|max_age| max_age.try_into().ok());
|
||||||
(_, Some(date_time)) => (true, Some(date_time)),
|
let (persistent, expiry_time) = match (max_age, cookie.expires_datetime()) {
|
||||||
|
(Some(max_age), _) => (true, Some(SystemTime::now() + max_age)),
|
||||||
|
(_, Some(date_time)) => (true, Some(date_time.into())),
|
||||||
_ => (false, None),
|
_ => (false, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,18 +124,18 @@ impl ServoCookie {
|
||||||
cookie,
|
cookie,
|
||||||
host_only,
|
host_only,
|
||||||
persistent,
|
persistent,
|
||||||
creation_time: now(),
|
creation_time: SystemTime::now(),
|
||||||
last_access: now(),
|
last_access: SystemTime::now(),
|
||||||
expiry_time,
|
expiry_time,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn touch(&mut self) {
|
pub fn touch(&mut self) {
|
||||||
self.last_access = now();
|
self.last_access = SystemTime::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_expiry_time_in_past(&mut self) {
|
pub fn set_expiry_time_in_past(&mut self) {
|
||||||
self.expiry_time = Some(time_03::OffsetDateTime::UNIX_EPOCH);
|
self.expiry_time = Some(SystemTime::UNIX_EPOCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://tools.ietf.org/html/rfc6265#section-5.1.4
|
// http://tools.ietf.org/html/rfc6265#section-5.1.4
|
||||||
|
|
|
@ -8,14 +8,13 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use net_traits::pub_domains::reg_suffix;
|
use net_traits::pub_domains::reg_suffix;
|
||||||
use net_traits::CookieSource;
|
use net_traits::CookieSource;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use time::Tm;
|
|
||||||
use time_03::OffsetDateTime;
|
|
||||||
|
|
||||||
use crate::cookie::ServoCookie;
|
use crate::cookie::ServoCookie;
|
||||||
|
|
||||||
|
@ -145,11 +144,7 @@ impl CookieStorage {
|
||||||
let a_path_len = a.cookie.path().as_ref().map_or(0, |p| p.len());
|
let a_path_len = a.cookie.path().as_ref().map_or(0, |p| p.len());
|
||||||
let b_path_len = b.cookie.path().as_ref().map_or(0, |p| p.len());
|
let b_path_len = b.cookie.path().as_ref().map_or(0, |p| p.len());
|
||||||
match a_path_len.cmp(&b_path_len) {
|
match a_path_len.cmp(&b_path_len) {
|
||||||
Ordering::Equal => {
|
Ordering::Equal => a.creation_time.cmp(&b.creation_time),
|
||||||
let a_creation_time = a.creation_time.to_timespec();
|
|
||||||
let b_creation_time = b.creation_time.to_timespec();
|
|
||||||
a_creation_time.cmp(&b_creation_time)
|
|
||||||
},
|
|
||||||
// Ensure that longer paths are sorted earlier than shorter paths
|
// Ensure that longer paths are sorted earlier than shorter paths
|
||||||
Ordering::Greater => Ordering::Less,
|
Ordering::Greater => Ordering::Less,
|
||||||
Ordering::Less => Ordering::Greater,
|
Ordering::Less => Ordering::Greater,
|
||||||
|
@ -235,12 +230,12 @@ fn reg_host(url: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_cookie_expired(cookie: &ServoCookie) -> bool {
|
fn is_cookie_expired(cookie: &ServoCookie) -> bool {
|
||||||
matches!(cookie.expiry_time, Some(date_time) if date_time <= OffsetDateTime::now_utc())
|
matches!(cookie.expiry_time, Some(date_time) if date_time <= SystemTime::now())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<ServoCookie>) -> bool {
|
fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<ServoCookie>) -> bool {
|
||||||
// Remove non-secure cookie with oldest access time
|
// Remove non-secure cookie with oldest access time
|
||||||
let oldest_accessed: Option<(usize, Tm)> = get_oldest_accessed(false, cookies);
|
let oldest_accessed = get_oldest_accessed(false, cookies);
|
||||||
|
|
||||||
if let Some((index, _)) = oldest_accessed {
|
if let Some((index, _)) = oldest_accessed {
|
||||||
cookies.remove(index);
|
cookies.remove(index);
|
||||||
|
@ -249,7 +244,7 @@ fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<ServoCookie>) -> b
|
||||||
if !is_secure_cookie {
|
if !is_secure_cookie {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let oldest_accessed: Option<(usize, Tm)> = get_oldest_accessed(true, cookies);
|
let oldest_accessed = get_oldest_accessed(true, cookies);
|
||||||
if let Some((index, _)) = oldest_accessed {
|
if let Some((index, _)) = oldest_accessed {
|
||||||
cookies.remove(index);
|
cookies.remove(index);
|
||||||
}
|
}
|
||||||
|
@ -257,13 +252,18 @@ fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<ServoCookie>) -> b
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_oldest_accessed(is_secure_cookie: bool, cookies: &mut [ServoCookie]) -> Option<(usize, Tm)> {
|
fn get_oldest_accessed(
|
||||||
let mut oldest_accessed: Option<(usize, Tm)> = None;
|
is_secure_cookie: bool,
|
||||||
|
cookies: &mut [ServoCookie],
|
||||||
|
) -> Option<(usize, SystemTime)> {
|
||||||
|
let mut oldest_accessed = None;
|
||||||
for (i, c) in cookies.iter().enumerate() {
|
for (i, c) in cookies.iter().enumerate() {
|
||||||
if (c.cookie.secure().unwrap_or(false) == is_secure_cookie) &&
|
if (c.cookie.secure().unwrap_or(false) == is_secure_cookie) &&
|
||||||
oldest_accessed
|
oldest_accessed
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(true, |a| c.last_access < a.1)
|
.map_or(true, |(_, current_oldest_time)| {
|
||||||
|
c.last_access < *current_oldest_time
|
||||||
|
})
|
||||||
{
|
{
|
||||||
oldest_accessed = Some((i, c.last_access));
|
oldest_accessed = Some((i, c.last_access));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue