add MSC2246 support

This commit is contained in:
Donjuanplatinum
2026-03-01 05:15:09 +08:00
parent d2836e9f50
commit 2b81e189cb
8 changed files with 461 additions and 8 deletions

View File

@@ -4,13 +4,13 @@ use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use reqwest::Url;
use ruma::{
Mxc, UserId,
MilliSecondsSinceUnixEpoch, Mxc, UserId,
api::client::{
authenticated_media::{
get_content, get_content_as_filename, get_content_thumbnail, get_media_config,
get_media_preview,
},
media::create_content,
media::{create_content, create_content_async, create_mxc_uri},
},
};
use tuwunel_core::{
@@ -80,6 +80,80 @@ pub(crate) async fn create_content_route(
})
}
/// # `POST /_matrix/media/v1/create`
///
/// Create a new MXC URI without content.
#[tracing::instrument(
name = "media_create_mxc",
level = "debug",
skip_all,
fields(%client),
)]
pub(crate) async fn create_mxc_uri_route(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<create_mxc_uri::v1::Request>,
) -> Result<create_mxc_uri::v1::Response> {
let user = body.sender_user();
let mxc = Mxc {
server_name: services.globals.server_name(),
media_id: &utils::random_string(MXC_LENGTH),
};
let unused_expires_at = (std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64)
.saturating_add(
services
.server
.config
.media_create_unused_expiration_time
* 1000,
);
services
.media
.create_pending(&mxc, user, unused_expires_at)
.await?;
Ok(create_mxc_uri::v1::Response {
content_uri: mxc.to_string().into(),
unused_expires_at: ruma::UInt::new(unused_expires_at).map(MilliSecondsSinceUnixEpoch),
})
}
/// # `PUT /_matrix/media/v3/upload/{serverName}/{mediaId}`
///
/// Upload content to a MXC URI that was created earlier.
#[tracing::instrument(
name = "media_upload_async",
level = "debug",
skip_all,
fields(%client),
)]
pub(crate) async fn create_content_async_route(
State(services): State<crate::State>,
InsecureClientIp(client): InsecureClientIp,
body: Ruma<create_content_async::v3::Request>,
) -> Result<create_content_async::v3::Response> {
let user = body.sender_user();
let mxc = Mxc {
server_name: &body.server_name,
media_id: &body.media_id,
};
let filename = body.filename.as_deref();
let content_type = body.content_type.as_deref();
let content_disposition = make_content_disposition(None, content_type, filename);
services
.media
.upload_pending(&mxc, user, Some(&content_disposition), content_type, &body.file)
.await?;
Ok(create_content_async::v3::Response {})
}
/// # `GET /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}`
///
/// Load media thumbnail from our server or over federation.
@@ -296,7 +370,11 @@ async fn fetch_thumbnail_meta(
timeout_ms: Duration,
dim: &Dim,
) -> Result<FileMeta> {
if let Some(filemeta) = services.media.get_thumbnail(mxc, dim).await? {
if let Some(filemeta) = services
.media
.get_thumbnail_with_timeout(mxc, dim, timeout_ms)
.await?
{
return Ok(filemeta);
}
@@ -316,7 +394,11 @@ async fn fetch_file_meta(
user: &UserId,
timeout_ms: Duration,
) -> Result<FileMeta> {
if let Some(filemeta) = services.media.get(mxc).await? {
if let Some(filemeta) = services
.media
.get_with_timeout(mxc, timeout_ms)
.await?
{
return Ok(filemeta);
}

View File

@@ -145,7 +145,11 @@ pub(crate) async fn get_content_legacy_route(
media_id: &body.media_id,
};
match services.media.get(&mxc).await? {
match services
.media
.get_with_timeout(&mxc, body.timeout_ms)
.await?
{
| Some(FileMeta {
content,
content_type,
@@ -236,7 +240,11 @@ pub(crate) async fn get_content_as_filename_legacy_route(
media_id: &body.media_id,
};
match services.media.get(&mxc).await? {
match services
.media
.get_with_timeout(&mxc, body.timeout_ms)
.await?
{
| Some(FileMeta {
content,
content_type,
@@ -327,7 +335,11 @@ pub(crate) async fn get_content_thumbnail_legacy_route(
};
let dim = Dim::from_ruma(body.width, body.height, body.method.clone())?;
match services.media.get_thumbnail(&mxc, &dim).await? {
match services
.media
.get_thumbnail_with_timeout(&mxc, &dim, body.timeout_ms)
.await?
{
| Some(FileMeta {
content,
content_type,

View File

@@ -158,6 +158,8 @@ pub fn build(router: Router<State>, server: &Server) -> Router<State> {
.ruma_route(&client::turn_server_route)
.ruma_route(&client::send_event_to_device_route)
.ruma_route(&client::create_content_route)
.ruma_route(&client::create_mxc_uri_route)
.ruma_route(&client::create_content_async_route)
.ruma_route(&client::get_content_thumbnail_route)
.ruma_route(&client::get_content_route)
.ruma_route(&client::get_content_as_filename_route)