client-api: Add support for authenticated media endpoints
According to MSC3916
This commit is contained in:
		
							parent
							
								
									f323f4f960
								
							
						
					
					
						commit
						73535a7dd3
					
				@ -13,6 +13,7 @@ Improvements:
 | 
				
			|||||||
- Heroes in `sync::sync_events::v4`: `SyncRequestList` and `RoomSubscription`
 | 
					- Heroes in `sync::sync_events::v4`: `SyncRequestList` and `RoomSubscription`
 | 
				
			||||||
  both have a new `include_heroes` field. `SlidingSyncRoom` has a new `heroes`
 | 
					  both have a new `include_heroes` field. `SlidingSyncRoom` has a new `heroes`
 | 
				
			||||||
  field, with a new type `SlidingSyncRoomHero`.
 | 
					  field, with a new type `SlidingSyncRoomHero`.
 | 
				
			||||||
 | 
					- Add unstable support for authenticated media endpoints, according to MSC3916.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Bug fixes:
 | 
					Bug fixes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -48,6 +48,7 @@ unstable-msc3488 = []
 | 
				
			|||||||
unstable-msc3575 = []
 | 
					unstable-msc3575 = []
 | 
				
			||||||
unstable-msc3814 = []
 | 
					unstable-msc3814 = []
 | 
				
			||||||
unstable-msc3843 = []
 | 
					unstable-msc3843 = []
 | 
				
			||||||
 | 
					unstable-msc3916 = []
 | 
				
			||||||
unstable-msc3983 = []
 | 
					unstable-msc3983 = []
 | 
				
			||||||
unstable-msc4108 = []
 | 
					unstable-msc4108 = []
 | 
				
			||||||
unstable-msc4121 = []
 | 
					unstable-msc4121 = []
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								crates/ruma-client-api/src/authenticated_media.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								crates/ruma-client-api/src/authenticated_media.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					//! Authenticated endpoints for the media repository, according to [MSC3916].
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! [MSC3916]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod get_content;
 | 
				
			||||||
 | 
					pub mod get_content_as_filename;
 | 
				
			||||||
 | 
					pub mod get_content_thumbnail;
 | 
				
			||||||
 | 
					pub mod get_media_config;
 | 
				
			||||||
 | 
					pub mod get_media_preview;
 | 
				
			||||||
