Skip to content

Commit 422f925

Browse files
committed
feat: Allow authorization headers to be skipped with the RequestConfig
1 parent ee82861 commit 422f925

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

crates/matrix-sdk/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- Add a new `RequestConfig::skip_auth()` option. This is useful to ensure that
12+
certain request won't ever include an authorization header.
13+
([#5822](https://github.com/matrix-org/matrix-rust-sdk/pull/5822))
1114
- Add support for extended profile fields with `Account::fetch_profile_field_of()`,
1215
`Account::fetch_profile_field_of_static()`, `Account::set_profile_field()` and
1316
`Account::delete_profile_field()`.

crates/matrix-sdk/src/client/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,10 @@ impl Client {
19241924
{
19251925
let homeserver = self.homeserver().to_string();
19261926
let access_token = self.access_token();
1927-
let path_builder_input = Request::PathBuilder::get_path_builder_input(self).await?;
1927+
let skip_auth = config.map(|c| c.skip_auth).unwrap_or(self.request_config().skip_auth);
1928+
1929+
let path_builder_input =
1930+
Request::PathBuilder::get_path_builder_input(self, skip_auth).await?;
19281931

19291932
self.inner
19301933
.http_client
@@ -2039,6 +2042,16 @@ impl Client {
20392042
Ok(server_info)
20402043
}
20412044

2045+
pub(crate) async fn get_cached_versions(&self) -> Option<SupportedVersions> {
2046+
let server_info = &self.inner.caches.server_info;
2047+
2048+
if let CachedValue::Cached(val) = &server_info.read().await.supported_versions {
2049+
Some(val.clone())
2050+
} else {
2051+
None
2052+
}
2053+
}
2054+
20422055
async fn get_or_load_and_cache_server_info<
20432056
Value,
20442057
MapFunction: Fn(&ClientServerInfo) -> CachedValue<Value>,

crates/matrix-sdk/src/config/request.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct RequestConfig {
4848
pub(crate) max_retry_time: Option<Duration>,
4949
pub(crate) max_concurrent_requests: Option<NonZeroUsize>,
5050
pub(crate) force_auth: bool,
51+
pub(crate) skip_auth: bool,
5152
}
5253

5354
#[cfg(not(tarpaulin_include))]
@@ -60,6 +61,7 @@ impl Debug for RequestConfig {
6061
max_retry_time: retry_timeout,
6162
force_auth,
6263
max_concurrent_requests,
64+
skip_auth: skip_optional_auth,
6365
} = self;
6466

6567
let mut res = fmt.debug_struct("RequestConfig");
@@ -73,6 +75,10 @@ impl Debug for RequestConfig {
7375
res.field("force_auth", &true);
7476
}
7577

78+
if *skip_optional_auth {
79+
res.field("skip_optional_auth", &true);
80+
}
81+
7682
res.finish()
7783
}
7884
}
@@ -86,6 +92,7 @@ impl Default for RequestConfig {
8692
max_retry_time: Default::default(),
8793
max_concurrent_requests: Default::default(),
8894
force_auth: false,
95+
skip_auth: false,
8996
}
9097
}
9198
}
@@ -168,6 +175,22 @@ impl RequestConfig {
168175
self.force_auth = true;
169176
self
170177
}
178+
179+
/// Skip sending authorization headers even if the endpoint requires it.
180+
///
181+
/// Default is to send authorization headers if the endpoint accepts or
182+
/// requires it.
183+
///
184+
/// This is useful for endpoints that may optionally accept authorization
185+
/// but don't require it.
186+
///
187+
/// Note: [`RequestConfig::force_auth`] takes precedence. If force auth is
188+
/// set, this value will be ignored.
189+
#[must_use]
190+
pub fn skip_auth(mut self) -> Self {
191+
self.skip_auth = true;
192+
self
193+
}
171194
}
172195

173196
#[cfg(test)]

crates/matrix-sdk/src/http_client/mod.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use eyeball::SharedObservable;
3030
use http::Method;
3131
use matrix_sdk_base::SendOutsideWasm;
3232
use ruma::api::{
33-
OutgoingRequest,
33+
OutgoingRequest, SupportedVersions,
3434
auth_scheme::{AuthScheme, SendAccessToken},
3535
error::{FromHttpResponseError, IntoHttpError},
3636
path_builder,
@@ -114,13 +114,11 @@ impl HttpClient {
114114
trace!(request_type = type_name::<R>(), "Serializing request");
115115

116116
let send_access_token = match access_token {
117-
Some(access_token) => {
118-
if config.force_auth {
119-
SendAccessToken::Always(access_token)
120-
} else {
121-
SendAccessToken::IfRequired(access_token)
122-
}
123-
}
117+
Some(access_token) => match (config.force_auth, config.skip_auth) {
118+
(true, true) | (true, false) => SendAccessToken::Always(access_token),
119+
(false, true) => SendAccessToken::None,
120+
(false, false) => SendAccessToken::IfRequired(access_token),
121+
},
124122
None => SendAccessToken::None,
125123
};
126124

@@ -256,19 +254,38 @@ async fn response_to_http_response(
256254
pub trait SupportedPathBuilder: path_builder::PathBuilder {
257255
fn get_path_builder_input(
258256
client: &crate::Client,
257+
skip_auth: bool,
259258
) -> impl Future<Output = HttpResult<Self::Input<'static>>> + SendOutsideWasm;
260259
}
261260

262261
impl SupportedPathBuilder for path_builder::VersionHistory {
263262
async fn get_path_builder_input(
264263
client: &crate::Client,
265-
) -> HttpResult<Cow<'static, ruma::api::SupportedVersions>> {
266-
client.supported_versions().await.map(Cow::Owned)
264+
skip_auth: bool,
265+
) -> HttpResult<Cow<'static, SupportedVersions>> {
266+
if skip_auth {
267+
let cached_versions = client.get_cached_versions().await;
268+
269+
let versions = if let Some(versions) = cached_versions {
270+
versions
271+
} else {
272+
// If we're skipping auth we might not get all the supported features, so just
273+
// fetch the versions and don't cache them.
274+
let request_config = RequestConfig::default().retry_limit(5).skip_auth();
275+
let response = client.fetch_server_versions(Some(request_config)).await?;
276+
277+
response.as_supported_versions()
278+
};
279+
280+
Ok(Cow::Owned(versions))
281+
} else {
282+
client.supported_versions().await.map(Cow::Owned)
283+
}
267284
}
268285
}
269286

270287
impl SupportedPathBuilder for path_builder::SinglePath {
271-
async fn get_path_builder_input(_client: &crate::Client) -> HttpResult<()> {
288+
async fn get_path_builder_input(_client: &crate::Client, _skip_auth: bool) -> HttpResult<()> {
272289
Ok(())
273290
}
274291
}

0 commit comments

Comments
 (0)