mirror of
https://gitlab.com/famedly/conduit.git
synced 2024-12-26 12:33:47 +03:00
Merge branch 'mediafixes' into 'next'
fix: old media used spaces in content disposition without quotes See merge request famedly/conduit!717
This commit is contained in:
commit
bca8d1f70f
6 changed files with 114 additions and 33 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -2232,7 +2232,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"js_int",
|
"js_int",
|
||||||
|
@ -2253,7 +2253,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -2265,7 +2265,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
|
@ -2288,7 +2288,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
@ -2318,7 +2318,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
|
@ -2341,7 +2341,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -2359,7 +2359,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -2368,7 +2368,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -2378,8 +2378,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -2393,7 +2394,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -2405,7 +2406,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-server-util"
|
name = "ruma-server-util"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"headers",
|
"headers",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
|
@ -2418,7 +2419,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
@ -2434,7 +2435,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-state-res"
|
name = "ruma-state-res"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
|
source = "git+https://github.com/ruma/ruma#c06af4385e0e30c48a8e9ca3d488da32102d0db9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"js_int",
|
"js_int",
|
||||||
|
|
|
@ -188,11 +188,11 @@ async fn get_content(
|
||||||
) -> Result<get_content::v1::Response, Error> {
|
) -> Result<get_content::v1::Response, Error> {
|
||||||
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
||||||
|
|
||||||
if let Some(FileMeta {
|
if let Ok(Some(FileMeta {
|
||||||
content_disposition,
|
content_disposition,
|
||||||
content_type,
|
content_type,
|
||||||
file,
|
file,
|
||||||
}) = services().media.get(mxc.clone()).await?
|
})) = services().media.get(mxc.clone()).await
|
||||||
{
|
{
|
||||||
Ok(get_content::v1::Response {
|
Ok(get_content::v1::Response {
|
||||||
file,
|
file,
|
||||||
|
@ -264,9 +264,9 @@ async fn get_content_as_filename(
|
||||||
) -> Result<get_content_as_filename::v1::Response, Error> {
|
) -> Result<get_content_as_filename::v1::Response, Error> {
|
||||||
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
||||||
|
|
||||||
if let Some(FileMeta {
|
if let Ok(Some(FileMeta {
|
||||||
file, content_type, ..
|
file, content_type, ..
|
||||||
}) = services().media.get(mxc.clone()).await?
|
})) = services().media.get(mxc.clone()).await
|
||||||
{
|
{
|
||||||
Ok(get_content_as_filename::v1::Response {
|
Ok(get_content_as_filename::v1::Response {
|
||||||
file,
|
file,
|
||||||
|
@ -348,9 +348,9 @@ async fn get_content_thumbnail(
|
||||||
) -> Result<get_content_thumbnail::v1::Response, Error> {
|
) -> Result<get_content_thumbnail::v1::Response, Error> {
|
||||||
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
let mxc = format!("mxc://{}/{}", server_name, media_id);
|
||||||
|
|
||||||
if let Some(FileMeta {
|
if let Ok(Some(FileMeta {
|
||||||
file, content_type, ..
|
file, content_type, ..
|
||||||
}) = services()
|
})) = services()
|
||||||
.media
|
.media
|
||||||
.get_thumbnail(
|
.get_thumbnail(
|
||||||
mxc.clone(),
|
mxc.clone(),
|
||||||
|
@ -359,9 +359,9 @@ async fn get_content_thumbnail(
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?,
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?,
|
||||||
height
|
height
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?,
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Height is invalid."))?,
|
||||||
)
|
)
|
||||||
.await?
|
.await
|
||||||
{
|
{
|
||||||
Ok(get_content_thumbnail::v1::Response { file, content_type })
|
Ok(get_content_thumbnail::v1::Response { file, content_type })
|
||||||
} else if server_name != services().globals.server_name() && allow_remote {
|
} else if server_name != services().globals.server_name() && allow_remote {
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub async fn join_room_by_id_or_alias_route(
|
||||||
|
|
||||||
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias) {
|
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias) {
|
||||||
Ok(room_id) => {
|
Ok(room_id) => {
|
||||||
let mut servers = body.server_name.clone();
|
let mut servers = body.via.clone();
|
||||||
servers.extend(
|
servers.extend(
|
||||||
services()
|
services()
|
||||||
.rooms
|
.rooms
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
services, utils, Error, PduEvent, Result, Ruma,
|
services, utils, Error, PduEvent, Result, Ruma,
|
||||||
};
|
};
|
||||||
use axum::{response::IntoResponse, Json};
|
use axum::{response::IntoResponse, Json};
|
||||||
use axum_extra::headers::{authorization::Credentials, CacheControl, Header};
|
use axum_extra::headers::{CacheControl, Header};
|
||||||
use get_profile_information::v1::ProfileField;
|
use get_profile_information::v1::ProfileField;
|
||||||
use http::header::AUTHORIZATION;
|
use http::header::AUTHORIZATION;
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@ use ruma::{
|
||||||
StateEventType, TimelineEventType,
|
StateEventType, TimelineEventType,
|
||||||
},
|
},
|
||||||
serde::{Base64, JsonObject, Raw},
|
serde::{Base64, JsonObject, Raw},
|
||||||
server_util::authorization::XMatrix,
|
|
||||||
to_device::DeviceIdOrAllDevices,
|
to_device::DeviceIdOrAllDevices,
|
||||||
uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
|
uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch,
|
||||||
OwnedEventId, OwnedRoomId, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, RoomId,
|
OwnedEventId, OwnedRoomId, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, RoomId,
|
||||||
|
@ -275,15 +274,15 @@ where
|
||||||
for s in signature_server {
|
for s in signature_server {
|
||||||
http_request.headers_mut().insert(
|
http_request.headers_mut().insert(
|
||||||
AUTHORIZATION,
|
AUTHORIZATION,
|
||||||
XMatrix::parse(&format!(
|
format!(
|
||||||
"X-Matrix origin=\"{}\",destination=\"{}\",key=\"{}\",sig=\"{}\"",
|
"X-Matrix origin=\"{}\",destination=\"{}\",key=\"{}\",sig=\"{}\"",
|
||||||
services().globals.server_name(),
|
services().globals.server_name(),
|
||||||
destination,
|
destination,
|
||||||
s.0,
|
s.0,
|
||||||
s.1
|
s.1
|
||||||
))
|
)
|
||||||
.expect("When Ruma signs JSON, it produces a valid base64 signature. All other types are valid ServerNames or OwnedKeyId")
|
.try_into()
|
||||||
.encode(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,7 +342,7 @@ where
|
||||||
|
|
||||||
response.map_err(|e| {
|
response.map_err(|e| {
|
||||||
warn!(
|
warn!(
|
||||||
"Invalid 200 response from {} on: {} {}",
|
"Invalid 200 response from {} on: {} {:?}",
|
||||||
&destination, url, e
|
&destination, url, e
|
||||||
);
|
);
|
||||||
Error::BadServerResponse("Server returned bad 200 response.")
|
Error::BadServerResponse("Server returned bad 200 response.")
|
||||||
|
|
|
@ -63,9 +63,9 @@ impl service::media::Data for KeyValueDatabase {
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("Media ID in db is invalid."))?;
|
.ok_or_else(|| Error::bad_database("Media ID in db is invalid."))?;
|
||||||
|
|
||||||
let content_disposition = content_disposition_bytes
|
let content_disposition = content_disposition_bytes.try_into().unwrap_or_else(|_| {
|
||||||
.try_into()
|
ContentDisposition::new(ruma::http_headers::ContentDispositionType::Inline)
|
||||||
.map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid."))?;
|
});
|
||||||
Ok((content_disposition, content_type, key))
|
Ok((content_disposition, content_type, key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
SERVICES,
|
SERVICES,
|
||||||
};
|
};
|
||||||
use abstraction::{KeyValueDatabaseEngine, KvTree};
|
use abstraction::{KeyValueDatabaseEngine, KvTree};
|
||||||
|
use base64::{engine::general_purpose, Engine};
|
||||||
use directories::ProjectDirs;
|
use directories::ProjectDirs;
|
||||||
use lru_cache::LruCache;
|
use lru_cache::LruCache;
|
||||||
|
|
||||||
|
@ -424,7 +425,7 @@ impl KeyValueDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the database has any data, perform data migrations before starting
|
// If the database has any data, perform data migrations before starting
|
||||||
let latest_database_version = 13;
|
let latest_database_version = 16;
|
||||||
|
|
||||||
if services().users.count()? > 0 {
|
if services().users.count()? > 0 {
|
||||||
// MIGRATIONS
|
// MIGRATIONS
|
||||||
|
@ -941,6 +942,86 @@ impl KeyValueDatabase {
|
||||||
warn!("Migration: 12 -> 13 finished");
|
warn!("Migration: 12 -> 13 finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if services().globals.database_version()? < 16 {
|
||||||
|
// Reconstruct all media using the filesystem
|
||||||
|
db.mediaid_file.clear().unwrap();
|
||||||
|
|
||||||
|
for file in fs::read_dir(services().globals.get_media_folder()).unwrap() {
|
||||||
|
let file = file.unwrap();
|
||||||
|
let mediaid = general_purpose::URL_SAFE_NO_PAD
|
||||||
|
.decode(file.file_name().into_string().unwrap())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut parts = mediaid.rsplit(|&b| b == 0xff);
|
||||||
|
|
||||||
|
let mut removed_bytes = 0;
|
||||||
|
|
||||||
|
let content_type_bytes = parts.next().unwrap();
|
||||||
|
removed_bytes += content_type_bytes.len() + 1;
|
||||||
|
|
||||||
|
let content_disposition_bytes = parts
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| Error::bad_database("Media ID in db is invalid."))?;
|
||||||
|
removed_bytes += content_disposition_bytes.len();
|
||||||
|
|
||||||
|
let mut content_disposition =
|
||||||
|
utils::string_from_bytes(content_disposition_bytes).map_err(|_| {
|
||||||
|
Error::bad_database("Content Disposition in mediaid_file is invalid.")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if content_disposition.contains("filename=")
|
||||||
|
&& !content_disposition.contains("filename=\"")
|
||||||
|
{
|
||||||
|
println!("{}", &content_disposition);
|
||||||
|
content_disposition =
|
||||||
|
content_disposition.replacen("filename=", "filename=\"", 1);
|
||||||
|
content_disposition.push('"');
|
||||||
|
println!("{}", &content_disposition);
|
||||||
|
|
||||||
|
let mut new_key = mediaid[..(mediaid.len() - removed_bytes)].to_vec();
|
||||||
|
assert!(*new_key.last().unwrap() == 0xff);
|
||||||
|
|
||||||
|
let mut shorter_key = new_key.clone();
|
||||||
|
shorter_key.extend(
|
||||||
|
ruma::http_headers::ContentDisposition::new(
|
||||||
|
ruma::http_headers::ContentDispositionType::Inline,
|
||||||
|
)
|
||||||
|
.to_string()
|
||||||
|
.as_bytes(),
|
||||||
|
);
|
||||||
|
shorter_key.push(0xff);
|
||||||
|
shorter_key.extend_from_slice(content_type_bytes);
|
||||||
|
|
||||||
|
new_key.extend_from_slice(content_disposition.to_string().as_bytes());
|
||||||
|
new_key.push(0xff);
|
||||||
|
new_key.extend_from_slice(content_type_bytes);
|
||||||
|
|
||||||
|
// Some file names are too long. Ignore those.
|
||||||
|
match fs::rename(
|
||||||
|
services().globals.get_media_file(&mediaid),
|
||||||
|
services().globals.get_media_file(&new_key),
|
||||||
|
) {
|
||||||
|
Ok(_) => {
|
||||||
|
db.mediaid_file.insert(&new_key, &[])?;
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
fs::rename(
|
||||||
|
services().globals.get_media_file(&mediaid),
|
||||||
|
services().globals.get_media_file(&shorter_key),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
db.mediaid_file.insert(&shorter_key, &[])?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
db.mediaid_file.insert(&mediaid, &[])?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
services().globals.bump_database_version(16)?;
|
||||||
|
|
||||||
|
warn!("Migration: 13 -> 16 finished");
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
services().globals.database_version().unwrap(),
|
services().globals.database_version().unwrap(),
|
||||||
latest_database_version
|
latest_database_version
|
||||||
|
|
Loading…
Reference in a new issue