conduit/src/client_server/media.rs

104 lines
2.9 KiB
Rust
Raw Normal View History

2020-07-30 16:14:47 +00:00
use super::State;
use crate::{database::media::FileMeta, utils, ConduitResult, Database, Error, Ruma};
use ruma::api::client::{
error::ErrorKind,
r0::media::{create_content, get_content, get_content_thumbnail, get_media_config},
};
#[cfg(feature = "conduit_bin")]
use rocket::{get, post};
use std::convert::TryInto;
const MXC_LENGTH: usize = 256;
#[cfg_attr(feature = "conduit_bin", get("/_matrix/media/r0/config"))]
pub fn get_media_config_route(
db: State<'_, Database>,
) -> ConduitResult<get_media_config::Response> {
Ok(get_media_config::Response {
upload_size: db.globals.max_request_size().into(),
}
.into())
}
#[cfg_attr(
feature = "conduit_bin",
post("/_matrix/media/r0/upload", data = "<body>")
)]
pub fn create_content_route(
db: State<'_, Database>,
2020-09-08 15:32:03 +00:00
body: Ruma<create_content::Request<'_>>,
2020-07-30 16:14:47 +00:00
) -> ConduitResult<create_content::Response> {
let mxc = format!(
"mxc://{}/{}",
db.globals.server_name(),
utils::random_string(MXC_LENGTH)
);
2020-09-12 19:30:07 +00:00
db.media
.create(mxc.clone(), &body.filename, &body.content_type, &body.file)?;
2020-07-30 16:14:47 +00:00
Ok(create_content::Response { content_uri: mxc }.into())
}
#[cfg_attr(
feature = "conduit_bin",
get(
"/_matrix/media/r0/download/<_server_name>/<_media_id>",
data = "<body>"
)
)]
pub fn get_content_route(
db: State<'_, Database>,
2020-09-08 15:32:03 +00:00
body: Ruma<get_content::Request<'_>>,
2020-07-30 16:14:47 +00:00
_server_name: String,
_media_id: String,
) -> ConduitResult<get_content::Response> {
if let Some(FileMeta {
filename,
content_type,
file,
}) = db
.media
.get(format!("mxc://{}/{}", body.server_name, body.media_id))?
{
Ok(get_content::Response {
file,
content_type,
content_disposition: filename.unwrap_or_default(), // TODO: Spec says this should be optional
}
.into())
} else {
Err(Error::BadRequest(ErrorKind::NotFound, "Media not found."))
}
}
#[cfg_attr(
feature = "conduit_bin",
get(
"/_matrix/media/r0/thumbnail/<_server_name>/<_media_id>",
data = "<body>"
)
)]
pub fn get_content_thumbnail_route(
db: State<'_, Database>,
2020-09-08 15:32:03 +00:00
body: Ruma<get_content_thumbnail::Request<'_>>,
2020-07-30 16:14:47 +00:00
_server_name: String,
_media_id: String,
) -> ConduitResult<get_content_thumbnail::Response> {
if let Some(FileMeta {
content_type, file, ..
}) = db.media.get_thumbnail(
format!("mxc://{}/{}", body.server_name, body.media_id),
body.width
.try_into()
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?,
body.height
.try_into()
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?,
)? {
Ok(get_content_thumbnail::Response { file, content_type }.into())
} else {
Err(Error::BadRequest(ErrorKind::NotFound, "Media not found."))
}
}