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