From ea28234d954f96bbca8430ffce3215540adc7c0a Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 4 Jun 2025 14:04:29 +0100 Subject: [PATCH] sdk: Cache the client well-known file and add Client::rtc_foci which uses it. --- Cargo.lock | 24 ++-- Cargo.toml | 7 +- crates/matrix-sdk-base/CHANGELOG.md | 3 + .../src/store/integration_tests.rs | 13 +- crates/matrix-sdk-base/src/store/mod.rs | 2 +- crates/matrix-sdk-base/src/store/traits.rs | 51 ++++++- crates/matrix-sdk/CHANGELOG.md | 3 + .../src/authentication/oauth/tests.rs | 2 +- .../src/client/builder/homeserver_config.rs | 26 +++- crates/matrix-sdk/src/client/builder/mod.rs | 9 +- crates/matrix-sdk/src/client/mod.rs | 127 ++++++++++++++++-- .../src/test_json/api_responses.rs | 8 +- 12 files changed, 226 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa00e5708..4733bb4f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4449,8 +4449,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d910a9b75cbf0e88f74295997c1a41c3ab7a117879a029c72db815192c167a0d" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "assign", "js_int", @@ -4466,8 +4465,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc4ff88a70a3d1e7a2c5b51cca7499cb889b42687608ab664b9a216c49314d" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "as_variant", "assign", @@ -4490,8 +4488,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b75da013b362664c3e161662902e5da3f77e990525681b59c6035bac27e87b4" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "as_variant", "base64", @@ -4523,8 +4520,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.30.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ab3d1b54c32a65194ecc44bc7f7575df50ef4255b139547d7dcc1753dc883d" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "as_variant", "indexmap", @@ -4549,8 +4545,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373bc5a30b84574dfce3e75c33d79d6ba9843bf0eee1bf351f904eef9bea001a" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "http", "js_int", @@ -4564,8 +4559,7 @@ dependencies = [ [[package]] name = "ruma-html" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865afa2321e34fa836ea4c1d77ce0c2bb40f7d13fe18ee3e795091fd8d173a1d" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "as_variant", "html5ever", @@ -4577,8 +4571,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ad674b5e5368c53a2c90fde7dac7e30747004aaf7b1827b72874a25fc06d4d8" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "js_int", "thiserror 2.0.11", @@ -4587,8 +4580,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1182e83ee5cd10121974f163337b16af68a93eedfc7cdbdbd52307ac7e1d743" +source = "git+https://github.com/ruma/ruma?rev=d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a#d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" dependencies = [ "cfg-if", "proc-macro-crate", diff --git a/Cargo.toml b/Cargo.toml index 7d902ec41..3e5e9ee17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ reqwest = { version = "0.12.12", default-features = false } rmp-serde = "1.3.0" # Be careful to use commits from the https://github.com/ruma/ruma/tree/ruma-0.12 # branch until a proper release with breaking changes happens. -ruma = { version = "0.12.3", features = [ +ruma = { git = "https://github.com/ruma/ruma", rev = "d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a", features = [ "client-api-c", "compat-upload-signatures", "compat-user-id", @@ -73,11 +73,12 @@ ruma = { version = "0.12.3", features = [ "unstable-msc3489", "unstable-msc4075", "unstable-msc4140", + "unstable-msc4143", "unstable-msc4171", "unstable-msc4278", "unstable-msc4286", - ] } -ruma-common = "0.15.2" +] } +ruma-common = { git = "https://github.com/ruma/ruma", rev = "d1d53e2b7aaf9190f11a5465b9edf6a19fc5b59a" } sentry = "0.36.0" sentry-tracing = "0.36.0" serde = { version = "1.0.217", features = ["rc"] } diff --git a/crates/matrix-sdk-base/CHANGELOG.md b/crates/matrix-sdk-base/CHANGELOG.md index 070105acf..7c8afc5cd 100644 --- a/crates/matrix-sdk-base/CHANGELOG.md +++ b/crates/matrix-sdk-base/CHANGELOG.md @@ -52,6 +52,9 @@ No notable changes in this release. ([#4897](https://github.com/matrix-org/matrix-rust-sdk/pull/4897)) - [**breaking**] `RoomInfo::prev_state` has been removed due to being useless. ([#5054](https://github.com/matrix-org/matrix-rust-sdk/pull/5054)) +- The cached `ServerCapabilities` has been renamed to `ServerInfo` and additionally contains + the well-known response alongside the existing server versions. Despite the old name, it + does not contain the server capabilities (yet?!). ## [0.10.0] - 2025-02-04 diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index 70cc8f672..ffd88b622 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -7,7 +7,10 @@ use assert_matches2::assert_let; use growable_bloom_filter::GrowableBloomBuilder; use matrix_sdk_test::{event_factory::EventFactory, test_json}; use ruma::{ - api::MatrixVersion, + api::{ + client::discovery::discover_homeserver::{HomeserverInfo, RtcFocusInfo}, + MatrixVersion, + }, event_id, events::{ presence::PresenceEvent, @@ -34,7 +37,7 @@ use serde_json::{json, value::Value as JsonValue}; use super::{ send_queue::SentRequestKey, DependentQueuedRequestKind, DisplayName, DynStateStore, - RoomLoadSettings, ServerInfo, + RoomLoadSettings, ServerInfo, WellKnownResponse, }; use crate::{ deserialized_responses::MemberEvent, @@ -477,6 +480,12 @@ impl StateStoreIntegrationTests for DynStateStore { let server_info = ServerInfo::new( versions.iter().map(|version| version.to_string()).collect(), [("org.matrix.experimental".to_owned(), true)].into(), + Some(WellKnownResponse { + homeserver: HomeserverInfo::new("matrix.example.com".to_owned()), + identity_server: None, + tile_server: None, + rtc_foci: vec![RtcFocusInfo::livekit("livekit.example.com".to_owned())], + }), ); self.set_kv_data( diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index c9350f740..372c85b31 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -82,7 +82,7 @@ pub use self::{ }, traits::{ ComposerDraft, ComposerDraftType, DynStateStore, IntoStateStore, ServerInfo, StateStore, - StateStoreDataKey, StateStoreDataValue, StateStoreExt, + StateStoreDataKey, StateStoreDataValue, StateStoreExt, WellKnownResponse, }, }; diff --git a/crates/matrix-sdk-base/src/store/traits.rs b/crates/matrix-sdk-base/src/store/traits.rs index 98fba71d5..512497277 100644 --- a/crates/matrix-sdk-base/src/store/traits.rs +++ b/crates/matrix-sdk-base/src/store/traits.rs @@ -24,7 +24,16 @@ use async_trait::async_trait; use growable_bloom_filter::GrowableBloom; use matrix_sdk_common::AsyncTraitDeps; use ruma::{ - api::{client::discovery::get_supported_versions, MatrixVersion}, + api::{ + client::discovery::{ + discover_homeserver, + discover_homeserver::{ + HomeserverInfo, IdentityServerInfo, RtcFocusInfo, TileServerInfo, + }, + get_supported_versions, + }, + MatrixVersion, + }, events::{ presence::PresenceEvent, receipt::{Receipt, ReceiptThread, ReceiptType}, @@ -960,6 +969,10 @@ pub struct ServerInfo { /// List of unstable features and their enablement status. pub unstable_features: BTreeMap, + /// Information about the server found in the client well-known file. + #[serde(skip_serializing_if = "Option::is_none")] + pub well_known: Option, + /// Last time we fetched this data from the server, in milliseconds since /// epoch. last_fetch_ts: f64, @@ -970,8 +983,12 @@ impl ServerInfo { pub const STALE_THRESHOLD: f64 = (1000 * 60 * 60 * 24 * 7) as _; // seven days /// Encode server info into this serializable struct. - pub fn new(versions: Vec, unstable_features: BTreeMap) -> Self { - Self { versions, unstable_features, last_fetch_ts: now_timestamp_ms() } + pub fn new( + versions: Vec, + unstable_features: BTreeMap, + well_known: Option, + ) -> Self { + Self { versions, unstable_features, well_known, last_fetch_ts: now_timestamp_ms() } } /// Decode server info from this serializable struct. @@ -998,6 +1015,33 @@ impl ServerInfo { } } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +/// A serialisable representation of discover_homeserver::Response. +pub struct WellKnownResponse { + /// Information about the homeserver to connect to. + pub homeserver: HomeserverInfo, + + /// Information about the identity server to connect to. + pub identity_server: Option, + + /// Information about the tile server to use to display location data. + pub tile_server: Option, + + /// A list of the available MatrixRTC foci, ordered by priority. + pub rtc_foci: Vec, +} + +impl From for WellKnownResponse { + fn from(response: discover_homeserver::Response) -> Self { + Self { + homeserver: response.homeserver, + identity_server: response.identity_server, + tile_server: response.tile_server, + rtc_foci: response.rtc_foci, + } + } +} + /// Get the current timestamp as the number of milliseconds since Unix Epoch. fn now_timestamp_ms() -> f64 { SystemTime::now() @@ -1180,6 +1224,7 @@ mod tests { let mut server_info = ServerInfo { versions: Default::default(), unstable_features: Default::default(), + well_known: Default::default(), last_fetch_ts: now_timestamp_ms() - ServerInfo::STALE_THRESHOLD - 1.0, }; diff --git a/crates/matrix-sdk/CHANGELOG.md b/crates/matrix-sdk/CHANGELOG.md index ace2c4de3..b1012ed87 100644 --- a/crates/matrix-sdk/CHANGELOG.md +++ b/crates/matrix-sdk/CHANGELOG.md @@ -78,6 +78,9 @@ All notable changes to this project will be documented in this file. ([#5047](https://github.com/matrix-org/matrix-rust-sdk/pull/5047)) - `Room::set_unread_flag()` is now a no-op if the unread flag already has the wanted value. ([#5055](https://github.com/matrix-org/matrix-rust-sdk/pull/5055)) +- `ClientServerCapabilities` has been renamed to `ClientServerInfo`. Alongside this, + `Client::reset_server_info` is now `Client::reset_server_info` and `Client::fetch_server_capabilities` + is now `Client::fetch_server_versions`, returning the server versions response directly. ## [0.11.0] - 2025-04-11 diff --git a/crates/matrix-sdk/src/authentication/oauth/tests.rs b/crates/matrix-sdk/src/authentication/oauth/tests.rs index d57443ed5..74c52b5f5 100644 --- a/crates/matrix-sdk/src/authentication/oauth/tests.rs +++ b/crates/matrix-sdk/src/authentication/oauth/tests.rs @@ -516,7 +516,7 @@ async fn test_insecure_clients() -> anyhow::Result<()> { let server = MatrixMockServer::new().await; let server_url = server.server().uri(); - server.mock_well_known().ok().expect(1).named("well_known").mount().await; + server.mock_well_known().ok().expect(1..).named("well_known").mount().await; server.mock_versions().ok().expect(1..).named("versions").mount().await; let oauth_server = server.oauth(); diff --git a/crates/matrix-sdk/src/client/builder/homeserver_config.rs b/crates/matrix-sdk/src/client/builder/homeserver_config.rs index ce7ddc740..d7a829e91 100644 --- a/crates/matrix-sdk/src/client/builder/homeserver_config.rs +++ b/crates/matrix-sdk/src/client/builder/homeserver_config.rs @@ -53,6 +53,7 @@ pub(super) struct HomeserverDiscoveryResult { pub server: Option, pub homeserver: Url, pub supported_versions: Option, + pub well_known: Option, } impl HomeserverConfig { @@ -68,6 +69,7 @@ impl HomeserverConfig { server: None, // We can't know the `server` if we only have a `homeserver`. homeserver, supported_versions: None, + well_known: None, } } @@ -79,18 +81,19 @@ impl HomeserverConfig { server: Some(server), homeserver: Url::parse(&well_known.homeserver.base_url)?, supported_versions: None, + well_known: Some(well_known), } } Self::ServerNameOrHomeserverUrl(server_name_or_url) => { - let (server, homeserver, supported_versions) = + let (server, homeserver, supported_versions, well_known) = discover_homeserver_from_server_name_or_url( server_name_or_url.to_owned(), http_client, ) .await?; - HomeserverDiscoveryResult { server, homeserver, supported_versions } + HomeserverDiscoveryResult { server, homeserver, supported_versions, well_known } } }) } @@ -102,7 +105,15 @@ impl HomeserverConfig { async fn discover_homeserver_from_server_name_or_url( mut server_name_or_url: String, http_client: &HttpClient, -) -> Result<(Option, Url, Option), ClientBuildError> { +) -> Result< + ( + Option, + Url, + Option, + Option, + ), + ClientBuildError, +> { let mut discovery_error: Option = None; // Attempt discovery as a server name first. @@ -117,7 +128,12 @@ async fn discover_homeserver_from_server_name_or_url( match discover_homeserver(server_name, &protocol, http_client).await { Ok((server, well_known)) => { - return Ok((Some(server), Url::parse(&well_known.homeserver.base_url)?, None)); + return Ok(( + Some(server), + Url::parse(&well_known.homeserver.base_url)?, + None, + Some(well_known), + )); } Err(e) => { debug!(error = %e, "Well-known discovery failed."); @@ -138,7 +154,7 @@ async fn discover_homeserver_from_server_name_or_url( // Make sure the URL is definitely for a homeserver. match get_supported_versions(&homeserver_url, http_client).await { Ok(response) => { - return Ok((None, homeserver_url, Some(response))); + return Ok((None, homeserver_url, Some(response), None)); } Err(e) => { debug!(error = %e, "Checking supported versions failed."); diff --git a/crates/matrix-sdk/src/client/builder/mod.rs b/crates/matrix-sdk/src/client/builder/mod.rs index 048649b2a..1ed3cf70e 100644 --- a/crates/matrix-sdk/src/client/builder/mod.rs +++ b/crates/matrix-sdk/src/client/builder/mod.rs @@ -525,7 +525,7 @@ impl ClientBuilder { let http_client = HttpClient::new(inner_http_client.clone(), self.request_config); #[allow(unused_variables)] - let HomeserverDiscoveryResult { server, homeserver, supported_versions } = + let HomeserverDiscoveryResult { server, homeserver, supported_versions, well_known } = homeserver_cfg.discover(&http_client).await?; let sliding_sync_version = { @@ -560,8 +560,11 @@ impl ClientBuilder { // Enable the send queue by default. let send_queue = Arc::new(SendQueueData::new(true)); - let server_info = - ClientServerInfo { server_versions: self.server_versions, unstable_features: None }; + let server_info = ClientServerInfo { + server_versions: self.server_versions, + unstable_features: None, + well_known: well_known.map(Into::into), + }; let event_cache = OnceCell::new(); let inner = ClientInner::new( diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 3b0c34505..ff52f5e5b 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -31,7 +31,7 @@ use futures_util::StreamExt; use matrix_sdk_base::crypto::store::LockableCryptoStore; use matrix_sdk_base::{ event_cache::store::EventCacheStoreLock, - store::{DynStateStore, RoomLoadSettings, ServerInfo}, + store::{DynStateStore, RoomLoadSettings, ServerInfo, WellKnownResponse}, sync::{Notification, RoomUpdates}, BaseClient, RoomInfoNotableUpdate, RoomState, RoomStateFilter, SendOutsideWasm, SessionMeta, StateStoreDataKey, StateStoreDataValue, SyncOutsideWasm, @@ -47,6 +47,8 @@ use ruma::{ device::{delete_devices, get_devices, update_device}, directory::{get_public_rooms, get_public_rooms_filtered}, discovery::{ + discover_homeserver, + discover_homeserver::RtcFocusInfo, get_capabilities::{self, Capabilities}, get_supported_versions, }, @@ -1740,8 +1742,8 @@ impl Client { pub async fn fetch_server_versions( &self, request_config: Option, - ) -> HttpResult<(Vec, BTreeMap)> { - let resp = self + ) -> HttpResult { + let server_versions = self .inner .http_client .send( @@ -1754,7 +1756,42 @@ impl Client { ) .await?; - Ok((resp.versions, resp.unstable_features)) + Ok(server_versions) + } + + /// Fetches client well_known from network; no caching. + pub async fn fetch_client_well_known(&self) -> Option { + let server_url_string = self + .server() + .unwrap_or( + // Sometimes people configure their well-known directly on the homeserver so use + // this as a fallback when the server name is unknown. + &self.homeserver(), + ) + .to_string(); + + let well_known = self + .inner + .http_client + .send( + discover_homeserver::Request::new(), + Some(RequestConfig::short_retry()), + server_url_string, + None, + &[MatrixVersion::V1_0], + Default::default(), + ) + .await; + + match well_known { + Ok(well_known) => Some(well_known), + Err(http_error) => { + // It is perfectly valid to not have a well-known file. + // Maybe we should check for a specific error code to be sure? + warn!("Failed to fetch client well-known: {http_error}"); + None + } + } } /// Load server info from storage, or fetch them from network and cache @@ -1777,8 +1814,13 @@ impl Client { } } - let (versions, unstable_features) = self.fetch_server_versions(None).await?; - let server_info = ServerInfo::new(versions.clone(), unstable_features.clone()); + let server_versions = self.fetch_server_versions(None).await?; + let well_known = self.fetch_client_well_known().await; + let server_info = ServerInfo::new( + server_versions.versions.clone(), + server_versions.unstable_features.clone(), + well_known.map(Into::into), + ); // Attempt to cache the result in storage. { @@ -1821,6 +1863,7 @@ impl Client { guard.server_versions = Some(versions.into()); guard.unstable_features = Some(server_info.unstable_features); + guard.well_known = server_info.well_known; // SAFETY: both fields were set above, so the function will always return some. Ok(f(&guard).unwrap()) @@ -1871,6 +1914,36 @@ impl Client { .await } + /// Get information about the homeserver's advertised RTC foci by fetching + /// the well-known file from the server or the cache. + /// + /// # Examples + /// ```no_run + /// # use matrix_sdk::{Client, config::SyncSettings, ruma::api::client::discovery::discover_homeserver::RtcFocusInfo}; + /// # use url::Url; + /// # async { + /// # let homeserver = Url::parse("http://localhost:8080")?; + /// # let mut client = Client::new(homeserver).await?; + /// let rtc_foci = client.rtc_foci().await?; + /// let default_livekit_focus_info = rtc_foci.iter().find_map(|focus| match focus { + /// RtcFocusInfo::LiveKit(info) => Some(info), + /// _ => None, + /// }); + /// if let Some(info) = default_livekit_focus_info { + /// println!("Default LiveKit service URL: {}", info.service_url); + /// } + /// # anyhow::Ok(()) }; + /// ``` + pub async fn rtc_foci(&self) -> HttpResult> { + self.get_or_load_and_cache_server_info(|server_info| { + server_info + .well_known + .as_ref() + .and_then(|well_known| well_known.rtc_foci.clone().into()) + }) + .await + } + /// Empty the server version and unstable features cache. /// /// Since the SDK caches server info (versions, unstable features, @@ -2625,6 +2698,8 @@ struct ClientServerInfo { /// The unstable features and their on/off state on the server. unstable_features: Option>, + + well_known: Option, } // The http mocking library is not supported for wasm32 @@ -2649,7 +2724,13 @@ pub(crate) mod tests { wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); use ruma::{ - api::{client::room::create_room::v3::Request as CreateRoomRequest, MatrixVersion}, + api::{ + client::{ + discovery::discover_homeserver::RtcFocusInfo, + room::create_room::v3::Request as CreateRoomRequest, + }, + MatrixVersion, + }, assign, events::{ ignored_user_list::IgnoredUserListEventContent, @@ -3046,16 +3127,17 @@ pub(crate) mod tests { let server_url = server.uri(); let domain = server_url.strip_prefix("http://").unwrap(); let server_name = <&ServerName>::try_from(domain).unwrap(); + let rtc_foci = vec![RtcFocusInfo::livekit("https://livekit.example.com".to_owned())]; - Mock::given(method("GET")) + let well_known_mock = Mock::given(method("GET")) .and(path("/.well-known/matrix/client")) .respond_with(ResponseTemplate::new(200).set_body_raw( test_json::WELL_KNOWN.to_string().replace("HOMESERVER_URL", server_url.as_ref()), "application/json", )) .named("well known mock") - .expect(2) - .mount(&server) + .expect(2) // One for ClientBuilder discovery, one for the ServerInfo cache. + .mount_as_scoped(&server) .await; let versions_mock = Mock::given(method("GET")) @@ -3079,13 +3161,14 @@ pub(crate) mod tests { assert_eq!(client.server_versions().await.unwrap().len(), 1); - // This second call hits the in-memory cache. + // These subsequent calls hit the in-memory cache. assert!(client.server_versions().await.unwrap().contains(&MatrixVersion::V1_0)); + assert_eq!(client.rtc_foci().await.unwrap(), rtc_foci); drop(client); let client = Client::builder() - .insecure_server_name_no_tls(server_name) + .homeserver_url(server.uri()) // Configure this client directly so as to not hit the discovery endpoint. .store_config( StoreConfig::new("cross-process-store-locks-holder-name".to_owned()) .state_store(memory_store.clone()), @@ -3094,18 +3177,33 @@ pub(crate) mod tests { .await .unwrap(); - // This third call hits the on-disk cache. + // This call to the new client hits the on-disk cache. assert_eq!( client.unstable_features().await.unwrap().get("org.matrix.e2e_cross_signing"), Some(&true) ); + // Then this call hits the in-memory cache. + assert_eq!(client.rtc_foci().await.unwrap(), rtc_foci); + drop(versions_mock); + drop(well_known_mock); server.verify().await; - // Now, reset the cache, and observe the endpoint being called again once. + // Now, reset the cache, and observe the endpoints being called again once. client.reset_server_info().await.unwrap(); + Mock::given(method("GET")) + .and(path("/.well-known/matrix/client")) + .respond_with(ResponseTemplate::new(200).set_body_raw( + test_json::WELL_KNOWN.to_string().replace("HOMESERVER_URL", server_url.as_ref()), + "application/json", + )) + .named("second well known mock") + .expect(1) + .mount(&server) + .await; + Mock::given(method("GET")) .and(path("/_matrix/client/versions")) .respond_with(ResponseTemplate::new(200).set_body_json(&*test_json::VERSIONS)) @@ -3118,6 +3216,7 @@ pub(crate) mod tests { assert_eq!(client.server_versions().await.unwrap().len(), 1); // Hits in-memory cache again. assert!(client.server_versions().await.unwrap().contains(&MatrixVersion::V1_0)); + assert_eq!(client.rtc_foci().await.unwrap(), rtc_foci); } #[async_test] diff --git a/testing/matrix-sdk-test/src/test_json/api_responses.rs b/testing/matrix-sdk-test/src/test_json/api_responses.rs index 166ea25a2..7aa35b616 100644 --- a/testing/matrix-sdk-test/src/test_json/api_responses.rs +++ b/testing/matrix-sdk-test/src/test_json/api_responses.rs @@ -359,7 +359,13 @@ pub static WELL_KNOWN: Lazy = Lazy::new(|| { json!({ "m.homeserver": { "base_url": "HOMESERVER_URL" - } + }, + "m.rtc_foci": [ + { + "type": "livekit", + "livekit_service_url": "https://livekit.example.com", + } + ] }) });