This commit is contained in:
+17
-14
@@ -20,19 +20,13 @@ use thiserror::Error;
|
||||
use tower_http::trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer};
|
||||
use tracing::{Level, error, warn};
|
||||
|
||||
use crate::assets;
|
||||
use crate::domain::{DomainError, SessionUser};
|
||||
use crate::ports::{HubEvent, RealtimeNotifier};
|
||||
use crate::services::{AuthService, InvitationService, ListService, MealService};
|
||||
use crate::views;
|
||||
use crate::webauthn::WebAuthnService;
|
||||
|
||||
/// The contents of `static/`, embedded into the binary at compile time so the
|
||||
/// app can be shipped as a single executable without a separate static directory.
|
||||
const STYLE_CSS: &[u8] = include_bytes!("../static/style.css");
|
||||
const PASSKEY_LOGIN_JS: &[u8] = include_bytes!("../static/passkey-login.js");
|
||||
const PASSKEY_REGISTER_JS: &[u8] = include_bytes!("../static/passkey-register.js");
|
||||
const PASSWORD_TOGGLE_JS: &[u8] = include_bytes!("../static/password-toggle.js");
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub auth: Arc<AuthService>,
|
||||
@@ -340,15 +334,24 @@ async fn home() -> Redirect {
|
||||
}
|
||||
|
||||
/// Serves a file embedded in the binary from the `static/` folder.
|
||||
///
|
||||
/// Every asset is served with an immutable, long-lived cache header. Because
|
||||
/// the HTML references each asset under a URL that is versioned by its content
|
||||
/// hash, a changed file gets a new URL and the cache is never stale.
|
||||
async fn static_asset(Path(path): Path<String>) -> Response {
|
||||
let (mime, data) = match path.as_str() {
|
||||
"style.css" => ("text/css", STYLE_CSS),
|
||||
"passkey-login.js" => ("application/javascript", PASSKEY_LOGIN_JS),
|
||||
"passkey-register.js" => ("application/javascript", PASSKEY_REGISTER_JS),
|
||||
"password-toggle.js" => ("application/javascript", PASSWORD_TOGGLE_JS),
|
||||
_ => return StatusCode::NOT_FOUND.into_response(),
|
||||
let Some(asset) = assets::STORE.get(&path) else {
|
||||
return StatusCode::NOT_FOUND.into_response();
|
||||
};
|
||||
([(header::CONTENT_TYPE, mime)], data).into_response()
|
||||
let mime = match path.as_str() {
|
||||
"style.css" => "text/css",
|
||||
_ => "application/javascript",
|
||||
};
|
||||
let mut response = ([(header::CONTENT_TYPE, mime)], asset.data).into_response();
|
||||
response.headers_mut().insert(
|
||||
header::CACHE_CONTROL,
|
||||
HeaderValue::from_static("public, max-age=31536000, immutable"),
|
||||
);
|
||||
response
|
||||
}
|
||||
|
||||
async fn log_response_status(request: Request, next: Next) -> Response {
|
||||
|
||||
Reference in New Issue
Block a user