55// Please see LICENSE in the repository root for full details.
66
77use std:: {
8- future:: ready,
98 net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr , TcpListener , ToSocketAddrs } ,
109 os:: unix:: net:: UnixListener ,
10+ time:: Duration ,
1111} ;
1212
1313use anyhow:: Context ;
1414use axum:: {
1515 Extension , Router ,
16- error_handling:: HandleErrorLayer ,
1716 extract:: { FromRef , MatchedPath } ,
1817} ;
19- use headers:: { HeaderMapExt as _, UserAgent } ;
20- use hyper:: {
21- Method , Request , Response , StatusCode , Version ,
22- header:: { CACHE_CONTROL , HeaderValue , USER_AGENT } ,
23- } ;
18+ use headers:: { CacheControl , HeaderMapExt as _, UserAgent } ;
19+ use hyper:: { Method , Request , Response , StatusCode , Version , header:: USER_AGENT } ;
2420use listenfd:: ListenFd ;
2521use mas_config:: { HttpBindConfig , HttpResource , HttpTlsConfig , UnixOrTcp } ;
2622use mas_context:: LogContext ;
@@ -40,7 +36,7 @@ use opentelemetry_semantic_conventions::trace::{
4036use rustls:: ServerConfig ;
4137use sentry_tower:: { NewSentryLayer , SentryHttpLayer } ;
4238use tower:: Layer ;
43- use tower_http:: { services:: ServeDir , set_header :: SetResponseHeaderLayer } ;
39+ use tower_http:: services:: { ServeDir , fs :: ServeFileSystemResponseBody } ;
4440use tracing:: Span ;
4541use tracing_opentelemetry:: OpenTelemetrySpanExt ;
4642
@@ -209,6 +205,7 @@ async fn log_response_middleware(
209205 response
210206}
211207
208+ #[ allow( clippy:: too_many_lines) ]
212209pub fn build_router (
213210 state : AppState ,
214211 resources : & [ HttpResource ] ,
@@ -246,17 +243,28 @@ pub fn build_router(
246243 . precompressed_gzip ( )
247244 . precompressed_deflate ( ) ;
248245
249- let error_layer =
250- HandleErrorLayer :: new ( |_e| ready ( StatusCode :: INTERNAL_SERVER_ERROR ) ) ;
251-
252- let cache_layer = SetResponseHeaderLayer :: overriding (
253- CACHE_CONTROL ,
254- HeaderValue :: from_static ( "public, max-age=31536000, immutable" ) ,
246+ let add_cache_headers = axum:: middleware:: map_response (
247+ async |mut res : Response < ServeFileSystemResponseBody > | {
248+ let cache_control = if res. status ( ) == StatusCode :: NOT_FOUND {
249+ // Cache 404s for 5 minutes
250+ CacheControl :: new ( )
251+ . with_public ( )
252+ . with_max_age ( Duration :: from_secs ( 5 * 60 ) )
253+ } else {
254+ // Cache assets for 1 year
255+ CacheControl :: new ( )
256+ . with_public ( )
257+ . with_max_age ( Duration :: from_secs ( 365 * 24 * 60 * 60 ) )
258+ . with_immutable ( )
259+ } ;
260+ res. headers_mut ( ) . typed_insert ( cache_control) ;
261+ res
262+ } ,
255263 ) ;
256264
257265 router. nest_service (
258266 mas_router:: StaticAsset :: route ( ) ,
259- ( error_layer , cache_layer ) . layer ( static_service) ,
267+ add_cache_headers . layer ( static_service) ,
260268 )
261269 }
262270 mas_config:: HttpResource :: OAuth => router. merge ( mas_handlers:: api_router :: < AppState > ( ) ) ,
0 commit comments