fix spec violation and slight alias resolution refactor

This commit is contained in:
dasha_uwu
2025-09-20 06:56:21 +05:00
committed by Jason Volk
parent 9c4d376bec
commit 1c0b4e94ac
12 changed files with 74 additions and 118 deletions

View File

@@ -1,11 +1,9 @@
mod remote;
use std::sync::Arc;
use futures::{Stream, StreamExt};
use ruma::{
OwnedRoomId, OwnedServerName, OwnedUserId, RoomAliasId, RoomId, RoomOrAliasId, UserId,
events::StateEventType,
api::federation::query::get_room_information::v1::Request, events::StateEventType,
};
use tuwunel_core::{
Err, Result, err,
@@ -99,23 +97,21 @@ impl Service {
}
#[inline]
pub async fn resolve(&self, room: &RoomOrAliasId) -> Result<OwnedRoomId> {
self.resolve_with_servers(room, None)
.await
.map(|(room_id, _)| room_id)
pub async fn maybe_resolve(&self, room: &RoomOrAliasId) -> Result<OwnedRoomId> {
match <&RoomId>::try_from(room) {
| Ok(room_id) => Ok(room_id.to_owned()),
| Err(alias) => Ok(self.resolve_alias(alias).await?.0),
}
}
pub async fn resolve_with_servers(
pub async fn maybe_resolve_with_servers(
&self,
room: &RoomOrAliasId,
servers: Option<Vec<OwnedServerName>>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
if room.is_room_id() {
let room_id: &RoomId = room.try_into().expect("valid RoomId");
Ok((room_id.to_owned(), servers.unwrap_or_default()))
} else {
let alias: &RoomAliasId = room.try_into().expect("valid RoomAliasId");
self.resolve_alias(alias, servers).await
match <&RoomId>::try_from(room) {
| Ok(room_id) => Ok((room_id.to_owned(), servers.unwrap_or_default())),
| Err(alias) => self.resolve_alias(alias).await,
}
}
@@ -123,7 +119,6 @@ impl Service {
pub async fn resolve_alias(
&self,
room_alias: &RoomAliasId,
servers: Option<Vec<OwnedServerName>>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
if self
.services
@@ -141,9 +136,24 @@ impl Service {
return Err!(Request(NotFound("Room with alias not found.")));
}
return self
.remote_resolve(room_alias, servers.unwrap_or_default())
.await;
return self.remote_resolve(room_alias).await;
}
async fn remote_resolve(
&self,
room_alias: &RoomAliasId,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
let server = room_alias.server_name();
let request = Request { room_alias: room_alias.to_owned() };
let response = self
.services
.sending
.send_federation_request(server, request)
.await?;
Ok((response.room_id, response.servers))
}
#[tracing::instrument(skip(self), level = "trace")]

View File

@@ -1,73 +0,0 @@
use std::iter::once;
use federation::query::get_room_information::v1::Response;
use ruma::{OwnedRoomId, OwnedServerName, RoomAliasId, ServerName, api::federation};
use tuwunel_core::{Result, debug, debug_error, err, implement};
#[implement(super::Service)]
pub(super) async fn remote_resolve(
&self,
room_alias: &RoomAliasId,
servers: Vec<OwnedServerName>,
) -> Result<(OwnedRoomId, Vec<OwnedServerName>)> {
debug!(?room_alias, servers = ?servers, "resolve");
let servers = once(room_alias.server_name())
.map(ToOwned::to_owned)
.chain(servers.into_iter());
let mut resolved_servers = Vec::new();
let mut resolved_room_id: Option<OwnedRoomId> = None;
for server in servers {
match self.remote_request(room_alias, &server).await {
| Err(e) => debug_error!("Failed to query for {room_alias:?} from {server}: {e}"),
| Ok(Response { room_id, servers }) => {
debug!(
"Server {server} answered with {room_id:?} for {room_alias:?} servers: \
{servers:?}"
);
resolved_room_id.get_or_insert(room_id);
add_server(&mut resolved_servers, server);
if !servers.is_empty() {
add_servers(&mut resolved_servers, servers);
break;
}
},
}
}
resolved_room_id
.map(|room_id| (room_id, resolved_servers))
.ok_or_else(|| {
err!(Request(NotFound("No servers could assist in resolving the room alias")))
})
}
#[implement(super::Service)]
async fn remote_request(
&self,
room_alias: &RoomAliasId,
server: &ServerName,
) -> Result<Response> {
use federation::query::get_room_information::v1::Request;
let request = Request { room_alias: room_alias.to_owned() };
self.services
.sending
.send_federation_request(server, request)
.await
}
fn add_servers(servers: &mut Vec<OwnedServerName>, new: Vec<OwnedServerName>) {
for server in new {
add_server(servers, server);
}
}
fn add_server(servers: &mut Vec<OwnedServerName>, server: OwnedServerName) {
if !servers.contains(&server) {
servers.push(server);
}
}