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}