52 lines
1.5 KiB
Rust

use std::io::Cursor;
use rust_embed::RustEmbed;
use rocket::{Data, Request, Response, Route};
use rocket::http::{ContentType, Method};
use rocket::http::uri::{Segments};
use rocket::http::uri::fmt::Path;
use rocket::route::{Handler, Outcome};
#[cfg(feature = "static")]
#[derive(RustEmbed)]
#[folder = "webroot/"]
struct Asset;
#[cfg(feature = "static")]
#[derive(Clone)]
pub struct CustomHandler {
}
#[cfg(feature = "static")]
impl Into<Vec<Route>> for CustomHandler {
fn into(self) -> Vec<Route> {
vec![
Route::ranked(-2, Method::Get, "/<path..>", self),
]
}
}
#[cfg(feature = "static")]
#[rocket::async_trait]
impl Handler for CustomHandler {
async fn handle<'r>(&self, request: &'r Request<'_>, _: Data<'r>) -> Outcome<'r> {
let path = request.segments::<Segments<'_, Path>>(0..).ok()
.and_then(|segments| segments.to_path_buf(true).ok()).unwrap();
let path = if path.is_dir() || path.to_str() == Some("") {
path.join("index.html")
} else {
path
};
let file_content =
<Asset as RustEmbed>::get(path.to_string_lossy().as_ref()).unwrap();
let content_type: ContentType = path
.extension()
.map(|x| x.to_string_lossy())
.and_then(|x| ContentType::from_extension(&x))
.unwrap_or(ContentType::Plain);
let rsp = Response::build().header(content_type).sized_body(file_content.data.len(), Cursor::new(file_content.data)).finalize();
Outcome::Success(rsp)
}
}