use bytes::Bytes;
use http::{Response, StatusCode};
use crate::app_state::AppState;
use crate::router::{self, Body};
pub async fn serve_static(
_state: AppState,
_parts: http::request::Parts,
params: Vec<(String, String)>,
) -> Response<Body> {
let file_path = router::path_param(¶ms, "path").unwrap_or_default();
if !csaf_core::path_security::is_safe_relative_path(&file_path) {
return Response::builder()
.status(StatusCode::FORBIDDEN)
.body(Body::from("Forbidden"))
.unwrap_or_default();
}
let content_type = mime_guess::from_path(&file_path)
.first_raw()
.unwrap_or("application/octet-stream");
let data: Option<Bytes> = match file_path.as_str() {
"css/custom.css" => Some(Bytes::from_static(include_bytes!(
"../static/css/custom.css"
))),
"js/theme.js" => Some(Bytes::from_static(include_bytes!("../static/js/theme.js"))),
"img/logo.png" => Some(Bytes::from_static(include_bytes!("../static/img/logo.png"))),
"fonts/roboto/roboto-regular.ttf" => Some(Bytes::from_static(include_bytes!(
"../static/fonts/roboto/roboto-regular.ttf"
))),
"fonts/roboto/roboto-bold.ttf" => Some(Bytes::from_static(include_bytes!(
"../static/fonts/roboto/roboto-bold.ttf"
))),
"fonts/roboto-mono/roboto-mono-regular.ttf" => Some(Bytes::from_static(include_bytes!(
"../static/fonts/roboto-mono/roboto-mono-regular.ttf"
))),
"fonts/roboto-mono/roboto-mono-bold.ttf" => Some(Bytes::from_static(include_bytes!(
"../static/fonts/roboto-mono/roboto-mono-bold.ttf"
))),
_ => None,
};
match data {
Some(bytes) => Response::builder()
.status(StatusCode::OK)
.header("content-type", content_type)
.header("cache-control", "public, max-age=86400")
.body(Body::from(bytes))
.unwrap_or_default(),
None => Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("Static file not found"))
.unwrap_or_default(),
}
}