use hyper::{Body, Response, StatusCode};
use rust_embed::Embed;
#[derive(Embed)]
#[folder = "src/server/dashboard/static/"]
pub struct DashboardAssets;
fn get_mime_type(path: &str) -> &'static str {
let ext = path.rsplit('.').next().unwrap_or("");
match ext.to_lowercase().as_str() {
"html" => "text/html; charset=utf-8",
"css" => "text/css; charset=utf-8",
"js" => "application/javascript; charset=utf-8",
"json" => "application/json; charset=utf-8",
"png" => "image/png",
"jpg" | "jpeg" => "image/jpeg",
"gif" => "image/gif",
"svg" => "image/svg+xml",
"ico" => "image/x-icon",
"woff" => "font/woff",
"woff2" => "font/woff2",
"ttf" => "font/ttf",
"eot" => "application/vnd.ms-fontobject",
_ => "application/octet-stream",
}
}
pub fn serve_dashboard(path: &str) -> Option<Response<Body>> {
let path = path.trim_start_matches('/');
if path.is_empty() || path == "dashboard" || path == "dashboard/" {
return serve_file("index.html");
}
if let Some(static_path) = path.strip_prefix("static/") {
return serve_file(static_path);
}
if !path.starts_with("torc-service") && !path.contains('.') {
return serve_file("index.html");
}
None
}
fn serve_file(path: &str) -> Option<Response<Body>> {
match DashboardAssets::get(path) {
Some(content) => {
let mime_type = get_mime_type(path);
let body = Body::from(content.data.into_owned());
Some(
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", mime_type)
.header("Cache-Control", "public, max-age=3600")
.body(body)
.expect("Failed to build response"),
)
}
None => {
None
}
}
}
pub fn is_dashboard_route(path: &str) -> bool {
let path = path.trim_start_matches('/');
if path.is_empty() {
return true;
}
if path == "dashboard" || path.starts_with("dashboard/") {
return true;
}
if path.starts_with("static/") {
return true;
}
if path == "favicon.ico" {
return true;
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_dashboard_route() {
assert!(is_dashboard_route("/"));
assert!(is_dashboard_route("/dashboard"));
assert!(is_dashboard_route("/dashboard/"));
assert!(is_dashboard_route("/static/css/style.css"));
assert!(is_dashboard_route("/static/js/app.js"));
assert!(is_dashboard_route("/favicon.ico"));
assert!(!is_dashboard_route("/torc-service/v1/workflows"));
assert!(!is_dashboard_route("/torc-service/v1/jobs"));
}
#[test]
fn test_get_mime_type() {
assert_eq!(get_mime_type("index.html"), "text/html; charset=utf-8");
assert_eq!(get_mime_type("style.css"), "text/css; charset=utf-8");
assert_eq!(
get_mime_type("app.js"),
"application/javascript; charset=utf-8"
);
assert_eq!(
get_mime_type("data.json"),
"application/json; charset=utf-8"
);
assert_eq!(get_mime_type("image.png"), "image/png");
}
#[test]
fn test_serve_dashboard_root() {
let response = serve_dashboard("/");
assert!(response.is_some());
}
#[test]
fn test_serve_dashboard_static() {
let response = serve_dashboard("/static/css/style.css");
assert!(response.is_some());
}
}