diff --git a/Cargo.lock b/Cargo.lock index e47f32d..37b0afd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -510,6 +510,7 @@ dependencies = [ "tower", "tower-http", "url", + "url-escape", "uuid", ] @@ -3412,6 +3413,15 @@ dependencies = [ "serde", ] +[[package]] +name = "url-escape" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44e0ce4d1246d075ca5abec4b41d33e87a6054d08e2366b63205665e950db218" +dependencies = [ + "percent-encoding", +] + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index b665055..ccc8afe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,4 @@ base64 = "0.22.1" chrono = "0.4.38" uuid = { version = "1.11.0", features = [ "v4", "serde" ] } image = "0.25.5" +url-escape = "0.1.1" diff --git a/src/internal/db/images.rs b/src/internal/db/images.rs index ff59dbc..67ba572 100644 --- a/src/internal/db/images.rs +++ b/src/internal/db/images.rs @@ -15,7 +15,7 @@ pub struct Image { pub width: i32, pub height: i32, pub mime_type: String, - pub original_filename: String, + pub original_filename: Option, pub alt: Option, pub uploaded_at: chrono::DateTime, } diff --git a/src/web/controllers/images.rs b/src/web/controllers/images.rs index ef0959b..5b75e03 100644 --- a/src/web/controllers/images.rs +++ b/src/web/controllers/images.rs @@ -14,6 +14,7 @@ use std::{ sync::Arc, }; use tower_http::services::ServeFile; +use url_escape; use uuid::Uuid; use super::{AppState, ControllerError}; @@ -95,8 +96,21 @@ pub async fn get_image( let image_path = get_image_path(image_id); let db_img = images::get_image(&state.db, image_id).await?; let content = ServeFile::new(image_path).try_call(req).await?; + let filename = match db_img.original_filename { + Some(filename) => url_escape::encode_fragment(&filename).to_string(), + None => image_id.simple().to_string(), + }; - Ok(([(header::CONTENT_TYPE, db_img.mime_type)], content)) + Ok(( + [ + (header::CONTENT_TYPE, db_img.mime_type), + ( + header::CONTENT_DISPOSITION, + format!("inline; filename=\"{filename}\""), + ), + ], + content, + )) } pub async fn delete_image(