Use "mediaType" property value to determine file extension when saving downloaded media
This commit is contained in:
parent
85dbb6f392
commit
7c07cd79bc
5 changed files with 32 additions and 7 deletions
|
@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Changed
|
||||
|
||||
- Save downloaded media as "unknown" if its media type is not supported.
|
||||
- Use `mediaType` property value to determine file extension when saving downloaded media.
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -27,9 +27,17 @@ async fn fetch_actor_images(
|
|||
default_banner: Option<ProfileImage>,
|
||||
) -> (Option<ProfileImage>, Option<ProfileImage>) {
|
||||
let maybe_avatar = if let Some(icon) = &actor.icon {
|
||||
match fetch_file(instance, &icon.url, media_dir).await {
|
||||
Ok((file_name, _)) => {
|
||||
let image = ProfileImage { file_name, media_type: None };
|
||||
match fetch_file(
|
||||
instance,
|
||||
&icon.url,
|
||||
icon.media_type.as_deref(),
|
||||
media_dir,
|
||||
).await {
|
||||
Ok((file_name, maybe_media_type)) => {
|
||||
let image = ProfileImage {
|
||||
file_name,
|
||||
media_type: maybe_media_type,
|
||||
};
|
||||
Some(image)
|
||||
},
|
||||
Err(error) => {
|
||||
|
@ -41,9 +49,17 @@ async fn fetch_actor_images(
|
|||
None
|
||||
};
|
||||
let maybe_banner = if let Some(image) = &actor.image {
|
||||
match fetch_file(instance, &image.url, media_dir).await {
|
||||
Ok((file_name, _)) => {
|
||||
let image = ProfileImage { file_name, media_type: None };
|
||||
match fetch_file(
|
||||
instance,
|
||||
&image.url,
|
||||
image.media_type.as_deref(),
|
||||
media_dir,
|
||||
).await {
|
||||
Ok((file_name, maybe_media_type)) => {
|
||||
let image = ProfileImage {
|
||||
file_name,
|
||||
media_type: maybe_media_type,
|
||||
};
|
||||
Some(image)
|
||||
},
|
||||
Err(error) => {
|
||||
|
|
|
@ -49,6 +49,7 @@ pub struct ActorImage {
|
|||
#[serde(rename = "type")]
|
||||
object_type: String,
|
||||
pub url: String,
|
||||
pub media_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
|
@ -240,6 +241,7 @@ pub fn get_local_actor(
|
|||
let actor_image = ActorImage {
|
||||
object_type: IMAGE.to_string(),
|
||||
url: get_file_url(instance_url, &image.file_name),
|
||||
media_type: None,
|
||||
};
|
||||
Some(actor_image)
|
||||
},
|
||||
|
@ -250,6 +252,7 @@ pub fn get_local_actor(
|
|||
let actor_image = ActorImage {
|
||||
object_type: IMAGE.to_string(),
|
||||
url: get_file_url(instance_url, &image.file_name),
|
||||
media_type: None,
|
||||
};
|
||||
Some(actor_image)
|
||||
},
|
||||
|
|
|
@ -107,6 +107,7 @@ const FILE_MAX_SIZE: u64 = 1024 * 1024 * 20;
|
|||
pub async fn fetch_file(
|
||||
instance: &Instance,
|
||||
url: &str,
|
||||
maybe_media_type: Option<&str>,
|
||||
output_dir: &Path,
|
||||
) -> Result<(String, Option<String>), FetchError> {
|
||||
let client = build_client(instance)?;
|
||||
|
@ -122,7 +123,10 @@ pub async fn fetch_file(
|
|||
if file_data.len() > FILE_MAX_SIZE as usize {
|
||||
return Err(FetchError::OtherError("file is too large"));
|
||||
};
|
||||
let maybe_media_type = sniff_media_type(&file_data)
|
||||
let maybe_media_type = maybe_media_type
|
||||
.map(|media_type| media_type.to_string())
|
||||
// Sniff media type if not provided
|
||||
.or(sniff_media_type(&file_data))
|
||||
// Remove media type if it is not supported to prevent XSS
|
||||
.filter(|media_type| {
|
||||
if SUPPORTED_MEDIA_TYPES.contains(&media_type.as_str()) {
|
||||
|
|
|
@ -178,6 +178,7 @@ pub async fn handle_note(
|
|||
let (file_name, maybe_media_type) = fetch_file(
|
||||
instance,
|
||||
&attachment_url,
|
||||
attachment.media_type.as_deref(),
|
||||
media_dir,
|
||||
).await
|
||||
.map_err(|err| {
|
||||
|
|
Loading…
Reference in a new issue