jsglue/
embedded.rs

1use axum::{body::Body, debug_handler, extract::Request, response::Response, Extension};
2use hyper::{header::CONTENT_TYPE, StatusCode};
3use include_dir::Dir;
4
5#[debug_handler]
6pub async fn handle_embedded(
7    Extension(dir): Extension<Dir<'static>>,
8    req: Request<Body>,
9) -> Response<Body> {
10    let path = req.uri().path();
11    let index_path = format!("{}index.html", path);
12
13    let path = if path.ends_with('/') {
14        index_path.as_str()
15    } else {
16        path
17    };
18
19    let path = path.trim_start_matches('/');
20
21    // Try the file
22    if let Some(file) = dir.get_file(path) {
23        let mime = mime_guess::from_path(path).first().unwrap();
24
25        return Response::builder()
26            .status(StatusCode::OK)
27            .header(CONTENT_TYPE, mime.to_string())
28            .body(Body::from(file.contents().to_vec()))
29            .unwrap();
30    }
31
32    // Try a fallback page
33    if let Some(file) = dir.get_file("fallback.html") {
34        return Response::builder()
35            .status(StatusCode::OK)
36            .header(CONTENT_TYPE, "text/html")
37            .body(Body::from(file.contents().to_vec()))
38            .unwrap();
39    }
40
41    // Try a 404 page
42    if let Some(file) = dir.get_file("404.html") {
43        return Response::builder()
44            .status(StatusCode::NOT_FOUND)
45            .header(CONTENT_TYPE, "text/html")
46            .body(Body::from(file.contents().to_vec()))
47            .unwrap();
48    }
49
50    // Maybe it's an SPA?
51    if let Some(file) = dir.get_file("index.html") {
52        return Response::builder()
53            .status(StatusCode::OK)
54            .header(CONTENT_TYPE, "text/html")
55            .body(Body::from(file.contents().to_vec()))
56            .unwrap();
57    }
58
59    // 404 not found in plaintext
60    Response::builder()
61        .status(StatusCode::NOT_FOUND)
62        .header(CONTENT_TYPE, "text/plain")
63        .body(Body::from(
64            "Cannot find the file specified!".as_bytes().to_vec(),
65        ))
66        .unwrap()
67}