Rewrite url paths

HTML files should only be accessible without their file ending. Index
files should only be accessible via a path that ends in `/`, not
directly via name,
This commit is contained in:
Joscha 2024-03-10 14:41:42 +01:00
parent 1c3b2a380a
commit 9d17d34642

View file

@ -8,21 +8,57 @@ use rust_embed::RustEmbed;
#[folder = "static"] #[folder = "static"]
struct StaticFiles; struct StaticFiles;
struct StaticFile(pub String); struct StaticFile(String);
fn not_found() -> Response {
(StatusCode::NOT_FOUND, "404 Not Found").into_response()
}
fn look_up_path(path: &str) -> Option<Response> {
let path = path.trim_start_matches('/');
let file = StaticFiles::get(path)?;
let mime = mime_guess::from_path(path).first_or_octet_stream();
let response = ([(header::CONTENT_TYPE, mime.as_ref())], file.data).into_response();
Some(response)
}
impl IntoResponse for StaticFile { impl IntoResponse for StaticFile {
fn into_response(self) -> Response { fn into_response(self) -> Response {
match StaticFiles::get(&self.0) { let mut path = self.0;
None => (StatusCode::NOT_FOUND, "404 Not Found").into_response(), if path.is_empty() {
Some(file) => { path.push('/')
let mime = mime_guess::from_path(self.0).first_or_octet_stream(); };
([(header::CONTENT_TYPE, mime.as_ref())], file.data).into_response()
if path.ends_with(".html") {
// A file `/foo/bar.html` should not be accessible directly, only
// indirectly at `/foo/bar`.
return not_found();
} }
if path.ends_with("/index") {
// A file `/foo/index.html` should not be accessible directly, only
// indirectly at `/foo/`.
return not_found();
} }
if path.ends_with('/') {
path.push_str("index");
}
if let Some(response) = look_up_path(&path) {
return response;
}
path.push_str(".html");
if let Some(response) = look_up_path(&path) {
return response;
}
not_found()
} }
} }
pub async fn get_static_file(uri: Uri) -> impl IntoResponse { pub async fn get_static_file(uri: Uri) -> impl IntoResponse {
let path = uri.path().trim_start_matches('/').to_string(); StaticFile(uri.path().to_string())
StaticFile(path)
} }