fix spec violation and slight alias resolution refactor
This commit is contained in:
@@ -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")]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user