spa.rs
⎇
Raw
1use axum::http::Uri;
2use axum::http::{header, Method, StatusCode};
3use axum::response::{IntoResponse, Response};
4
5const DEV_HINT: &str = r#"<!doctype html>
6<html lang="en"><head><meta charset="utf-8"><title>filebrowser-ng</title></head>
7<body style="font-family:system-ui;display:grid;place-items:center;min-height:100vh;margin:0;background:#f6f7f9">
8<div style="max-width:520px;padding:24px;border:1px solid #e5e7eb;border-radius:12px;background:#fff">
9<h1>filebrowser-ng</h1>
10<p>The frontend has not been built yet.</p>
11<p>In development, run <code>just dev-web</code> in a second terminal and open
12<code>http://localhost:8080</code> (Trunk serves the app and proxies <code>/api</code> to this backend).</p>
13<p>If you hit this page directly from the backend, make sure Trunk's output
14directory is visible — the server looks in <code>target/web</code> or <code>$FBNG_DIST</code>.</p>
15<p>For the production single binary: <code>just build</code>.</p>
16</div></body></html>"#;
17
18/// Serve the frontend: static assets, with a fallback to index.html so that
19/// client-side routes (e.g. `/s/<token>`) work.
20pub(super) async fn fallback(method: Method, uri: Uri) -> Response {
21 let path = uri.path();
22 if path.starts_with("/api/") {
23 return (StatusCode::NOT_FOUND, "unknown endpoint").into_response();
24 }
25 if method != Method::GET && method != Method::HEAD {
26 return StatusCode::METHOD_NOT_ALLOWED.into_response();
27 }
28
29 let rel = path.trim_start_matches('/');
30 let asset = if rel.is_empty() {
31 crate::assets::get_asset("index.html")
32 } else {
33 crate::assets::get_asset(rel)
34 };
35
36 match asset {
37 Some((bytes, mime, cache)) => {
38 (
39 [(header::CONTENT_TYPE, mime), (header::CACHE_CONTROL, cache)],
40 bytes,
41 )
42 .into_response()
43 }
44 None => match crate::assets::get_asset("index.html") {
45 Some((bytes, mime, _)) => {
46 ([(header::CONTENT_TYPE, mime), (header::CACHE_CONTROL, "no-cache".to_string())], bytes)
47 .into_response()
48 }
49 None => DEV_HINT.into_response(),
50 },
51 }
52}
53