@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					//! `GET /_matrix/client/*/media/download/{serverName}/{mediaId}`
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! Retrieve content from the media store.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod unstable {
 | 
				
			||||||
 | 
					    //! `/unstable/org.matrix.msc3916/` ([MSC])
 | 
				
			||||||
 | 
					    //!
 | 
				
			||||||
 | 
					    //! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE};
 | 
				
			||||||
 | 
					    use ruma_common::{
 | 
				
			||||||
 | 
					        api::{request, response, Metadata},
 | 
				
			||||||
 | 
					        metadata, IdParseError, MxcUri, OwnedServerName,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const METADATA: Metadata = metadata! {
 | 
				
			||||||
 | 
					        method: GET,
 | 
				
			||||||
 | 
					        rate_limited: false,
 | 
				
			||||||
 | 
					        authentication: AccessToken,
 | 
				
			||||||
 | 
					        history: {
 | 
				
			||||||
 | 
					            unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/download/:server_name/:media_id",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Request type for the `get_media_content` endpoint.
 | 
				
			||||||
 | 
					    #[request(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Request {
 | 
				
			||||||
 | 
					        /// The server name from the mxc:// URI (the authoritory component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub server_name: OwnedServerName,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The media ID from the mxc:// URI (the path component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub media_id: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The maximum duration that the client is willing to wait to start receiving data, in the
 | 
				
			||||||
 | 
					        /// case that the content has not yet been uploaded.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// The default value is 20 seconds.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(
 | 
				
			||||||
 | 
					            with = "ruma_common::serde::duration::ms",
 | 
				
			||||||
 | 
					            default = "crate::media::default_download_timeout",
 | 
				
			||||||
 | 
					            skip_serializing_if = "crate::media::is_default_download_timeout"
 | 
				
			||||||
 | 
					        )]
 | 
				
			||||||
 | 
					        pub timeout_ms: Duration,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Response type for the `get_media_content` endpoint.
 | 
				
			||||||
 | 
					    #[response(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Response {
 | 
				
			||||||
 | 
					        /// The content that was previously uploaded.
 | 
				
			||||||
 | 
					        #[ruma_api(raw_body)]
 | 
				
			||||||
 | 
					        pub file: Vec<u8>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The content type of the file that was previously uploaded.
 | 
				
			||||||
 | 
					        #[ruma_api(header = CONTENT_TYPE)]
 | 
				
			||||||
 | 
					        pub content_type: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
 | 
				
			||||||
 | 
					        /// file that was previously uploaded.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// See [MDN] for the syntax.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
 | 
				
			||||||
 | 
					        #[ruma_api(header = CONTENT_DISPOSITION)]
 | 
				
			||||||
 | 
					        pub content_disposition: Option<String>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Request {
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given media ID and server name.
 | 
				
			||||||
 | 
					        pub fn new(media_id: String, server_name: OwnedServerName) -> Self {
 | 
				
			||||||
 | 
					            Self { media_id, server_name, timeout_ms: crate::media::default_download_timeout() }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given URI.
 | 
				
			||||||
 | 
					        pub fn from_uri(uri: &MxcUri) -> Result<Self, IdParseError> {
 | 
				
			||||||
 | 
					            let (server_name, media_id) = uri.parts()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ok(Self::new(media_id.to_owned(), server_name.to_owned()))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Response {
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given file contents.
 | 
				
			||||||
 | 
					        pub fn new(file: Vec<u8>) -> Self {
 | 
				
			||||||
 | 
					            Self { file, content_type: None, content_disposition: None }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					//! `GET /_matrix/client/*/media/download/{serverName}/{mediaId}/{fileName}`
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! Retrieve content from the media store, specifying a filename to return.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod unstable {
 | 
				
			||||||
 | 
					    //! `/unstable/org.matrix.msc3916/` ([MSC])
 | 
				
			||||||
 | 
					    //!
 | 
				
			||||||
 | 
					    //! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE};
 | 
				
			||||||
 | 
					    use ruma_common::{
 | 
				
			||||||
 | 
					        api::{request, response, Metadata},
 | 
				
			||||||
 | 
					        metadata, IdParseError, MxcUri, OwnedServerName,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const METADATA: Metadata = metadata! {
 | 
				
			||||||
 | 
					        method: GET,
 | 
				
			||||||
 | 
					        rate_limited: false,
 | 
				
			||||||
 | 
					        authentication: AccessToken,
 | 
				
			||||||
 | 
					        history: {
 | 
				
			||||||
 | 
					            unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/download/:server_name/:media_id/:filename",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Request type for the `get_media_content_as_filename` endpoint.
 | 
				
			||||||
 | 
					    #[request(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Request {
 | 
				
			||||||
 | 
					        /// The server name from the mxc:// URI (the authoritory component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub server_name: OwnedServerName,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The media ID from the mxc:// URI (the path component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub media_id: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The filename to return in the `Content-Disposition` header.
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub filename: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The maximum duration that the client is willing to wait to start receiving data, in the
 | 
				
			||||||
 | 
					        /// case that the content has not yet been uploaded.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// The default value is 20 seconds.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(
 | 
				
			||||||
 | 
					            with = "ruma_common::serde::duration::ms",
 | 
				
			||||||
 | 
					            default = "crate::media::default_download_timeout",
 | 
				
			||||||
 | 
					            skip_serializing_if = "crate::media::is_default_download_timeout"
 | 
				
			||||||
 | 
					        )]
 | 
				
			||||||
 | 
					        pub timeout_ms: Duration,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Response type for the `get_media_content_as_filename` endpoint.
 | 
				
			||||||
 | 
					    #[response(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Response {
 | 
				
			||||||
 | 
					        /// The content that was previously uploaded.
 | 
				
			||||||
 | 
					        #[ruma_api(raw_body)]
 | 
				
			||||||
 | 
					        pub file: Vec<u8>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The content type of the file that was previously uploaded.
 | 
				
			||||||
 | 
					        #[ruma_api(header = CONTENT_TYPE)]
 | 
				
			||||||
 | 
					        pub content_type: Option<String>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
 | 
				
			||||||
 | 
					        /// file that was previously uploaded.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// See [MDN] for the syntax.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
 | 
				
			||||||
 | 
					        #[ruma_api(header = CONTENT_DISPOSITION)]
 | 
				
			||||||
 | 
					        pub content_disposition: Option<String>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Request {
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given media ID, server name and filename.
 | 
				
			||||||
 | 
					        pub fn new(media_id: String, server_name: OwnedServerName, filename: String) -> Self {
 | 
				
			||||||
 | 
					            Self {
 | 
				
			||||||
 | 
					                media_id,
 | 
				
			||||||
 | 
					                server_name,
 | 
				
			||||||
 | 
					                filename,
 | 
				
			||||||
 | 
					                timeout_ms: crate::media::default_download_timeout(),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given URI and filename.
 | 
				
			||||||
 | 
					        pub fn from_uri(uri: &MxcUri, filename: String) -> Result<Self, IdParseError> {
 | 
				
			||||||
 | 
					            let (server_name, media_id) = uri.parts()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ok(Self::new(media_id.to_owned(), server_name.to_owned(), filename))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Response {
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given file.
 | 
				
			||||||
 | 
					        pub fn new(file: Vec<u8>) -> Self {
 | 
				
			||||||
 | 
					            Self { file, content_type: None, content_disposition: None }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,134 @@
 | 
				
			|||||||
 | 
					//! `GET /_matrix/client/*/media/thumbnail/{serverName}/{mediaId}`
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! Get a thumbnail of content from the media store.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod unstable {
 | 
				
			||||||
 | 
					    //! `/unstable/org.matrix.msc3916/` ([MSC])
 | 
				
			||||||
 | 
					    //!
 | 
				
			||||||
 | 
					    //! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use http::header::CONTENT_TYPE;
 | 
				
			||||||
 | 
					    use js_int::UInt;
 | 
				
			||||||
 | 
					    use ruma_common::{
 | 
				
			||||||
 | 
					        api::{request, response, Metadata},
 | 
				
			||||||
 | 
					        metadata, IdParseError, MxcUri, OwnedServerName,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use crate::media::get_content_thumbnail::v3::Method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const METADATA: Metadata = metadata! {
 | 
				
			||||||
 | 
					        method: GET,
 | 
				
			||||||
 | 
					        rate_limited: true,
 | 
				
			||||||
 | 
					        authentication: AccessToken,
 | 
				
			||||||
 | 
					        history: {
 | 
				
			||||||
 | 
					            unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/thumbnail/:server_name/:media_id",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Request type for the `get_content_thumbnail` endpoint.
 | 
				
			||||||
 | 
					    #[request(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Request {
 | 
				
			||||||
 | 
					        /// The server name from the mxc:// URI (the authoritory component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub server_name: OwnedServerName,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The media ID from the mxc:// URI (the path component).
 | 
				
			||||||
 | 
					        #[ruma_api(path)]
 | 
				
			||||||
 | 
					        pub media_id: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The desired resizing method.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					        pub method: Option<Method>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The *desired* width of the thumbnail.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// The actual thumbnail may not match the size specified.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        pub width: UInt,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The *desired* height of the thumbnail.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// The actual thumbnail may not match the size specified.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        pub height: UInt,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The maximum duration that the client is willing to wait to start receiving data, in the
 | 
				
			||||||
 | 
					        /// case that the content has not yet been uploaded.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// The default value is 20 seconds.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(
 | 
				
			||||||
 | 
					            with = "ruma_common::serde::duration::ms",
 | 
				
			||||||
 | 
					            default = "crate::media::default_download_timeout",
 | 
				
			||||||
 | 
					            skip_serializing_if = "crate::media::is_default_download_timeout"
 | 
				
			||||||
 | 
					        )]
 | 
				
			||||||
 | 
					        pub timeout_ms: Duration,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Whether the server should return an animated thumbnail.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// When `true`, the server should return an animated thumbnail if possible and supported.
 | 
				
			||||||
 | 
					        /// Otherwise it must not return an animated thumbnail.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// Defaults to `false`.
 | 
				
			||||||
 | 
					        #[cfg(feature = "unstable-msc2705")]
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(
 | 
				
			||||||
 | 
					            rename = "org.matrix.msc2705.animated",
 | 
				
			||||||
 | 
					            default,
 | 
				
			||||||
 | 
					            skip_serializing_if = "ruma_common::serde::is_default"
 | 
				
			||||||
 | 
					        )]
 | 
				
			||||||
 | 
					        pub animated: bool,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Response type for the `get_content_thumbnail` endpoint.
 | 
				
			||||||
 | 
					    #[response(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Response {
 | 
				
			||||||
 | 
					        /// A thumbnail of the requested content.
 | 
				
			||||||
 | 
					        #[ruma_api(raw_body)]
 | 
				
			||||||
 | 
					        pub file: Vec<u8>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// The content type of the thumbnail.
 | 
				
			||||||
 | 
					        #[ruma_api(header = CONTENT_TYPE)]
 | 
				
			||||||
 | 
					        pub content_type: Option<String>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Request {
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given media ID, server name, desired thumbnail width
 | 
				
			||||||
 | 
					        /// and desired thumbnail height.
 | 
				
			||||||
 | 
					        pub fn new(
 | 
				
			||||||
 | 
					            media_id: String,
 | 
				
			||||||
 | 
					            server_name: OwnedServerName,
 | 
				
			||||||
 | 
					            width: UInt,
 | 
				
			||||||
 | 
					            height: UInt,
 | 
				
			||||||
 | 
					        ) -> Self {
 | 
				
			||||||
 | 
					            Self {
 | 
				
			||||||
 | 
					                media_id,
 | 
				
			||||||
 | 
					                server_name,
 | 
				
			||||||
 | 
					                method: None,
 | 
				
			||||||
 | 
					                width,
 | 
				
			||||||
 | 
					                height,
 | 
				
			||||||
 | 
					                timeout_ms: crate::media::default_download_timeout(),
 | 
				
			||||||
 | 
					                #[cfg(feature = "unstable-msc2705")]
 | 
				
			||||||
 | 
					                animated: false,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given URI, desired thumbnail width and
 | 
				
			||||||
 | 
					        /// desired thumbnail height.
 | 
				
			||||||
 | 
					        pub fn from_uri(uri: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
 | 
				
			||||||
 | 
					            let (server_name, media_id) = uri.parts()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Response {
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given thumbnail.
 | 
				
			||||||
 | 
					        pub fn new(file: Vec<u8>) -> Self {
 | 
				
			||||||
 | 
					            Self { file, content_type: None }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					//! `GET /_matrix/client/*/media/config`
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! Gets the config for the media repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod unstable {
 | 
				
			||||||
 | 
					    //! `/unstable/org.matrix.msc3916/` ([MSC])
 | 
				
			||||||
 | 
					    //!
 | 
				
			||||||
 | 
					    //! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use js_int::UInt;
 | 
				
			||||||
 | 
					    use ruma_common::{
 | 
				
			||||||
 | 
					        api::{request, response, Metadata},
 | 
				
			||||||
 | 
					        metadata,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const METADATA: Metadata = metadata! {
 | 
				
			||||||
 | 
					        method: GET,
 | 
				
			||||||
 | 
					        rate_limited: true,
 | 
				
			||||||
 | 
					        authentication: AccessToken,
 | 
				
			||||||
 | 
					        history: {
 | 
				
			||||||
 | 
					            unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/config",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Request type for the `get_media_config` endpoint.
 | 
				
			||||||
 | 
					    #[request(error = crate::Error)]
 | 
				
			||||||
 | 
					    #[derive(Default)]
 | 
				
			||||||
 | 
					    pub struct Request {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Response type for the `get_media_config` endpoint.
 | 
				
			||||||
 | 
					    #[response(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Response {
 | 
				
			||||||
 | 
					        /// Maximum size of upload in bytes.
 | 
				
			||||||
 | 
					        #[serde(rename = "m.upload.size")]
 | 
				
			||||||
 | 
					        pub upload_size: UInt,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Request {
 | 
				
			||||||
 | 
					        /// Creates an empty `Request`.
 | 
				
			||||||
 | 
					        pub fn new() -> Self {
 | 
				
			||||||
 | 
					            Self {}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Response {
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given maximum upload size.
 | 
				
			||||||
 | 
					        pub fn new(upload_size: UInt) -> Self {
 | 
				
			||||||
 | 
					            Self { upload_size }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					//! `GET /_matrix/client/*/media/preview_url`
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! Get a preview for a URL.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod unstable {
 | 
				
			||||||
 | 
					    //! `/unstable/org.matrix.msc3916/` ([MSC])
 | 
				
			||||||
 | 
					    //!
 | 
				
			||||||
 | 
					    //! [MSC]: https://github.com/matrix-org/matrix-spec-proposals/pull/3916
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use ruma_common::{
 | 
				
			||||||
 | 
					        api::{request, response, Metadata},
 | 
				
			||||||
 | 
					        metadata, MilliSecondsSinceUnixEpoch,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    use serde::Serialize;
 | 
				
			||||||
 | 
					    use serde_json::value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const METADATA: Metadata = metadata! {
 | 
				
			||||||
 | 
					        method: GET,
 | 
				
			||||||
 | 
					        rate_limited: true,
 | 
				
			||||||
 | 
					        authentication: AccessToken,
 | 
				
			||||||
 | 
					        history: {
 | 
				
			||||||
 | 
					            unstable => "/_matrix/client/unstable/org.matrix.msc3916/media/preview_url",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Request type for the `get_media_preview` endpoint.
 | 
				
			||||||
 | 
					    #[request(error = crate::Error)]
 | 
				
			||||||
 | 
					    pub struct Request {
 | 
				
			||||||
 | 
					        /// URL to get a preview of.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        pub url: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Preferred point in time (in milliseconds) to return a preview for.
 | 
				
			||||||
 | 
					        #[ruma_api(query)]
 | 
				
			||||||
 | 
					        #[serde(skip_serializing_if = "Option::is_none")]
 | 
				
			||||||
 | 
					        pub ts: Option<MilliSecondsSinceUnixEpoch>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Response type for the `get_media_preview` endpoint.
 | 
				
			||||||
 | 
					    #[response(error = crate::Error)]
 | 
				
			||||||
 | 
					    #[derive(Default)]
 | 
				
			||||||
 | 
					    pub struct Response {
 | 
				
			||||||
 | 
					        /// OpenGraph-like data for the URL.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// Differences from OpenGraph: the image size in bytes is added to the `matrix:image:size`
 | 
				
			||||||
 | 
					        /// field, and `og:image` returns the MXC URI to the image, if any.
 | 
				
			||||||
 | 
					        #[ruma_api(body)]
 | 
				
			||||||
 | 
					        pub data: Option<Box<RawJsonValue>>,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Request {
 | 
				
			||||||
 | 
					        /// Creates a new `Request` with the given URL.
 | 
				
			||||||
 | 
					        pub fn new(url: String) -> Self {
 | 
				
			||||||
 | 
					            Self { url, ts: None }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Response {
 | 
				
			||||||
 | 
					        /// Creates an empty `Response`.
 | 
				
			||||||
 | 
					        pub fn new() -> Self {
 | 
				
			||||||
 | 
					            Self { data: None }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given OpenGraph data (in a
 | 
				
			||||||
 | 
					        /// `serde_json::value::RawValue`).
 | 
				
			||||||
 | 
					        pub fn from_raw_value(data: Box<RawJsonValue>) -> Self {
 | 
				
			||||||
 | 
					            Self { data: Some(data) }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Creates a new `Response` with the given OpenGraph data (in any kind of serializable
 | 
				
			||||||
 | 
					        /// object).
 | 
				
			||||||
 | 
					        pub fn from_serialize<T: Serialize>(data: &T) -> serde_json::Result<Self> {
 | 
				
			||||||
 | 
					            Ok(Self { data: Some(to_raw_json_value(data)?) })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(test)]
 | 
				
			||||||
 | 
					    mod tests {
 | 
				
			||||||
 | 
					        use assert_matches2::assert_matches;
 | 
				
			||||||
 | 
					        use serde_json::{
 | 
				
			||||||
 | 
					            from_value as from_json_value, json,
 | 
				
			||||||
 | 
					            value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue},
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Since BTreeMap<String, Box<RawJsonValue>> deserialization doesn't seem to
 | 
				
			||||||
 | 
					        // work, test that Option<RawJsonValue> works
 | 
				
			||||||
 | 
					        #[test]
 | 
				
			||||||
 | 
					        fn raw_json_deserialize() {
 | 
				
			||||||
 | 
					            type OptRawJson = Option<Box<RawJsonValue>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            assert_matches!(from_json_value::<OptRawJson>(json!(null)).unwrap(), None);
 | 
				
			||||||
 | 
					            from_json_value::<OptRawJson>(json!("test")).unwrap().unwrap();
 | 
				
			||||||
 | 
					            from_json_value::<OptRawJson>(json!({ "a": "b" })).unwrap().unwrap();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For completeness sake, make sure serialization works too
 | 
				
			||||||
 | 
					        #[test]
 | 
				
			||||||
 | 
					        fn raw_json_serialize() {
 | 
				
			||||||
 | 
					            to_raw_json_value(&json!(null)).unwrap();
 | 
				
			||||||
 | 
					            to_raw_json_value(&json!("string")).unwrap();
 | 
				
			||||||
 | 
					            to_raw_json_value(&json!({})).unwrap();
 | 
				
			||||||
 | 
					            to_raw_json_value(&json!({ "a": "b" })).unwrap();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -12,6 +12,8 @@
 | 
				
			|||||||
pub mod account;
 | 
					pub mod account;
 | 
				
			||||||
pub mod alias;
 | 
					pub mod alias;
 | 
				
			||||||
pub mod appservice;
 | 
					pub mod appservice;
 | 
				
			||||||
 | 
					#[cfg(feature = "unstable-msc3916")]
 | 
				
			||||||
 | 
					pub mod authenticated_media;
 | 
				
			||||||
pub mod backup;
 | 
					pub mod backup;
 | 
				
			||||||
pub mod config;
 | 
					pub mod config;
 | 
				
			||||||
pub mod context;
 | 
					pub mod context;
 | 
				
			||||||
 | 
				
			|||||||
@ -12,12 +12,12 @@ pub mod get_media_config;
 | 
				
			|||||||
pub mod get_media_preview;
 | 
					pub mod get_media_preview;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The default duration that the client should be willing to wait to start receiving data.
 | 
					/// The default duration that the client should be willing to wait to start receiving data.
 | 
				
			||||||
fn default_download_timeout() -> Duration {
 | 
					pub(crate) fn default_download_timeout() -> Duration {
 | 
				
			||||||
    Duration::from_secs(20)
 | 
					    Duration::from_secs(20)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Whether the given duration is the default duration that the client should be willing to wait to
 | 
					/// Whether the given duration is the default duration that the client should be willing to wait to
 | 
				
			||||||
/// start receiving data.
 | 
					/// start receiving data.
 | 
				
			||||||
fn is_default_download_timeout(timeout: &Duration) -> bool {
 | 
					pub(crate) fn is_default_download_timeout(timeout: &Duration) -> bool {
 | 
				
			||||||
    timeout.as_secs() == 20
 | 
					    timeout.as_secs() == 20
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -216,6 +216,7 @@ unstable-msc3618 = ["ruma-federation-api?/unstable-msc3618"]
 | 
				
			|||||||
unstable-msc3723 = ["ruma-federation-api?/unstable-msc3723"]
 | 
					unstable-msc3723 = ["ruma-federation-api?/unstable-msc3723"]
 | 
				
			||||||
unstable-msc3814 = ["ruma-client-api?/unstable-msc3814"]
 | 
					unstable-msc3814 = ["ruma-client-api?/unstable-msc3814"]
 | 
				
			||||||
unstable-msc3843 = ["ruma-client-api?/unstable-msc3843", "ruma-federation-api?/unstable-msc3843"]
 | 
					unstable-msc3843 = ["ruma-client-api?/unstable-msc3843", "ruma-federation-api?/unstable-msc3843"]
 | 
				
			||||||
 | 
					unstable-msc3916 = ["ruma-client-api?/unstable-msc3916"]
 | 
				
			||||||
unstable-msc3927 = ["ruma-events?/unstable-msc3927"]
 | 
					unstable-msc3927 = ["ruma-events?/unstable-msc3927"]
 | 
				
			||||||
unstable-msc3930 = ["ruma-common/unstable-msc3930"]
 | 
					unstable-msc3930 = ["ruma-common/unstable-msc3930"]
 | 
				
			||||||
unstable-msc3931 = ["ruma-common/unstable-msc3931"]
 | 
					unstable-msc3931 = ["ruma-common/unstable-msc3931"]
 | 
				
			||||||
@ -270,6 +271,7 @@ __ci = [
 | 
				
			|||||||
    "unstable-msc3723",
 | 
					    "unstable-msc3723",
 | 
				
			||||||
    "unstable-msc3814",
 | 
					    "unstable-msc3814",
 | 
				
			||||||
    "unstable-msc3843",
 | 
					    "unstable-msc3843",
 | 
				
			||||||
 | 
					    "unstable-msc3916",
 | 
				
			||||||
    "unstable-msc3927",
 | 
					    "unstable-msc3927",
 | 
				
			||||||
    "unstable-msc3930",
 | 
					    "unstable-msc3930",
 | 
				
			||||||
    "unstable-msc3931",
 | 
					    "unstable-msc3931",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user