Skip to content

Commit 613fab6

Browse files
committed
add optional embed-static feature
1 parent ba1a0a6 commit 613fab6

File tree

4 files changed

+98
-3
lines changed

4 files changed

+98
-3
lines changed

Cargo.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ nibbletree = { version = "0.1.0", path = "./nibbletree", features = ["ipnet"] }
3333
autometrics = { version = "0.3.0", features = ["prometheus-exporter"] }
3434
zettabgp = "0.3.4"
3535
hickory-resolver = "0.24.0"
36+
include_dir = { version = "0.7.3", optional = true }
37+
mime_guess = { version = "2.0.4", optional = true }
3638

3739
[[bin]]
3840
name = "fernglas-configcheck"
3941
path = "src/config_check.rs"
42+
43+
[features]
44+
embed-static = ["include_dir", "mime_guess"]

flake.nix

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
rustPlatform.buildRustPackage {
1414
pname = "fernglas";
15+
16+
preBuild = ''
17+
cp -r ${final.buildPackages.fernglas-frontend} ./static
18+
'';
19+
1520
version =
1621
self.shortRev or "dirty-${toString self.lastModifiedDate}";
1722
src = lib.cleanSourceWith {
@@ -25,7 +30,11 @@
2530
};
2631
};
2732

28-
cargoBuildFlags = lib.optionals (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isStatic) [ "--features" "mimalloc" ];
33+
cargoBuildFlags = lib.optionals (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isStatic) [
34+
"--features" "mimalloc"
35+
] ++ [
36+
"--features" "embed-static"
37+
];
2938
cargoLock = {
3039
lockFile = ./Cargo.lock;
3140
allowBuiltinFetchGit = true;

src/api.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ use std::convert::Infallible;
1717
use std::net::SocketAddr;
1818
use std::sync::Arc;
1919

20+
#[cfg(feature = "embed-static")]
21+
static STATIC_DIR: include_dir::Dir<'_> = include_dir::include_dir!("$CARGO_MANIFEST_DIR/static");
22+
2023
#[derive(Debug, Clone, Deserialize)]
2124
pub struct ApiServerConfig {
2225
bind: SocketAddr,
2326
#[serde(default)]
2427
query_limits: QueryLimits,
28+
#[cfg(feature = "embed-static")]
29+
#[serde(default)]
30+
serve_static: bool,
2531
}
2632

2733
#[derive(Debug, Clone, Serialize)]
@@ -157,14 +163,49 @@ pub async fn get_metrics() -> (StatusCode, String) {
157163
}
158164
}
159165

166+
#[cfg(feature = "embed-static")]
167+
async fn static_path(axum::extract::Path(path): axum::extract::Path<String>) -> impl IntoResponse {
168+
use axum::body::Full;
169+
use axum::body::Empty;
170+
use axum::http::header;
171+
use axum::http::header::HeaderValue;
172+
173+
let path = path.trim_start_matches('/');
174+
let mime_type = mime_guess::from_path(path).first_or_text_plain();
175+
176+
match STATIC_DIR.get_file(path) {
177+
None => Response::builder()
178+
.status(StatusCode::NOT_FOUND)
179+
.body(axum::body::boxed(Empty::new()))
180+
.unwrap(),
181+
Some(file) => Response::builder()
182+
.status(StatusCode::OK)
183+
.header(
184+
header::CONTENT_TYPE,
185+
HeaderValue::from_str(mime_type.as_ref()).unwrap(),
186+
)
187+
.body(axum::body::boxed(Full::from(file.contents())))
188+
.unwrap(),
189+
}
190+
}
191+
160192
pub async fn run_api_server<T: Store>(
161193
cfg: ApiServerConfig,
162194
store: T,
163195
mut shutdown: tokio::sync::watch::Receiver<bool>,
164196
) -> anyhow::Result<()> {
165-
let make_service = Router::new()
197+
let mut router = Router::new();
198+
199+
#[cfg(feature = "embed-static")]
200+
if cfg.serve_static {
201+
router = router.route("/*path", get(static_path))
202+
}
203+
204+
router = router
166205
.nest("/api", make_api(cfg.clone(), store)?)
167-
.route("/metrics", get(get_metrics))
206+
.route("/metrics", get(get_metrics));
207+
208+
let make_service = router
168209
.into_make_service();
169210

170211
axum::Server::bind(&cfg.bind)

0 commit comments

Comments
 (0)