media: drop Content-Type detection support

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-06-03 23:14:31 -04:00
parent df8ba04e31
commit b781771a9b
5 changed files with 14 additions and 35 deletions

7
Cargo.lock generated
View file

@ -666,7 +666,6 @@ dependencies = [
"http 1.1.0", "http 1.1.0",
"http-body-util", "http-body-util",
"image", "image",
"infer",
"ipaddress", "ipaddress",
"itertools 0.13.0", "itertools 0.13.0",
"libloading", "libloading",
@ -1685,12 +1684,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "infer"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847"
[[package]] [[package]]
name = "inlinable_string" name = "inlinable_string"
version = "0.1.15" version = "0.1.15"

View file

@ -28,10 +28,6 @@ name = "conduit"
[workspace.dependencies.sanitize-filename] [workspace.dependencies.sanitize-filename]
version = "0.5.0" version = "0.5.0"
[workspace.dependencies.infer]
version = "0.16"
default-features = false
[workspace.dependencies.jsonwebtoken] [workspace.dependencies.jsonwebtoken]
version = "9.3.0" version = "9.3.0"

View file

@ -139,7 +139,7 @@ pub(crate) async fn create_content_route(
.map(|filename| { .map(|filename| {
format!( format!(
"{}; filename={}", "{}; filename={}",
content_disposition_type(&body.file, &body.content_type), content_disposition_type(&body.content_type),
sanitise_filename(filename.to_owned()) sanitise_filename(filename.to_owned())
) )
}) })
@ -188,7 +188,7 @@ pub(crate) async fn get_content_route(body: Ruma<get_content::v3::Request>) -> R
content_disposition, content_disposition,
}) = services().media.get(mxc.clone()).await? }) = services().media.get(mxc.clone()).await?
{ {
let content_disposition = Some(make_content_disposition(&file, &content_type, content_disposition, None)); let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
Ok(get_content::v3::Response { Ok(get_content::v3::Response {
file, file,
@ -212,7 +212,6 @@ pub(crate) async fn get_content_route(body: Ruma<get_content::v3::Request>) -> R
})?; })?;
let content_disposition = Some(make_content_disposition( let content_disposition = Some(make_content_disposition(
&response.file,
&response.content_type, &response.content_type,
response.content_disposition, response.content_disposition,
None, None,
@ -268,7 +267,6 @@ pub(crate) async fn get_content_as_filename_route(
}) = services().media.get(mxc.clone()).await? }) = services().media.get(mxc.clone()).await?
{ {
let content_disposition = Some(make_content_disposition( let content_disposition = Some(make_content_disposition(
&file,
&content_type, &content_type,
content_disposition, content_disposition,
Some(body.filename.clone()), Some(body.filename.clone()),
@ -293,7 +291,6 @@ pub(crate) async fn get_content_as_filename_route(
{ {
Ok(remote_content_response) => { Ok(remote_content_response) => {
let content_disposition = Some(make_content_disposition( let content_disposition = Some(make_content_disposition(
&remote_content_response.file,
&remote_content_response.content_type, &remote_content_response.content_type,
remote_content_response.content_disposition, remote_content_response.content_disposition,
None, None,
@ -365,7 +362,7 @@ pub(crate) async fn get_content_thumbnail_route(
) )
.await? .await?
{ {
let content_disposition = Some(make_content_disposition(&file, &content_type, content_disposition, None)); let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
Ok(get_content_thumbnail::v3::Response { Ok(get_content_thumbnail::v3::Response {
file, file,
@ -418,7 +415,6 @@ pub(crate) async fn get_content_thumbnail_route(
.await?; .await?;
let content_disposition = Some(make_content_disposition( let content_disposition = Some(make_content_disposition(
&get_thumbnail_response.file,
&get_thumbnail_response.content_type, &get_thumbnail_response.content_type,
get_thumbnail_response.content_disposition, get_thumbnail_response.content_disposition,
None, None,
@ -489,7 +485,6 @@ async fn get_remote_content(
.await?; .await?;
let content_disposition = Some(make_content_disposition( let content_disposition = Some(make_content_disposition(
&content_response.file,
&content_response.content_type, &content_response.content_type,
content_response.content_disposition, content_response.content_disposition,
None, None,

View file

@ -69,7 +69,6 @@ figment.workspace = true
http-body-util.workspace = true http-body-util.workspace = true
http.workspace = true http.workspace = true
image.workspace = true image.workspace = true
infer.workspace = true
ipaddress.workspace = true ipaddress.workspace = true
itertools.workspace = true itertools.workspace = true
libloading.workspace = true libloading.workspace = true

View file

@ -1,5 +1,3 @@
use crate::debug_info;
const ATTACHMENT: &str = "attachment"; const ATTACHMENT: &str = "attachment";
const INLINE: &str = "inline"; const INLINE: &str = "inline";
@ -35,19 +33,17 @@ const ALLOWED_INLINE_CONTENT_TYPES: [&str; 26] = [
]; ];
/// 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` /// Content-Type against MSC2702 list of safe inline Content-Types
/// crate (basically libmagic without needing libmagic). /// (`ALLOWED_INLINE_CONTENT_TYPES`)
#[must_use] #[must_use]
#[tracing::instrument(skip(buf))] #[tracing::instrument]
pub fn content_disposition_type(buf: &[u8], content_type: &Option<String>) -> &'static str { pub fn content_disposition_type(content_type: &Option<String>) -> &'static str {
let Some(file_type) = infer::get(buf) else { let Some(content_type) = content_type else {
debug_info!("Failed to infer the file's contents, assuming attachment for Content-Disposition"); // no Content-Type was given to us, assume attachment
return ATTACHMENT; return ATTACHMENT;
}; };
debug_info!("detected MIME type: {}", file_type.mime_type()); if ALLOWED_INLINE_CONTENT_TYPES.contains(&content_type.to_lowercase().as_str()) {
if ALLOWED_INLINE_CONTENT_TYPES.contains(&file_type.mime_type()) {
INLINE INLINE
} else { } else {
ATTACHMENT ATTACHMENT
@ -74,9 +70,9 @@ pub fn sanitise_filename(filename: String) -> String {
/// `Content-Disposition: attachment/inline; filename=filename.ext` /// `Content-Disposition: attachment/inline; filename=filename.ext`
/// ///
/// else: `Content-Disposition: attachment/inline` /// else: `Content-Disposition: attachment/inline`
#[tracing::instrument(skip(file))] #[tracing::instrument]
pub fn make_content_disposition( pub fn make_content_disposition(
file: &[u8], content_type: &Option<String>, content_disposition: Option<String>, req_filename: Option<String>, content_type: &Option<String>, content_disposition: Option<String>, req_filename: Option<String>,
) -> String { ) -> String {
let filename: String; let filename: String;
@ -98,10 +94,10 @@ pub fn make_content_disposition(
if !filename.is_empty() { if !filename.is_empty() {
// Content-Disposition: attachment/inline; filename=filename.ext // Content-Disposition: attachment/inline; filename=filename.ext
format!("{}; filename={}", content_disposition_type(file, content_type), filename) format!("{}; filename={}", content_disposition_type(content_type), filename)
} else { } else {
// Content-Disposition: attachment/inline // Content-Disposition: attachment/inline
String::from(content_disposition_type(file, content_type)) String::from(content_disposition_type(content_type))
} }
} }