Skip to content

Commit

Permalink
add optional embed-static feature
Browse files Browse the repository at this point in the history
  • Loading branch information
yu-re-ka committed Nov 22, 2023
1 parent ba1a0a6 commit 613fab6
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 3 deletions.
40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ nibbletree = { version = "0.1.0", path = "./nibbletree", features = ["ipnet"] }
autometrics = { version = "0.3.0", features = ["prometheus-exporter"] }
zettabgp = "0.3.4"
hickory-resolver = "0.24.0"
include_dir = { version = "0.7.3", optional = true }
mime_guess = { version = "2.0.4", optional = true }

[[bin]]
name = "fernglas-configcheck"
path = "src/config_check.rs"

[features]
embed-static = ["include_dir", "mime_guess"]
11 changes: 10 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

rustPlatform.buildRustPackage {
pname = "fernglas";

preBuild = ''
cp -r ${final.buildPackages.fernglas-frontend} ./static
'';

version =
self.shortRev or "dirty-${toString self.lastModifiedDate}";
src = lib.cleanSourceWith {
Expand All @@ -25,7 +30,11 @@
};
};

cargoBuildFlags = lib.optionals (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isStatic) [ "--features" "mimalloc" ];
cargoBuildFlags = lib.optionals (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isStatic) [
"--features" "mimalloc"
] ++ [
"--features" "embed-static"
];
cargoLock = {
lockFile = ./Cargo.lock;
allowBuiltinFetchGit = true;
Expand Down
45 changes: 43 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ use std::convert::Infallible;
use std::net::SocketAddr;
use std::sync::Arc;

#[cfg(feature = "embed-static")]
static STATIC_DIR: include_dir::Dir<'_> = include_dir::include_dir!("$CARGO_MANIFEST_DIR/static");

#[derive(Debug, Clone, Deserialize)]
pub struct ApiServerConfig {
bind: SocketAddr,
#[serde(default)]
query_limits: QueryLimits,
#[cfg(feature = "embed-static")]
#[serde(default)]
serve_static: bool,
}

#[derive(Debug, Clone, Serialize)]
Expand Down Expand Up @@ -157,14 +163,49 @@ pub async fn get_metrics() -> (StatusCode, String) {
}
}

#[cfg(feature = "embed-static")]
async fn static_path(axum::extract::Path(path): axum::extract::Path<String>) -> impl IntoResponse {
use axum::body::Full;
use axum::body::Empty;
use axum::http::header;
use axum::http::header::HeaderValue;

let path = path.trim_start_matches('/');
let mime_type = mime_guess::from_path(path).first_or_text_plain();

match STATIC_DIR.get_file(path) {
None => Response::builder()
.status(StatusCode::NOT_FOUND)
.body(axum::body::boxed(Empty::new()))
.unwrap(),
Some(file) => Response::builder()
.status(StatusCode::OK)
.header(
header::CONTENT_TYPE,
HeaderValue::from_str(mime_type.as_ref()).unwrap(),
)
.body(axum::body::boxed(Full::from(file.contents())))
.unwrap(),
}
}

pub async fn run_api_server<T: Store>(
cfg: ApiServerConfig,
store: T,
mut shutdown: tokio::sync::watch::Receiver<bool>,
) -> anyhow::Result<()> {
let make_service = Router::new()
let mut router = Router::new();

#[cfg(feature = "embed-static")]
if cfg.serve_static {
router = router.route("/*path", get(static_path))
}

router = router
.nest("/api", make_api(cfg.clone(), store)?)
.route("/metrics", get(get_metrics))
.route("/metrics", get(get_metrics));

let make_service = router
.into_make_service();

axum::Server::bind(&cfg.bind)
Expand Down

0 comments on commit 613fab6

Please sign in to comment.