1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-04-22 14:10:16 +03:00

feat(appservice): pinging

This commit is contained in:
Matthias Ahouansou 2025-03-08 11:26:17 +00:00
parent b726ccaab8
commit dc5abd6f3b
No known key found for this signature in database
4 changed files with 85 additions and 0 deletions
src

View file

@ -0,0 +1,80 @@
use std::time::Instant;
use ruma::api::{
appservice::ping::send_ping,
client::{appservice::request_ping, error::ErrorKind},
};
use crate::{api::appservice_server, Error, Result, Ruma};
/// # `POST /_matrix/client/v1/appservice/{appserviceId}/ping`
///
/// Allows an appservice to check whether the server and
/// appservice can connect, and how fast their connection is
pub async fn ping_appservice_route(
body: Ruma<request_ping::v1::Request>,
) -> Result<request_ping::v1::Response> {
let Ruma::<request_ping::v1::Request> {
appservice_info,
body,
..
} = body;
let registration = appservice_info
.expect("Only appservices can call this endpoint")
.registration;
if registration.id != body.appservice_id {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"Appservice ID specified in path does not match the requesting access token",
));
}
if registration.url.is_some() {
let start = Instant::now();
let response = appservice_server::send_request(
registration,
send_ping::v1::Request {
transaction_id: body.transaction_id,
},
)
.await;
let elapsed = start.elapsed();
if let Err(error) = response {
Err(match error {
Error::ReqwestError { source } => {
if source.is_timeout() {
Error::BadRequest(
ErrorKind::ConnectionTimeout,
"Connection to appservice timed-out",
)
} else if let Some(status_code) = source.status() {
Error::BadRequest(
ErrorKind::BadStatus {
status: Some(status_code),
body: Some(source.to_string()),
},
"Ping returned error status",
)
} else {
Error::BadRequest(ErrorKind::ConnectionFailed, "Failed to ping appservice")
}
}
Error::BadServerResponse(_) => Error::BadRequest(
ErrorKind::ConnectionFailed,
"Recieved invalid response from appservice",
),
e => e,
})
} else {
Ok(request_ping::v1::Response::new(elapsed))
}
} else {
Err(Error::BadRequest(
ErrorKind::UrlNotSet,
"Appservice doesn't have a URL configured",
))
}
}

View file

@ -1,5 +1,6 @@
mod account;
mod alias;
mod appservice;
mod backup;
mod capabilities;
mod config;
@ -37,6 +38,7 @@ mod well_known;
pub use account::*;
pub use alias::*;
pub use appservice::*;
pub use backup::*;
pub use capabilities::*;
pub use config::*;

View file

@ -279,6 +279,7 @@ async fn unrecognized_method(
fn routes(config: &Config) -> Router {
let router = Router::new()
.ruma_route(client_server::ping_appservice_route)
.ruma_route(client_server::get_supported_versions_route)
.ruma_route(client_server::get_register_available_route)
.ruma_route(client_server::register_route)

View file

@ -122,6 +122,8 @@ impl Error {
LimitExceeded { .. } => StatusCode::TOO_MANY_REQUESTS,
UserDeactivated => StatusCode::FORBIDDEN,
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
ConnectionTimeout => StatusCode::GATEWAY_TIMEOUT,
BadStatus { .. } | ConnectionFailed => StatusCode::BAD_GATEWAY,
_ => StatusCode::BAD_REQUEST,
},
),