diff --git a/Cargo.toml b/Cargo.toml index 37ec9f26..653f690b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ tokio-stream = { version = "0.1.18", features = ["fs"] } bytes = "1.11.1" tempfile = "3.25.0" tower = "0.5.3" -tower-http = { version = "0.6.8", features = ["fs", "compression-gzip", "trace", "cors", "add-extension", "request-id"] } +tower-http = { version = "0.6.8", features = ["fs", "compression-gzip", "trace", "cors", "add-extension", "request-id", "set-header"] } flate2 = "1.1.9" zip = "=6.0.0" tracing = "0.1.44" diff --git a/src/interfaces/web/mod.rs b/src/interfaces/web/mod.rs index 729a16a0..ad480340 100644 --- a/src/interfaces/web/mod.rs +++ b/src/interfaces/web/mod.rs @@ -1,7 +1,10 @@ use crate::common::config::AppConfig; use crate::common::di::AppState; +use axum::http::header::{CACHE_CONTROL, HeaderValue}; use axum::{Router, response::Html, routing::get}; +use tower_http::compression::CompressionLayer; use tower_http::services::ServeDir; +use tower_http::set_header::SetResponseHeaderLayer; /// Creates web routes for serving static files pub fn create_web_routes() -> Router { @@ -9,14 +12,25 @@ pub fn create_web_routes() -> Router { let config = AppConfig::from_env(); let static_path = config.static_path.clone(); + // Static assets (JS, CSS, JSON, SVG, ICO) served via ServeDir + // with gzip compression and aggressive caching (7 days). + // HTML pages are served via explicit routes (include_str!) and + // do NOT pass through these layers. + let static_service = ServeDir::new(static_path); + Router::new() // Add specific routes for clean URLs (without .html) .route("/login", get(serve_login_page)) .route("/profile", get(serve_profile_page)) .route("/admin", get(serve_admin_page)) .route("/shared", get(serve_shared_page)) - // Serve static files - .fallback_service(ServeDir::new(static_path)) + // Serve static files with compression + cache headers + .fallback_service(static_service) + .layer(CompressionLayer::new()) + .layer(SetResponseHeaderLayer::if_not_present( + CACHE_CONTROL, + HeaderValue::from_static("public, max-age=604800, stale-while-revalidate=86400"), + )) } /// Serve the login page