client-api: Implement asynchronous uploads (MSC2246)
https://github.com/matrix-org/matrix-spec-proposals/pull/2246
This commit is contained in:
parent
62c4d7ab72
commit
ddc5279b6e
@ -18,6 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
[features]
|
[features]
|
||||||
compat = []
|
compat = []
|
||||||
unstable-exhaustive-types = []
|
unstable-exhaustive-types = []
|
||||||
|
unstable-msc2246 = []
|
||||||
unstable-msc2448 = []
|
unstable-msc2448 = []
|
||||||
unstable-msc2654 = []
|
unstable-msc2654 = []
|
||||||
unstable-msc2676 = []
|
unstable-msc2676 = []
|
||||||
|
@ -141,6 +141,14 @@ pub enum ErrorKind {
|
|||||||
/// M_WEAK_PASSWORD
|
/// M_WEAK_PASSWORD
|
||||||
WeakPassword,
|
WeakPassword,
|
||||||
|
|
||||||
|
/// FI.MAU.MSC2246_NOT_YET_UPLOADED
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
NotYetUploaded,
|
||||||
|
|
||||||
|
/// FI.MAU.MSC2246_CANNOT_OVERWRITE_MEDIA
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
CannotOverwriteMedia,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_Custom { errcode: PrivOwnedStr, extra: Extra },
|
_Custom { errcode: PrivOwnedStr, extra: Extra },
|
||||||
}
|
}
|
||||||
@ -185,6 +193,10 @@ impl AsRef<str> for ErrorKind {
|
|||||||
Self::ResourceLimitExceeded { .. } => "M_RESOURCE_LIMIT_EXCEEDED",
|
Self::ResourceLimitExceeded { .. } => "M_RESOURCE_LIMIT_EXCEEDED",
|
||||||
Self::CannotLeaveServerNoticeRoom => "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM",
|
Self::CannotLeaveServerNoticeRoom => "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM",
|
||||||
Self::WeakPassword => "M_WEAK_PASSWORD",
|
Self::WeakPassword => "M_WEAK_PASSWORD",
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
Self::NotYetUploaded => "FI.MAU.MSC2246_NOT_YET_UPLOADED",
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
Self::CannotOverwriteMedia => "FI.MAU.MSC2246_CANNOT_OVERWRITE_MEDIA",
|
||||||
Self::_Custom { errcode, .. } => &errcode.0,
|
Self::_Custom { errcode, .. } => &errcode.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,10 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
|
|||||||
},
|
},
|
||||||
ErrCode::CannotLeaveServerNoticeRoom => ErrorKind::CannotLeaveServerNoticeRoom,
|
ErrCode::CannotLeaveServerNoticeRoom => ErrorKind::CannotLeaveServerNoticeRoom,
|
||||||
ErrCode::WeakPassword => ErrorKind::WeakPassword,
|
ErrCode::WeakPassword => ErrorKind::WeakPassword,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
ErrCode::NotYetUploaded => ErrorKind::NotYetUploaded,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
ErrCode::CannotOverwriteMedia => ErrorKind::CannotOverwriteMedia,
|
||||||
ErrCode::_Custom(errcode) => ErrorKind::_Custom { errcode, extra },
|
ErrCode::_Custom(errcode) => ErrorKind::_Custom { errcode, extra },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -247,6 +251,15 @@ enum ErrCode {
|
|||||||
ResourceLimitExceeded,
|
ResourceLimitExceeded,
|
||||||
CannotLeaveServerNoticeRoom,
|
CannotLeaveServerNoticeRoom,
|
||||||
WeakPassword,
|
WeakPassword,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
#[ruma_enum(rename = "FI.MAU.MSC2246_NOT_YET_UPLOADED", alias = "M_NOT_YET_UPLOADED")]
|
||||||
|
NotYetUploaded,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
#[ruma_enum(
|
||||||
|
rename = "FI.MAU.MSC2246_CANNOT_OVERWRITE_MEDIA",
|
||||||
|
alias = "M_CANNOT_OVERWRITE_MEDIA"
|
||||||
|
)]
|
||||||
|
CannotOverwriteMedia,
|
||||||
_Custom(PrivOwnedStr),
|
_Custom(PrivOwnedStr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
//! Endpoints for the media repository.
|
//! Endpoints for the media repository.
|
||||||
|
|
||||||
pub mod create_content;
|
pub mod create_content;
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
pub mod create_content_async;
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
pub mod create_mxc_uri;
|
||||||
pub mod get_content;
|
pub mod get_content;
|
||||||
pub mod get_content_as_filename;
|
pub mod get_content_as_filename;
|
||||||
pub mod get_content_thumbnail;
|
pub mod get_content_thumbnail;
|
||||||
|
57
crates/ruma-client-api/src/media/create_content_async.rs
Normal file
57
crates/ruma-client-api/src/media/create_content_async.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//! `POST /_matrix/media/*/upload/{serverName}/{mediaId}`
|
||||||
|
|
||||||
|
pub mod unstable {
|
||||||
|
//! `/unstable/` ([spec])
|
||||||
|
//!
|
||||||
|
//! [spec]: https://github.com/tulir/matrix-doc/blob/asynchronous_uploads/proposals/2246-asynchronous-uploads.md
|
||||||
|
|
||||||
|
use ruma_common::{api::ruma_api, IdParseError, MxcUri, ServerName};
|
||||||
|
|
||||||
|
ruma_api! {
|
||||||
|
metadata: {
|
||||||
|
description: "Upload media to an MXC URI that was created with create_mxc_uri.",
|
||||||
|
method: PUT,
|
||||||
|
name: "create_content_async",
|
||||||
|
unstable_path: "/_matrix/media/unstable/fi.mau.msc2246/upload/:server_name/:media_id",
|
||||||
|
rate_limited: true,
|
||||||
|
authentication: AccessToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
request: {
|
||||||
|
/// The media ID from the mxc:// URI (the path component).
|
||||||
|
#[ruma_api(path)]
|
||||||
|
pub media_id: &'a str,
|
||||||
|
|
||||||
|
/// The server name from the mxc:// URI (the authoritory component).
|
||||||
|
#[ruma_api(path)]
|
||||||
|
pub server_name: &'a ServerName,
|
||||||
|
|
||||||
|
/// The file contents to upload.
|
||||||
|
#[ruma_api(raw_body)]
|
||||||
|
pub file: &'a [u8],
|
||||||
|
|
||||||
|
/// The content type of the file being uploaded.
|
||||||
|
#[ruma_api(header = CONTENT_TYPE)]
|
||||||
|
pub content_type: Option<&'a str>,
|
||||||
|
|
||||||
|
// TODO: How does this and msc2448 (blurhash) interact?
|
||||||
|
}
|
||||||
|
|
||||||
|
response: {}
|
||||||
|
|
||||||
|
error: crate::Error
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Request<'a> {
|
||||||
|
/// Creates a new `Request` with the given file contents.
|
||||||
|
pub fn new(media_id: &'a str, server_name: &'a ServerName, file: &'a [u8]) -> Self {
|
||||||
|
Self { media_id, server_name, file, content_type: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new `Request` with the given url and file contents.
|
||||||
|
pub fn from_url(url: &'a MxcUri, file: &'a [u8]) -> Result<Self, IdParseError> {
|
||||||
|
let (server_name, media_id) = url.parts()?;
|
||||||
|
Ok(Self::new(media_id, server_name, file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
crates/ruma-client-api/src/media/create_mxc_uri.rs
Normal file
40
crates/ruma-client-api/src/media/create_mxc_uri.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//! `POST /_matrix/media/*/create`
|
||||||
|
|
||||||
|
pub mod unstable {
|
||||||
|
//! `/unstable/` ([spec])
|
||||||
|
//!
|
||||||
|
//! [spec]: https://github.com/tulir/matrix-doc/blob/asynchronous_uploads/proposals/2246-asynchronous-uploads.md
|
||||||
|
|
||||||
|
use js_int::UInt;
|
||||||
|
use ruma_common::{api::ruma_api, OwnedMxcUri};
|
||||||
|
|
||||||
|
ruma_api! {
|
||||||
|
metadata: {
|
||||||
|
description: "Create an MXC URI without content.",
|
||||||
|
method: POST,
|
||||||
|
name: "create_mxc_uri",
|
||||||
|
unstable_path: "/_matrix/media/unstable/fi.mau.msc2246/create",
|
||||||
|
rate_limited: true,
|
||||||
|
authentication: AccessToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
request: {}
|
||||||
|
|
||||||
|
response: {
|
||||||
|
/// The MXC URI for the about to be uploaded content.
|
||||||
|
pub content_uri: OwnedMxcUri,
|
||||||
|
|
||||||
|
/// The time at which the URI will expire if an upload has not been started.
|
||||||
|
pub unused_expires_at: UInt,
|
||||||
|
}
|
||||||
|
|
||||||
|
error: crate::Error
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Response {
|
||||||
|
/// Creates a new `Response` with the given MXC URI which expires at a given point in time.
|
||||||
|
pub fn new(content_uri: OwnedMxcUri, unused_expires_at: UInt) -> Self {
|
||||||
|
Self { content_uri, unused_expires_at }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ pub mod v3 {
|
|||||||
//!
|
//!
|
||||||
//! [spec]: https://spec.matrix.org/v1.2/client-server-api/#get_matrixmediav3downloadservernamemediaid
|
//! [spec]: https://spec.matrix.org/v1.2/client-server-api/#get_matrixmediav3downloadservernamemediaid
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
use js_int::UInt;
|
||||||
use ruma_common::{api::ruma_api, IdParseError, MxcUri, ServerName};
|
use ruma_common::{api::ruma_api, IdParseError, MxcUri, ServerName};
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
@ -34,6 +36,21 @@ pub mod v3 {
|
|||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
#[serde(default = "ruma_common::serde::default_true", skip_serializing_if = "ruma_common::serde::is_true")]
|
#[serde(default = "ruma_common::serde::default_true", skip_serializing_if = "ruma_common::serde::is_true")]
|
||||||
pub allow_remote: bool,
|
pub allow_remote: bool,
|
||||||
|
|
||||||
|
|
||||||
|
/// How long to wait for the media to be uploaded
|
||||||
|
///
|
||||||
|
/// This uses the unstable prefix in
|
||||||
|
/// [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246)
|
||||||
|
#[ruma_api(query)]
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
skip_serializing_if = "ruma_common::serde::is_default",
|
||||||
|
rename = "fi.mau.msc2246.max_stall_ms",
|
||||||
|
alias = "max_stall_ms"
|
||||||
|
)]
|
||||||
|
pub max_stall_ms: Option<UInt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
response: {
|
response: {
|
||||||
@ -61,14 +78,20 @@ pub mod v3 {
|
|||||||
impl<'a> Request<'a> {
|
impl<'a> Request<'a> {
|
||||||
/// Creates a new `Request` with the given media ID and server name.
|
/// Creates a new `Request` with the given media ID and server name.
|
||||||
pub fn new(media_id: &'a str, server_name: &'a ServerName) -> Self {
|
pub fn new(media_id: &'a str, server_name: &'a ServerName) -> Self {
|
||||||
Self { media_id, server_name, allow_remote: true }
|
Self {
|
||||||
|
media_id,
|
||||||
|
server_name,
|
||||||
|
allow_remote: true,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
max_stall_ms: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `Request` with the given url.
|
/// Creates a new `Request` with the given url.
|
||||||
pub fn from_url(url: &'a MxcUri) -> Result<Self, IdParseError> {
|
pub fn from_url(url: &'a MxcUri) -> Result<Self, IdParseError> {
|
||||||
let (server_name, media_id) = url.parts()?;
|
let (server_name, media_id) = url.parts()?;
|
||||||
|
|
||||||
Ok(Self { media_id, server_name, allow_remote: true })
|
Ok(Self::new(media_id, server_name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,20 @@ pub mod v3 {
|
|||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
#[serde(default = "ruma_common::serde::default_true", skip_serializing_if = "ruma_common::serde::is_true")]
|
#[serde(default = "ruma_common::serde::default_true", skip_serializing_if = "ruma_common::serde::is_true")]
|
||||||
pub allow_remote: bool,
|
pub allow_remote: bool,
|
||||||
|
|
||||||
|
/// How long to wait for the media to be uploaded
|
||||||
|
///
|
||||||
|
/// This uses the unstable prefix in
|
||||||
|
/// [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246)
|
||||||
|
#[ruma_api(query)]
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
skip_serializing_if = "ruma_common::serde::is_default",
|
||||||
|
rename = "fi.mau.msc2246.max_stall_ms",
|
||||||
|
alias = "max_stall_ms"
|
||||||
|
)]
|
||||||
|
pub max_stall_ms: Option<UInt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
response: {
|
response: {
|
||||||
@ -78,7 +92,16 @@ pub mod v3 {
|
|||||||
width: UInt,
|
width: UInt,
|
||||||
height: UInt,
|
height: UInt,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { media_id, server_name, method: None, width, height, allow_remote: true }
|
Self {
|
||||||
|
media_id,
|
||||||
|
server_name,
|
||||||
|
method: None,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
allow_remote: true,
|
||||||
|
#[cfg(feature = "unstable-msc2246")]
|
||||||
|
max_stall_ms: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `Request` with the given url, desired thumbnail width and
|
/// Creates a new `Request` with the given url, desired thumbnail width and
|
||||||
@ -86,7 +109,7 @@ pub mod v3 {
|
|||||||
pub fn from_url(url: &'a MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
|
pub fn from_url(url: &'a MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
|
||||||
let (server_name, media_id) = url.parts()?;
|
let (server_name, media_id) = url.parts()?;
|
||||||
|
|
||||||
Ok(Self { media_id, server_name, method: None, width, height, allow_remote: true })
|
Ok(Self::new(media_id, server_name, width, height))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ unstable-pre-spec = [
|
|||||||
"ruma-push-gateway-api/unstable-pre-spec",
|
"ruma-push-gateway-api/unstable-pre-spec",
|
||||||
]
|
]
|
||||||
unstable-msc1767 = ["ruma-common/unstable-msc1767"]
|
unstable-msc1767 = ["ruma-common/unstable-msc1767"]
|
||||||
|
unstable-msc2246 = ["ruma-client-api/unstable-msc2246"]
|
||||||
unstable-msc2448 = [
|
unstable-msc2448 = [
|
||||||
"ruma-client-api/unstable-msc2448",
|
"ruma-client-api/unstable-msc2448",
|
||||||
"ruma-common/unstable-msc2448",
|
"ruma-common/unstable-msc2448",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user