Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
002e51f36e |
Generated
+1
@@ -2574,6 +2574,7 @@ dependencies = [
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
|
||||
+2
-1
@@ -37,7 +37,8 @@ tempfile = "3"
|
||||
time = "0.3"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-util = { version = "0.7", features = ["io"] }
|
||||
tower-http = { version = "0.6", features = ["fs", "trace"] }
|
||||
tower = { version = "0.5", features = ["util"] }
|
||||
tower-http = { version = "0.6", features = ["fs", "set-header", "trace"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
urlencoding = "2"
|
||||
|
||||
+26
-3
@@ -1,4 +1,8 @@
|
||||
use axum::http::{header, HeaderValue};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::services::fs::ServeFileSystemResponseBody;
|
||||
use tower_http::services::{ServeDir, ServeFile};
|
||||
use tower_http::set_header::SetResponseHeaderLayer;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
@@ -17,11 +21,30 @@ async fn main() -> anyhow::Result<()> {
|
||||
let state = AppState::new(config).await?;
|
||||
|
||||
let static_dir = state.config.static_dir.clone();
|
||||
let index = std::path::Path::new(&static_dir).join("index.html");
|
||||
// .fallback (not .not_found_service) so SPA routes get index.html with a 200
|
||||
let spa = ServeDir::new(&static_dir).fallback(ServeFile::new(index));
|
||||
let static_root = std::path::Path::new(&static_dir);
|
||||
// Hashed assets cache forever — except 404s, which would outlive the next deploy.
|
||||
let assets = ServiceBuilder::new()
|
||||
.map_response(|mut response: axum::http::Response<ServeFileSystemResponseBody>| {
|
||||
if response.status().is_success() {
|
||||
response.headers_mut().insert(
|
||||
header::CACHE_CONTROL,
|
||||
HeaderValue::from_static("public, max-age=31536000, immutable"),
|
||||
);
|
||||
}
|
||||
response
|
||||
})
|
||||
.service(ServeDir::new(static_root.join("assets")));
|
||||
// index.html revalidates every load (it names the asset hashes);
|
||||
// .fallback (not .not_found_service) so SPA routes get it with a 200.
|
||||
let spa = ServiceBuilder::new()
|
||||
.layer(SetResponseHeaderLayer::overriding(
|
||||
header::CACHE_CONTROL,
|
||||
HeaderValue::from_static("no-cache"),
|
||||
))
|
||||
.service(ServeDir::new(static_root).fallback(ServeFile::new(static_root.join("index.html"))));
|
||||
|
||||
let app = photos::routes::router(&state)
|
||||
.nest_service("/assets", assets)
|
||||
.fallback_service(spa)
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.with_state(state.clone());
|
||||
|
||||
Reference in New Issue
Block a user