use axum::{ body::Body, http::{header, Response}, response::IntoResponse, }; // ─── Cache Policy Constants ─────────────────────────────────────────────────── /// Authenticated user data — never cache at CDN layer. pub const CACHE_PRIVATE: &str = "private, no-store"; /// Short-lived public data (60s). Ideal for dashboard summaries and analytics. /// `s-maxage` instructs CDN; `stale-while-revalidate` allows background refresh. pub const CACHE_SHORT: &str = "public, max-age=60, s-maxage=60, stale-while-revalidate=30"; /// Medium-lived public data (5 min). For product listings and storefront pages. pub const CACHE_MEDIUM: &str = "public, max-age=300, s-maxage=300, stale-while-revalidate=60"; /// Immutable long-lived content (24h). For static assets with content hashes. pub const CACHE_LONG: &str = "public, max-age=86400, s-maxage=86400, immutable"; /// Always revalidate — for exports and reports that must be fresh. pub const CACHE_REVALIDATE: &str = "public, max-age=0, must-revalidate"; // ─── Helpers ───────────────────────────────────────────────────────────────── /// Inject `Cache-Control` and `Vary: Accept-Encoding` headers into any response. pub fn with_cache(response: R, policy: &'static str) -> Response { let mut res = response.into_response(); let headers = res.headers_mut(); headers.insert( header::CACHE_CONTROL, header::HeaderValue::from_static(policy), ); headers.insert( header::VARY, header::HeaderValue::from_static("Accept-Encoding"), ); res } /// Add ETag derived from a resource version/timestamp for conditional GETs. pub fn with_etag(response: R, version: &str) -> Response { let etag = format!("\"{}\"", version); let mut res = response.into_response(); if let Ok(value) = header::HeaderValue::from_str(&etag) { res.headers_mut().insert(header::ETAG, value); } res } /// Combine cache policy and ETag in one call. pub fn with_cache_and_etag( response: R, policy: &'static str, version: &str, ) -> Response { let etag = format!("\"{}\"", version); let mut res = response.into_response(); let headers = res.headers_mut(); headers.insert( header::CACHE_CONTROL, header::HeaderValue::from_static(policy), ); headers.insert( header::VARY, header::HeaderValue::from_static("Accept-Encoding"), ); if let Ok(value) = header::HeaderValue::from_str(&etag) { headers.insert(header::ETAG, value); } res }