ruma_client_api/media/
get_content_thumbnail.rs

1//! `GET /_matrix/media/*/thumbnail/{serverName}/{mediaId}`
2//!
3//! Get a thumbnail of content from the media store.
4
5pub mod v3 {
6    //! `/v3/` ([spec])
7    //!
8    //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixmediav3thumbnailservernamemediaid
9
10    use std::time::Duration;
11
12    use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE};
13    use js_int::UInt;
14    pub use ruma_common::media::Method;
15    use ruma_common::{
16        api::{request, response, Metadata},
17        http_headers::ContentDisposition,
18        metadata, IdParseError, MxcUri, OwnedServerName,
19    };
20
21    use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
22
23    const METADATA: Metadata = metadata! {
24        method: GET,
25        rate_limited: true,
26        authentication: None,
27        history: {
28            1.0 => "/_matrix/media/r0/thumbnail/:server_name/:media_id",
29            1.1 => "/_matrix/media/v3/thumbnail/:server_name/:media_id",
30            1.11 => deprecated,
31        }
32    };
33
34    /// Request type for the `get_content_thumbnail` endpoint.
35    #[request(error = crate::Error)]
36    #[deprecated = "\
37        Since Matrix 1.11, clients should use `authenticated_media::get_content_thumbnail::v1::Request` \
38        instead if the homeserver supports it.\
39    "]
40    pub struct Request {
41        /// The server name from the mxc:// URI (the authoritory component).
42        #[ruma_api(path)]
43        pub server_name: OwnedServerName,
44
45        /// The media ID from the mxc:// URI (the path component).
46        #[ruma_api(path)]
47        pub media_id: String,
48
49        /// The desired resizing method.
50        #[ruma_api(query)]
51        #[serde(skip_serializing_if = "Option::is_none")]
52        pub method: Option<Method>,
53
54        /// The *desired* width of the thumbnail.
55        ///
56        /// The actual thumbnail may not match the size specified.
57        #[ruma_api(query)]
58        pub width: UInt,
59
60        /// The *desired* height of the thumbnail.
61        ///
62        /// The actual thumbnail may not match the size specified.
63        #[ruma_api(query)]
64        pub height: UInt,
65
66        /// Whether to fetch media deemed remote.
67        ///
68        /// Used to prevent routing loops. Defaults to `true`.
69        #[ruma_api(query)]
70        #[serde(
71            default = "ruma_common::serde::default_true",
72            skip_serializing_if = "ruma_common::serde::is_true"
73        )]
74        pub allow_remote: bool,
75
76        /// The maximum duration that the client is willing to wait to start receiving data, in the
77        /// case that the content has not yet been uploaded.
78        ///
79        /// The default value is 20 seconds.
80        #[ruma_api(query)]
81        #[serde(
82            with = "ruma_common::serde::duration::ms",
83            default = "ruma_common::media::default_download_timeout",
84            skip_serializing_if = "ruma_common::media::is_default_download_timeout"
85        )]
86        pub timeout_ms: Duration,
87
88        /// Whether the server may return a 307 or 308 redirect response that points at the
89        /// relevant media content.
90        ///
91        /// Unless explicitly set to `true`, the server must return the media content itself.
92        #[ruma_api(query)]
93        #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
94        pub allow_redirect: bool,
95
96        /// Whether the server should return an animated thumbnail.
97        ///
98        /// When `Some(true)`, the server should return an animated thumbnail if possible and
99        /// supported. When `Some(false)`, the server must not return an animated
100        /// thumbnail. When `None`, the server should not return an animated thumbnail.
101        #[ruma_api(query)]
102        #[serde(skip_serializing_if = "Option::is_none")]
103        pub animated: Option<bool>,
104    }
105
106    /// Response type for the `get_content_thumbnail` endpoint.
107    #[response(error = crate::Error)]
108    pub struct Response {
109        /// A thumbnail of the requested content.
110        #[ruma_api(raw_body)]
111        pub file: Vec<u8>,
112
113        /// The content type of the thumbnail.
114        #[ruma_api(header = CONTENT_TYPE)]
115        pub content_type: Option<String>,
116
117        /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
118        /// file that was previously uploaded.
119        ///
120        /// See [MDN] for the syntax.
121        ///
122        /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
123        #[ruma_api(header = CONTENT_DISPOSITION)]
124        pub content_disposition: Option<ContentDisposition>,
125
126        /// The value of the `Cross-Origin-Resource-Policy` HTTP header.
127        ///
128        /// See [MDN] for the syntax.
129        ///
130        /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#syntax
131        #[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
132        pub cross_origin_resource_policy: Option<String>,
133    }
134
135    #[allow(deprecated)]
136    impl Request {
137        /// Creates a new `Request` with the given media ID, server name, desired thumbnail width
138        /// and desired thumbnail height.
139        pub fn new(
140            media_id: String,
141            server_name: OwnedServerName,
142            width: UInt,
143            height: UInt,
144        ) -> Self {
145            Self {
146                media_id,
147                server_name,
148                method: None,
149                width,
150                height,
151                allow_remote: true,
152                timeout_ms: ruma_common::media::default_download_timeout(),
153                allow_redirect: false,
154                animated: None,
155            }
156        }
157
158        /// Creates a new `Request` with the given url, desired thumbnail width and
159        /// desired thumbnail height.
160        pub fn from_url(url: &MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
161            let (server_name, media_id) = url.parts()?;
162
163            Ok(Self::new(media_id.to_owned(), server_name.to_owned(), width, height))
164        }
165    }
166
167    impl Response {
168        /// Creates a new `Response` with the given thumbnail.
169        ///
170        /// The Cross-Origin Resource Policy defaults to `cross-origin`.
171        pub fn new(
172            file: Vec<u8>,
173            content_type: String,
174            content_disposition: ContentDisposition,
175        ) -> Self {
176            Self {
177                file,
178                content_type: Some(content_type),
179                content_disposition: Some(content_disposition),
180                cross_origin_resource_policy: Some("cross-origin".to_owned()),
181            }
182        }
183    }
184}