set csp and cache-control headers appropriately

This commit is contained in:
Brent Schroeter 2025-03-22 01:03:04 -07:00
parent 9d543eedd8
commit 377035ce88
3 changed files with 37 additions and 6 deletions

View file

@ -27,7 +27,7 @@ serde = { version = "1.0.213", features = ["derive"] }
serde_json = "1.0.132" serde_json = "1.0.132"
tokio = { version = "1.42.0", features = ["full"] } tokio = { version = "1.42.0", features = ["full"] }
tower = "0.5.2" tower = "0.5.2"
tower-http = { version = "0.6.2", features = ["compression-gzip", "fs", "normalize-path", "trace"] } tower-http = { version = "0.6.2", features = ["compression-gzip", "fs", "normalize-path", "set-header", "trace"] }
tracing = "0.1.40" tracing = "0.1.40"
tracing-subscriber = { version = "0.3.19", features = ["chrono", "env-filter"] } tracing-subscriber = { version = "0.3.19", features = ["chrono", "env-filter"] }
uuid = { version = "1.11.0", features = ["serde", "v4", "v7"] } uuid = { version = "1.11.0", features = ["serde", "v4", "v7"] }

View file

@ -1,11 +1,15 @@
use anyhow::Result; use anyhow::Result;
use axum::middleware::map_request; use axum::{
http::{header::CONTENT_SECURITY_POLICY, HeaderValue},
middleware::map_request,
};
use chrono::{TimeDelta, Utc}; use chrono::{TimeDelta, Utc};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use tokio::time::sleep; use tokio::time::sleep;
use tower::ServiceBuilder; use tower::ServiceBuilder;
use tower_http::{ use tower_http::{
compression::CompressionLayer, normalize_path::NormalizePathLayer, trace::TraceLayer, compression::CompressionLayer, normalize_path::NormalizePathLayer,
set_header::response::SetResponseHeaderLayer, trace::TraceLayer,
}; };
use crate::{ use crate::{
@ -42,7 +46,11 @@ pub async fn serve_command(state: AppState) -> Result<()> {
.layer(map_request(lowercase_uri_path)) .layer(map_request(lowercase_uri_path))
.layer(TraceLayer::new_for_http()) .layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new()) .layer(CompressionLayer::new())
.layer(NormalizePathLayer::trim_trailing_slash()), .layer(NormalizePathLayer::trim_trailing_slash())
.layer(SetResponseHeaderLayer::if_not_present(
CONTENT_SECURITY_POLICY,
HeaderValue::from_static("frame-ancestors 'none'"),
)),
); );
let listener = let listener =

View file

@ -1,10 +1,15 @@
use axum::{ use axum::{
extract::State, extract::State,
http::{header::CACHE_CONTROL, HeaderValue},
response::{IntoResponse, Redirect}, response::{IntoResponse, Redirect},
routing::get, routing::get,
Router, Router,
}; };
use tower_http::services::{ServeDir, ServeFile}; use tower::ServiceBuilder;
use tower_http::{
services::{ServeDir, ServeFile},
set_header::SetResponseHeaderLayer,
};
use crate::{ use crate::{
app_state::AppState, auth, channels_router, projects_router, settings::Settings, teams_router, app_state::AppState, auth, channels_router, projects_router, settings::Settings, teams_router,
@ -20,8 +25,26 @@ pub fn new_router(state: AppState) -> Router<()> {
.merge(teams_router::new_router()) .merge(teams_router::new_router())
.merge(v0_router::new_router()) .merge(v0_router::new_router())
.nest("/auth", auth::new_router()) .nest("/auth", auth::new_router())
.layer(SetResponseHeaderLayer::if_not_present(
CACHE_CONTROL,
HeaderValue::from_static("no-cache"),
))
.fallback_service( .fallback_service(
ServeDir::new("static").not_found_service(ServeFile::new("static/_404.html")), ServiceBuilder::new()
.layer(SetResponseHeaderLayer::if_not_present(
CACHE_CONTROL,
HeaderValue::from_static("max-age=21600, stale-while-revalidate=86400"),
))
.service(
ServeDir::new("static").not_found_service(
ServiceBuilder::new()
.layer(SetResponseHeaderLayer::if_not_present(
CACHE_CONTROL,
HeaderValue::from_static("no-cache"),
))
.service(ServeFile::new("static/_404.html")),
),
),
) )
.with_state(state); .with_state(state);
if base_path.is_empty() { if base_path.is_empty() {