Skip to main content

tuwunel_service/resolver/
well_known.rs

1use tuwunel_core::{Result, debug, debug_error, debug_info, debug_warn, implement, trace};
2
3use super::DestString;
4
5#[implement(super::Service)]
6#[tracing::instrument(
7	name = "well-known",
8	level = "debug",
9	ret(level = "debug"),
10	skip(self)
11)]
12pub(super) async fn request_well_known(&self, dest: &str) -> Result<Option<DestString>> {
13	trace!("Requesting well known for {dest}");
14	let response = self
15		.services
16		.client
17		.well_known
18		.get(format!("https://{dest}/.well-known/matrix/server"))
19		.send()
20		.await;
21
22	trace!("response: {response:?}");
23	if let Err(e) = &response {
24		debug!("error: {e:?}");
25		return Ok(None);
26	}
27
28	let response = response?;
29	if !response.status().is_success() {
30		debug!("response not 2XX");
31		return Ok(None);
32	}
33
34	let text = response.text().await?;
35	trace!("response text: {text:?}");
36	if text.len() >= 12288 {
37		debug_warn!("response contains junk");
38		return Ok(None);
39	}
40
41	let body: serde_json::Value = serde_json::from_str(&text).unwrap_or_default();
42
43	let m_server = body
44		.get("m.server")
45		.unwrap_or(&serde_json::Value::Null)
46		.as_str()
47		.unwrap_or_default();
48
49	if ruma::identifiers_validation::server_name::validate(m_server).is_err() {
50		debug_error!("response content missing or invalid");
51		return Ok(None);
52	}
53
54	debug_info!("{dest:?} found at {m_server:?}");
55	Ok(Some(m_server.into()))
56}