media: check detected content-type against MSC2702
only return `inline` if the detected content-type is an allowed inline content-type as defined by MSC2702 Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
9b096cc67b
commit
f11103b43b
1 changed files with 36 additions and 19 deletions
|
@ -1,5 +1,3 @@
|
||||||
use infer::MatcherType;
|
|
||||||
|
|
||||||
use crate::debug_info;
|
use crate::debug_info;
|
||||||
|
|
||||||
const ATTACHMENT: &str = "attachment";
|
const ATTACHMENT: &str = "attachment";
|
||||||
|
@ -7,34 +5,53 @@ const INLINE: &str = "inline";
|
||||||
const APPLICATION_OCTET_STREAM: &str = "application/octet-stream";
|
const APPLICATION_OCTET_STREAM: &str = "application/octet-stream";
|
||||||
const IMAGE_SVG_XML: &str = "image/svg+xml";
|
const IMAGE_SVG_XML: &str = "image/svg+xml";
|
||||||
|
|
||||||
|
/// as defined by MSC2702
|
||||||
|
const ALLOWED_INLINE_CONTENT_TYPES: [&str; 26] = [
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/csv",
|
||||||
|
"application/json",
|
||||||
|
"application/ld+json",
|
||||||
|
"image/jpeg",
|
||||||
|
"image/gif",
|
||||||
|
"image/png",
|
||||||
|
"image/apng",
|
||||||
|
"image/webp",
|
||||||
|
"image/avif",
|
||||||
|
"video/mp4",
|
||||||
|
"video/webm",
|
||||||
|
"video/ogg",
|
||||||
|
"video/quicktime",
|
||||||
|
"audio/mp4",
|
||||||
|
"audio/webm",
|
||||||
|
"audio/aac",
|
||||||
|
"audio/mpeg",
|
||||||
|
"audio/ogg",
|
||||||
|
"audio/wave",
|
||||||
|
"audio/wav",
|
||||||
|
"audio/x-wav",
|
||||||
|
"audio/x-pn-wav",
|
||||||
|
"audio/flac",
|
||||||
|
"audio/x-flac",
|
||||||
|
];
|
||||||
|
|
||||||
/// Returns a Content-Disposition of `attachment` or `inline`, depending on the
|
/// Returns a Content-Disposition of `attachment` or `inline`, depending on the
|
||||||
/// *parsed* contents of the file uploaded via format magic keys using `infer`
|
/// *parsed* contents of the file uploaded via format magic keys using `infer`
|
||||||
/// crate (basically libmagic without needing libmagic).
|
/// crate (basically libmagic without needing libmagic).
|
||||||
///
|
|
||||||
/// This forbids trusting what the client or remote server says the file is from
|
|
||||||
/// their `Content-Type` and we try to detect it ourselves. Also returns
|
|
||||||
/// `attachment` if the Content-Type does not match what we detected.
|
|
||||||
///
|
|
||||||
/// TODO: add a "strict" function for comparing the Content-Type with what we
|
|
||||||
/// detected: `file_type.mime_type() != content_type`
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[tracing::instrument(skip(buf))]
|
#[tracing::instrument(skip(buf))]
|
||||||
pub fn content_disposition_type(buf: &[u8], content_type: &Option<String>) -> &'static str {
|
pub fn content_disposition_type(buf: &[u8], content_type: &Option<String>) -> &'static str {
|
||||||
let Some(file_type) = infer::get(buf) else {
|
let Some(file_type) = infer::get(buf) else {
|
||||||
|
debug_info!("Failed to infer the file's contents, assuming attachment for Content-Disposition");
|
||||||
return ATTACHMENT;
|
return ATTACHMENT;
|
||||||
};
|
};
|
||||||
|
|
||||||
debug_info!("MIME type: {}", file_type.mime_type());
|
debug_info!("detected MIME type: {}", file_type.mime_type());
|
||||||
|
|
||||||
match file_type.matcher_type() {
|
if ALLOWED_INLINE_CONTENT_TYPES.contains(&file_type.mime_type()) {
|
||||||
MatcherType::Image | MatcherType::Audio | MatcherType::Text | MatcherType::Video => {
|
|
||||||
if file_type.mime_type().contains("xml") {
|
|
||||||
ATTACHMENT
|
|
||||||
} else {
|
|
||||||
INLINE
|
INLINE
|
||||||
}
|
} else {
|
||||||
},
|
ATTACHMENT
|
||||||
_ => ATTACHMENT,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue