Skip to main content

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