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