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:
parent
1c3b2a380a
commit
9d17d34642
1 changed files with 45 additions and 9 deletions
|
|
@ -8,21 +8,57 @@ use rust_embed::RustEmbed;
|
|||
#[folder = "static"]
|
||||
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 {
|
||||
fn into_response(self) -> Response {
|
||||
match StaticFiles::get(&self.0) {
|
||||
None => (StatusCode::NOT_FOUND, "404 Not Found").into_response(),
|
||||
Some(file) => {
|
||||
let mime = mime_guess::from_path(self.0).first_or_octet_stream();
|
||||
([(header::CONTENT_TYPE, mime.as_ref())], file.data).into_response()
|
||||
}
|
||||
let mut path = self.0;
|
||||
if path.is_empty() {
|
||||
path.push('/')
|
||||
};
|
||||
|
||||
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 {
|
||||
let path = uri.path().trim_start_matches('/').to_string();
|
||||
StaticFile(path)
|
||||
StaticFile(uri.path().to_string())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue