diff --git a/src/web/cache.rs b/src/web/cache.rs index cd05eee37..b9b5a40a1 100644 --- a/src/web/cache.rs +++ b/src/web/cache.rs @@ -6,6 +6,7 @@ use http::{header::CACHE_CONTROL, HeaderValue}; use std::sync::Arc; pub static NO_CACHING: HeaderValue = HeaderValue::from_static("max-age=0"); +pub static SHORT: HeaderValue = HeaderValue::from_static("max-age=60"); pub static NO_STORE_MUST_REVALIDATE: HeaderValue = HeaderValue::from_static("no-cache, no-store, must-revalidate, max-age=0"); @@ -24,7 +25,12 @@ pub enum CachePolicy { /// * enforce revalidation /// * never store NoStoreMustRevalidate, - /// cache forever in browser & CDN. + /// cache for a short time in the browser & CDN. + /// right now: one minute. + /// Can be used when the content can be a _little_ outdated, + /// while protecting agains spikes in traffic. + ShortInCdnAndBrowser, + /// cache forever in browser & CDN. /// Valid when you have hashed / versioned filenames and every rebuild would /// change the filename. ForeverInCdnAndBrowser, @@ -46,6 +52,7 @@ impl CachePolicy { match *self { CachePolicy::NoCaching => Some(NO_CACHING.clone()), CachePolicy::NoStoreMustRevalidate => Some(NO_STORE_MUST_REVALIDATE.clone()), + CachePolicy::ShortInCdnAndBrowser => Some(SHORT.clone()), CachePolicy::ForeverInCdnAndBrowser => Some(FOREVER_IN_CDN_AND_BROWSER.clone()), CachePolicy::ForeverInCdn => { if config.cache_invalidatable_responses { diff --git a/src/web/releases.rs b/src/web/releases.rs index 6aaf48065..b1c4a22d1 100644 --- a/src/web/releases.rs +++ b/src/web/releases.rs @@ -30,6 +30,8 @@ use std::sync::Arc; use tracing::{debug, warn}; use url::form_urlencoded; +use super::cache::CachePolicy; + /// Number of release in home page const RELEASES_IN_HOME: i64 = 15; /// Releases in /releases page @@ -271,6 +273,7 @@ struct HomePage { impl_axum_webpage! { HomePage = "core/home.html", + cache_policy = |_| CachePolicy::ShortInCdnAndBrowser, } pub(crate) async fn home_page(mut conn: DbConnection) -> AxumResult { @@ -719,7 +722,8 @@ mod tests { use super::*; use crate::registry_api::CrateOwner; use crate::test::{ - assert_redirect, assert_redirect_unchecked, assert_success, wrapper, TestFrontend, + assert_cache_control, assert_redirect, assert_redirect_unchecked, assert_success, wrapper, + TestFrontend, }; use anyhow::Error; use chrono::{Duration, TimeZone}; @@ -1484,6 +1488,8 @@ mod tests { seen.insert("".to_owned()); let resp = web.get("").send()?; + assert_cache_control(&resp, CachePolicy::ShortInCdnAndBrowser, &env.config()); + assert!(resp.status().is_success()); let html = kuchikiki::parse_html().one(resp.text()?); diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index d019ea89e..3f28fdeee 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -1013,7 +1013,7 @@ mod test { .build_result_failed() .create()?; let web = env.frontend(); - assert_success_cached("/", web, CachePolicy::NoCaching, &env.config())?; + assert_success_cached("/", web, CachePolicy::ShortInCdnAndBrowser, &env.config())?; assert_success_cached( "/crate/buggy/0.1.0/", web,