sdk: Cache the client well-known file and add Client::rtc_foci which uses it.
This commit is contained in:
Generated
+8
-16
@@ -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",
|
||||
|
||||
+4
-3
@@ -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"] }
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -82,7 +82,7 @@ pub use self::{
|
||||
},
|
||||
traits::{
|
||||
ComposerDraft, ComposerDraftType, DynStateStore, IntoStateStore, ServerInfo, StateStore,
|
||||
StateStoreDataKey, StateStoreDataValue, StateStoreExt,
|
||||
StateStoreDataKey, StateStoreDataValue, StateStoreExt, WellKnownResponse,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -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<String, bool>,
|
||||
|
||||
/// Information about the server found in the client well-known file.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub well_known: Option<WellKnownResponse>,
|
||||
|
||||
/// 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<String>, unstable_features: BTreeMap<String, bool>) -> Self {
|
||||
Self { versions, unstable_features, last_fetch_ts: now_timestamp_ms() }
|
||||
pub fn new(
|
||||
versions: Vec<String>,
|
||||
unstable_features: BTreeMap<String, bool>,
|
||||
well_known: Option<WellKnownResponse>,
|
||||
) -> 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<IdentityServerInfo>,
|
||||
|
||||
/// Information about the tile server to use to display location data.
|
||||
pub tile_server: Option<TileServerInfo>,
|
||||
|
||||
/// A list of the available MatrixRTC foci, ordered by priority.
|
||||
pub rtc_foci: Vec<RtcFocusInfo>,
|
||||
}
|
||||
|
||||
impl From<discover_homeserver::Response> 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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -53,6 +53,7 @@ pub(super) struct HomeserverDiscoveryResult {
|
||||
pub server: Option<Url>,
|
||||
pub homeserver: Url,
|
||||
pub supported_versions: Option<get_supported_versions::Response>,
|
||||
pub well_known: Option<discover_homeserver::Response>,
|
||||
}
|
||||
|
||||
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>, Url, Option<get_supported_versions::Response>), ClientBuildError> {
|
||||
) -> Result<
|
||||
(
|
||||
Option<Url>,
|
||||
Url,
|
||||
Option<get_supported_versions::Response>,
|
||||
Option<discover_homeserver::Response>,
|
||||
),
|
||||
ClientBuildError,
|
||||
> {
|
||||
let mut discovery_error: Option<ClientBuildError> = 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.");
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<RequestConfig>,
|
||||
) -> HttpResult<(Vec<String>, BTreeMap<String, bool>)> {
|
||||
let resp = self
|
||||
) -> HttpResult<get_supported_versions::Response> {
|
||||
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<discover_homeserver::Response> {
|
||||
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<Vec<RtcFocusInfo>> {
|
||||
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<BTreeMap<String, bool>>,
|
||||
|
||||
well_known: Option<WellKnownResponse>,
|
||||
}
|
||||
|
||||
// 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]
|
||||
|
||||
@@ -359,7 +359,13 @@ pub static WELL_KNOWN: Lazy<JsonValue> = Lazy::new(|| {
|
||||
json!({
|
||||
"m.homeserver": {
|
||||
"base_url": "HOMESERVER_URL"
|
||||
}
|
||||
},
|
||||
"m.rtc_foci": [
|
||||
{
|
||||
"type": "livekit",
|
||||
"livekit_service_url": "https://livekit.example.com",
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user