diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index cf47ed82..91c0fdfc 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -167,7 +167,7 @@ pub(crate) async fn create_content_route( filename: Some(filename), }) .as_ref(), - body.content_type.as_deref(), + body.content_type.clone(), &body.file, ) .await?; @@ -333,7 +333,7 @@ pub(crate) async fn get_remote_content( .create( mxc.to_string(), response.content.content_disposition.as_ref(), - response.content.content_type.as_deref(), + response.content.content_type.clone(), &response.content.file, ) .await?; @@ -851,7 +851,7 @@ async fn get_content_thumbnail_route_ruma( .upload_thumbnail( mxc.to_string(), None, - resp.content.content_type.as_deref(), + resp.content.content_type.clone(), width, height, &resp.content.file, diff --git a/src/database/key_value/media.rs b/src/database/key_value/media.rs index 868842ba..314cd0a9 100644 --- a/src/database/key_value/media.rs +++ b/src/database/key_value/media.rs @@ -2,7 +2,10 @@ use ruma::api::client::error::ErrorKind; use crate::{ database::KeyValueDatabase, - service::{self, media::MediaFileKey}, + service::{ + self, + media::{FileMeta, MediaFileKey}, + }, utils, Error, Result, }; @@ -12,8 +15,7 @@ impl service::media::Data for KeyValueDatabase { mxc: String, width: u32, height: u32, - content_disposition: Option<&str>, - content_type: Option<&str>, + meta: &FileMeta, ) -> Result { let mut key = mxc.as_bytes().to_vec(); key.push(0xFF); @@ -21,14 +23,17 @@ impl service::media::Data for KeyValueDatabase { key.extend_from_slice(&height.to_be_bytes()); key.push(0xFF); key.extend_from_slice( - content_disposition + meta.content_disposition .as_ref() - .map(|f| f.as_bytes()) + .map(String::as_bytes) .unwrap_or_default(), ); key.push(0xFF); key.extend_from_slice( - content_type.as_ref().map(|c| c.as_bytes()).unwrap_or_default(), + meta.content_type + .as_ref() + .map(String::as_bytes) + .unwrap_or_default(), ); let key = MediaFileKey::new(key); @@ -43,7 +48,7 @@ impl service::media::Data for KeyValueDatabase { mxc: String, width: u32, height: u32, - ) -> Result<(Option, Option, MediaFileKey)> { + ) -> Result<(FileMeta, MediaFileKey)> { let mut prefix = mxc.as_bytes().to_vec(); prefix.push(0xFF); prefix.extend_from_slice(&width.to_be_bytes()); @@ -86,6 +91,12 @@ impl service::media::Data for KeyValueDatabase { }, )?) }; - Ok((content_disposition, content_type, key)) + Ok(( + FileMeta { + content_disposition, + content_type, + }, + key, + )) } } diff --git a/src/service/media.rs b/src/service/media.rs index 12cb2538..94df18e5 100644 --- a/src/service/media.rs +++ b/src/service/media.rs @@ -48,22 +48,21 @@ impl Service { &self, mxc: String, content_disposition: Option<&ContentDisposition>, - content_type: Option<&str>, + content_type: Option, file: &[u8], - ) -> Result<()> { - // Width, Height = 0 if it's not a thumbnail - let key = self.db.create_file_metadata( - mxc, - 0, - 0, - content_disposition.map(ContentDisposition::to_string).as_deref(), + ) -> Result { + let meta = FileMeta { + content_disposition: content_disposition + .map(ContentDisposition::to_string), content_type, - )?; + }; + // Width, Height = 0 if it's not a thumbnail + let key = self.db.create_file_metadata(mxc, 0, 0, &meta)?; let path = services().globals.get_media_file(&key); let mut f = File::create(path).await?; f.write_all(file).await?; - Ok(()) + Ok(meta) } /// Uploads or replaces a file thumbnail. @@ -72,25 +71,23 @@ impl Service { pub(crate) async fn upload_thumbnail( &self, mxc: String, - content_disposition: Option<&str>, - content_type: Option<&str>, + content_disposition: Option, + content_type: Option, width: u32, height: u32, file: &[u8], - ) -> Result<()> { - let key = self.db.create_file_metadata( - mxc, - width, - height, + ) -> Result { + let meta = FileMeta { content_disposition, content_type, - )?; + }; + let key = self.db.create_file_metadata(mxc, width, height, &meta)?; let path = services().globals.get_media_file(&key); let mut f = File::create(path).await?; f.write_all(file).await?; - Ok(()) + Ok(meta) } /// Downloads a file. @@ -99,9 +96,7 @@ impl Service { &self, mxc: String, ) -> Result)>> { - if let Ok((content_disposition, content_type, key)) = - self.db.search_file_metadata(mxc, 0, 0) - { + if let Ok((meta, key)) = self.db.search_file_metadata(mxc, 0, 0) { let path = services().globals.get_media_file(&key); let mut file_data = Vec::new(); let Ok(mut file) = File::open(path).await else { @@ -110,13 +105,7 @@ impl Service { file.read_to_end(&mut file_data).await?; - Ok(Some(( - FileMeta { - content_disposition, - content_type, - }, - file_data, - ))) + Ok(Some((meta, file_data))) } else { Ok(None) } @@ -245,7 +234,7 @@ impl Service { let (width, height, crop) = Self::thumbnail_properties(width, height).unwrap_or((0, 0, false)); - if let Ok((content_disposition, content_type, key)) = + if let Ok((meta, key)) = self.db.search_file_metadata(mxc.clone(), width, height) { debug!("Using saved thumbnail"); @@ -253,17 +242,10 @@ impl Service { let mut file = Vec::new(); File::open(path).await?.read_to_end(&mut file).await?; - return Ok(Some(( - FileMeta { - content_disposition, - content_type, - }, - file.clone(), - ))); + return Ok(Some((meta, file.clone()))); } - let Ok((content_disposition, content_type, key)) = - self.db.search_file_metadata(mxc.clone(), 0, 0) + let Ok((meta, key)) = self.db.search_file_metadata(mxc.clone(), 0, 0) else { debug!("Original image not found, can't generate thumbnail"); return Ok(None); @@ -289,37 +271,20 @@ impl Service { let Some(thumbnail_bytes) = thumbnail_result? else { debug!("Returning source image as-is"); - return Ok(Some(( - FileMeta { - content_disposition, - content_type, - }, - file, - ))); + return Ok(Some((meta, file))); }; debug!("Saving created thumbnail"); // Save thumbnail in database so we don't have to generate it // again next time - let thumbnail_key = self.db.create_file_metadata( - mxc, - width, - height, - content_disposition.as_deref(), - content_type.as_deref(), - )?; + let thumbnail_key = + self.db.create_file_metadata(mxc, width, height, &meta)?; let path = services().globals.get_media_file(&thumbnail_key); let mut f = File::create(path).await?; f.write_all(&thumbnail_bytes).await?; - Ok(Some(( - FileMeta { - content_disposition, - content_type, - }, - thumbnail_bytes.clone(), - ))) + Ok(Some((meta, thumbnail_bytes.clone()))) } } diff --git a/src/service/media/data.rs b/src/service/media/data.rs index 0f337342..64fbdbbf 100644 --- a/src/service/media/data.rs +++ b/src/service/media/data.rs @@ -1,4 +1,4 @@ -use super::MediaFileKey; +use super::{FileMeta, MediaFileKey}; use crate::Result; pub(crate) trait Data: Send + Sync { @@ -7,15 +7,13 @@ pub(crate) trait Data: Send + Sync { mxc: String, width: u32, height: u32, - content_disposition: Option<&str>, - content_type: Option<&str>, + meta: &FileMeta, ) -> Result; - /// Returns `content_disposition`, `content_type` and the `metadata` key. fn search_file_metadata( &self, mxc: String, width: u32, height: u32, - ) -> Result<(Option, Option, MediaFileKey)>; + ) -> Result<(FileMeta, MediaFileKey)>; }