Fix asset serving: preserve original case in path (don't lowercase on GET)
All checks were successful
Deploy to Server / deploy (push) Successful in 1m39s
All checks were successful
Deploy to Server / deploy (push) Successful in 1m39s
This commit is contained in:
@@ -112,6 +112,22 @@ fn parse_path(path: &str) -> Result<(Option<String>, String), ApiError> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a path for serving only – preserves original case, only validates for path traversal.
|
||||
fn parse_serve_path(path: &str) -> Result<(Option<String>, String), ApiError> {
|
||||
let path = path.trim_start_matches('/');
|
||||
if path.contains("..") || path.contains('\\') {
|
||||
return Err(ApiError::BadRequest("Invalid asset path".into()));
|
||||
}
|
||||
let mut parts = path.splitn(2, '/');
|
||||
match (parts.next(), parts.next()) {
|
||||
(Some(a), None) if !a.is_empty() => Ok((None, a.to_string())),
|
||||
(Some(folder), Some(filename)) if !folder.is_empty() && !filename.is_empty() => {
|
||||
Ok((Some(folder.to_string()), filename.to_string()))
|
||||
}
|
||||
_ => Err(ApiError::BadRequest("Invalid asset path".into())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Read all image files from a directory, tagging them with the folder name.
|
||||
async fn read_images(
|
||||
dir: &std::path::Path,
|
||||
@@ -521,7 +537,7 @@ pub async fn get_asset(
|
||||
) -> Result<axum::response::Response, ApiError> {
|
||||
let env = state.effective_environment_from_param(env_param.environment.as_deref().map(|s| s.trim()).filter(|s| !s.is_empty()));
|
||||
let assets_dir = state.assets_dir_for(&env);
|
||||
let (folder, filename) = parse_path(&path)?;
|
||||
let (folder, filename) = parse_serve_path(&path)?;
|
||||
let file_path = match &folder {
|
||||
Some(f) => assets_dir.join(f).join(&filename),
|
||||
None => assets_dir.join(&filename),
|
||||
|
||||
Reference in New Issue
Block a user