use rust_embed::Embed;
use salvo::http::header::{CACHE_CONTROL, CONTENT_TYPE};
use salvo::http::ResBody;
use salvo::prelude::*;
#[derive(Embed)]
#[folder = "static/"]
struct AdminUiAssets;
#[handler]
async fn serve_admin_ui(req: &mut Request, res: &mut Response) {
let path = req.param::<String>("path").unwrap_or_default();
let path = path.trim_start_matches('/');
let path = if path.is_empty() { "index.html" } else { path };
match AdminUiAssets::get(path) {
Some(content) => {
serve_embedded_file(res, path, &content.data);
}
None => {
if let Some(index) = AdminUiAssets::get("index.html") {
serve_embedded_file(res, "index.html", &index.data);
} else {
res.status_code(StatusCode::NOT_FOUND);
res.render(Text::Plain("404 Not Found"));
}
}
}
}
fn serve_embedded_file(res: &mut Response, path: &str, data: &[u8]) {
let mime_type = mime_guess::from_path(path)
.first_or_octet_stream()
.to_string();
res.headers_mut()
.insert(CONTENT_TYPE, mime_type.parse().unwrap());
let cache_control = if path == "index.html" {
"no-cache, no-store, must-revalidate"
} else if path.starts_with("assets/") {
"public, max-age=31536000, immutable"
} else {
"public, max-age=3600"
};
res.headers_mut()
.insert(CACHE_CONTROL, cache_control.parse().unwrap());
res.body(ResBody::Once(data.to_vec().into()));
}
pub fn auth_admin_ui_router() -> Router {
Router::with_path("auth-admin/ui")
.get(serve_admin_ui_entry)
.push(Router::with_path("{**path}").get(serve_admin_ui))
}
#[handler]
async fn serve_admin_ui_entry(req: &mut Request, res: &mut Response) {
let path = req.uri().path().to_string();
if !path.ends_with('/') {
res.render(Redirect::other(format!("{}/", path)));
} else if let Some(index) = AdminUiAssets::get("index.html") {
serve_embedded_file(res, "index.html", &index.data);
} else {
res.status_code(StatusCode::NOT_FOUND);
res.render(Text::Plain("404 Not Found"));
}
}