From 690d0ed1bb3c9d3b22e3b50aebbcd4bb3b3764d0 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 29 Dec 2021 16:17:38 +0000 Subject: [PATCH] Add our own HTTP date formatter --- Cargo.lock | 1 - Cargo.toml | 1 - src/util.rs | 19 +++++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a048db5..8af4f0ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3295,7 +3295,6 @@ dependencies = [ "governor", "handlebars", "html5ever", - "httpdate", "idna 0.2.3", "job_scheduler", "jsonwebtoken", diff --git a/Cargo.toml b/Cargo.toml index 82c96386..f6ff7f68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,6 @@ uuid = { version = "0.8.2", features = ["v4"] } chrono = { version = "0.4.19", features = ["serde"] } chrono-tz = "0.6.1" time = "0.2.27" -httpdate = "1.0" # Job scheduler job_scheduler = "1.2.1" diff --git a/src/util.rs b/src/util.rs index 1d70e097..0b287ccf 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,9 +11,8 @@ use rocket::{ Data, Request, Response, Rocket, }; -use httpdate::HttpDate; use std::thread::sleep; -use std::time::{Duration, SystemTime}; +use std::time::Duration; use crate::CONFIG; @@ -143,12 +142,13 @@ impl<'r, R: Responder<'r>> Responder<'r> for Cached { format!("public, max-age={}", self.ttl) }; - let time_now = SystemTime::now(); + let time_now = chrono::Local::now(); match self.response.respond_to(req) { Ok(mut res) => { res.set_raw_header("Cache-Control", cache_control_header); - res.set_raw_header("Expires", HttpDate::from(time_now + Duration::from_secs(self.ttl)).to_string()); + let expiry_time = time_now + chrono::Duration::seconds(self.ttl.try_into().unwrap()); + res.set_raw_header("Expires", format_datetime_http(&expiry_time)); Ok(res) } e @ Err(_) => e, @@ -436,6 +436,17 @@ pub fn format_naive_datetime_local(dt: &NaiveDateTime, fmt: &str) -> String { format_datetime_local(&Local.from_utc_datetime(dt), fmt) } +/// Formats a `DateTime` as required for HTTP +/// +/// https://httpwg.org/specs/rfc7231.html#http.date +pub fn format_datetime_http(dt: &DateTime) -> String { + let expiry_time: chrono::DateTime = chrono::DateTime::from_utc(dt.naive_utc(), chrono::Utc); + + // HACK: HTTP expects the date to always be GMT (UTC) rather than giving an + // offset (which would always be 0 in UTC anyway) + return expiry_time.to_rfc2822().replace("+0000", "GMT"); +} + // // Deployment environment methods //