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