diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c976fae82..09a0911103 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## Unreleased +- The HTTP `Date` header in responses now strictly follows RFC7231. + ### Changed - When a previous block commit is unable to be RBFed, the miner will now just wait for it to be confirmed instead of submitting a new block commit which breaks the miner's UTXO chain. diff --git a/Cargo.lock b/Cargo.lock index 5ba814ea8b..5326152b43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -621,7 +621,6 @@ dependencies = [ "serde_stacker", "slog", "stacks-common 0.0.1", - "time 0.2.27", ] [[package]] @@ -694,9 +693,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_fn" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" [[package]] name = "core-foundation" @@ -810,9 +809,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -1668,9 +1667,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libflate" @@ -2984,9 +2983,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -3086,7 +3085,7 @@ dependencies = [ "serde", "serde_json", "slog", - "time 0.3.36", + "time 0.3.41", ] [[package]] @@ -3099,7 +3098,7 @@ dependencies = [ "slog", "term", "thread_local", - "time 0.3.36", + "time 0.3.41", ] [[package]] @@ -3188,7 +3187,6 @@ dependencies = [ "slog", "slog-json", "slog-term", - "time 0.2.27", "toml", "winapi 0.3.9", ] @@ -3373,7 +3371,7 @@ dependencies = [ "stx-genesis", "tempfile", "tikv-jemallocator", - "time 0.2.27", + "time 0.3.41", "toml", "url", "winapi 0.3.9", @@ -3645,9 +3643,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -3657,14 +3655,14 @@ dependencies = [ "powerfmt", "serde", "time-core", - "time-macros 0.2.18", + "time-macros 0.2.22", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" @@ -3678,9 +3676,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", diff --git a/clarity/Cargo.toml b/clarity/Cargo.toml index 9077834a70..37b3f0ed6f 100644 --- a/clarity/Cargo.toml +++ b/clarity/Cargo.toml @@ -37,10 +37,6 @@ rusqlite = { workspace = true, optional = true } version = "1.0" features = ["arbitrary_precision", "unbounded_depth"] -[dependencies.time] -version = "0.2.23" -features = ["std"] - [dev-dependencies] assert-json-diff = "1.0.0" mutants = "0.0.3" diff --git a/stacks-common/Cargo.toml b/stacks-common/Cargo.toml index a1a27ba6bf..45afb08452 100644 --- a/stacks-common/Cargo.toml +++ b/stacks-common/Cargo.toml @@ -68,10 +68,6 @@ workspace = true version = "4.1.3" features = ["serde"] -[dependencies.time] -version = "0.2.23" -features = ["std"] - [target.'cfg(not(target_family = "wasm"))'.dependencies] secp256k1 = { version = "0.24.3", features = ["serde", "recovery"] } diff --git a/stacks-common/src/util/mod.rs b/stacks-common/src/util/mod.rs index ca12c85901..1765817f29 100644 --- a/stacks-common/src/util/mod.rs +++ b/stacks-common/src/util/mod.rs @@ -34,8 +34,8 @@ pub mod vrf; use std::fs::File; use std::io::{BufReader, BufWriter, Write}; use std::path::Path; -use std::time::{SystemTime, UNIX_EPOCH}; -use std::{error, fmt, thread, time}; +use std::time::{self, SystemTime, UNIX_EPOCH}; +use std::{error, fmt, thread}; /// Given a relative path inside the Cargo workspace, return the absolute path #[cfg(any(test, feature = "testing"))] diff --git a/stackslib/Cargo.toml b/stackslib/Cargo.toml index c8f4a1fa7f..0e277f165a 100644 --- a/stackslib/Cargo.toml +++ b/stackslib/Cargo.toml @@ -52,6 +52,7 @@ libstackerdb = { path = "../libstackerdb" } siphasher = "0.3.7" hashbrown = { workspace = true } rusqlite = { workspace = true } +time = "0.3.41" toml = { workspace = true } [target.'cfg(not(any(target_os = "macos",target_os="windows", target_arch = "arm" )))'.dependencies] @@ -77,10 +78,6 @@ features = ["serde", "recovery"] [dependencies.ed25519-dalek] workspace = true -[dependencies.time] -version = "0.2.23" -features = ["std"] - [dev-dependencies] assert-json-diff = "1.0.0" stdext = "0.3.1" diff --git a/stackslib/src/net/http/response.rs b/stackslib/src/net/http/response.rs index abb21c984d..774740e292 100644 --- a/stackslib/src/net/http/response.rs +++ b/stackslib/src/net/http/response.rs @@ -17,7 +17,6 @@ use std::collections::{BTreeMap, HashSet}; use std::fmt; use std::io::{Read, Write}; -use std::time::SystemTime; use stacks_common::codec::{Error as CodecError, StacksMessageCodec}; use stacks_common::deps_common::httparse; @@ -347,9 +346,11 @@ impl HttpResponsePreamble { } /// Get an RFC 7231 date that represents the current time -fn rfc7231_now() -> String { - let now = time::PrimitiveDateTime::from(SystemTime::now()); - now.format("%a, %b %-d %-Y %-H:%M:%S GMT") +fn rfc7231_now() -> Result { + time::OffsetDateTime::now_utc() + .format(&time::format_description::well_known::Rfc2822) + .map(|date| date.replace("+0000", "GMT")) + .map_err(|e| CodecError::GenericError(format!("Failed to format RFC 7231 date: {:?}", e))) } /// Read from a stream until we see '\r\n\r\n', with the purpose of reading an HTTP preamble. @@ -387,7 +388,7 @@ impl StacksMessageCodec for HttpResponsePreamble { if !self.headers.contains_key("date") { fd.write_all("Date: ".as_bytes()) .map_err(CodecError::WriteError)?; - fd.write_all(rfc7231_now().as_bytes()) + fd.write_all(rfc7231_now()?.as_bytes()) .map_err(CodecError::WriteError)?; fd.write_all("\r\n".as_bytes()) .map_err(CodecError::WriteError)?; diff --git a/stackslib/src/net/http/tests.rs b/stackslib/src/net/http/tests.rs index 3952187a4f..e9e4661587 100644 --- a/stackslib/src/net/http/tests.rs +++ b/stackslib/src/net/http/tests.rs @@ -16,6 +16,7 @@ use std::collections::BTreeMap; +use regex; use stacks_common::codec::{Error as CodecError, StacksMessageCodec}; use stacks_common::types::net::{PeerAddress, PeerHost}; @@ -146,7 +147,7 @@ fn test_parse_http_request_preamble_ok() { ("POST asdf HTTP/1.1\r\nHost: core.blockstack.org\r\nConnection: close\r\nFoo: Bar\r\n\r\n", HttpRequestPreamble::from_headers(HttpVersion::Http11, "POST".to_string(), "asdf".to_string(), "core.blockstack.org".to_string(), 80, false, vec!["foo".to_string()], vec!["Bar".to_string()])), ("POST asdf HTTP/1.1\r\nHost: core.blockstack.org\r\nFoo: Bar\r\nConnection: close\r\n\r\n", - HttpRequestPreamble::from_headers(HttpVersion::Http11, "POST".to_string(), "asdf".to_string(), "core.blockstack.org".to_string(), 80, false, vec!["foo".to_string()], vec!["Bar".to_string()])) + HttpRequestPreamble::from_headers(HttpVersion::Http11, "POST".to_string(), "asdf".to_string(), "core.blockstack.org".to_string(), 80, false, vec!["foo".to_string()], vec!["Bar".to_string()])) ]; for (data, request) in tests.iter() { @@ -391,6 +392,14 @@ fn test_http_response_preamble_headers() { "Content-Type is missing" ); assert!(txt.find("Date: ").is_some(), "Date header is missing"); + + let rfc7231_date_regex = + regex::Regex::new(r"Date: [A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} GMT\r\n") + .unwrap(); + assert!( + rfc7231_date_regex.is_match(&txt), + "Date header format is incorrect" + ); assert!(txt.find("foo: bar\r\n").is_some(), "foo header is missing"); assert!( txt.find("Access-Control-Allow-Origin: *\r\n").is_some(),