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}