client-api: Add support for the appservice ping mechanism
According to MSC2659
This commit is contained in:
parent
7239be4fcb
commit
3b722c7faa
@ -12,6 +12,7 @@ Improvements:
|
|||||||
- Add support for using an existing session to log in another (MSC3882 / Matrix 1.7)
|
- Add support for using an existing session to log in another (MSC3882 / Matrix 1.7)
|
||||||
- Add support for media download redirects (MSC3860 / Matrix 1.7)
|
- Add support for media download redirects (MSC3860 / Matrix 1.7)
|
||||||
- Stabilize support for asynchronous media uploads (MSC2246 / Matrix 1.7)
|
- Stabilize support for asynchronous media uploads (MSC2246 / Matrix 1.7)
|
||||||
|
- Add support for the appservice ping mechanism (MSC 2659 / Matrix 1.7)
|
||||||
|
|
||||||
# 0.16.2
|
# 0.16.2
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
//! Endpoints part of the application service extension of the client-server API
|
//! Endpoints part of the application service extension of the client-server API
|
||||||
|
|
||||||
|
pub mod request_ping;
|
||||||
pub mod set_room_visibility;
|
pub mod set_room_visibility;
|
||||||
|
64
crates/ruma-client-api/src/appservice/request_ping.rs
Normal file
64
crates/ruma-client-api/src/appservice/request_ping.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//! `POST /_matrix/client/*/appservice/{appserviceId}/ping}`
|
||||||
|
//!
|
||||||
|
//! Ask the homeserver to ping the application service to ensure the connection works.
|
||||||
|
|
||||||
|
pub mod v1 {
|
||||||
|
//! `/v1/` ([spec])
|
||||||
|
//!
|
||||||
|
//! [spec]: https://spec.matrix.org/latest/application-service-api/#post_matrixclientv1appserviceappserviceidping
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use ruma_common::{
|
||||||
|
api::{request, response, Metadata},
|
||||||
|
metadata, OwnedTransactionId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const METADATA: Metadata = metadata! {
|
||||||
|
method: POST,
|
||||||
|
rate_limited: false,
|
||||||
|
authentication: AccessToken,
|
||||||
|
history: {
|
||||||
|
unstable => "/_matrix/client/unstable/fi.mau.msc2659/appservice/:appservice_id/ping",
|
||||||
|
1.7 => "/_matrix/client/v1/appservice/:appservice_id/ping",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Request type for the `request_ping` endpoint.
|
||||||
|
#[request(error = crate::Error)]
|
||||||
|
pub struct Request {
|
||||||
|
/// The appservice ID of the appservice to ping.
|
||||||
|
///
|
||||||
|
/// This must be the same as the appservice whose `as_token` is being used to authenticate
|
||||||
|
/// the request.
|
||||||
|
#[ruma_api(path)]
|
||||||
|
pub appservice_id: String,
|
||||||
|
|
||||||
|
/// Transaction ID that is passed through to the `POST /_matrix/app/v1/ping` call.
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub transaction_id: Option<OwnedTransactionId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Response type for the `request_ping` endpoint.
|
||||||
|
#[response(error = crate::Error)]
|
||||||
|
pub struct Response {
|
||||||
|
/// The duration in milliseconds that the `POST /_matrix/app/v1/ping` request took from the
|
||||||
|
/// homeserver's point of view.
|
||||||
|
#[serde(with = "ruma_common::serde::duration::ms", rename = "duration_ms")]
|
||||||
|
duration: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Request {
|
||||||
|
/// Creates a new `Request` with the given appservice ID.
|
||||||
|
pub fn new(appservice_id: String) -> Self {
|
||||||
|
Self { appservice_id, transaction_id: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Response {
|
||||||
|
/// Creates an `Response` with the given duration.
|
||||||
|
pub fn new(duration: Duration) -> Self {
|
||||||
|
Self { duration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -163,6 +163,24 @@ pub enum ErrorKind {
|
|||||||
#[cfg(feature = "unstable-msc3575")]
|
#[cfg(feature = "unstable-msc3575")]
|
||||||
UnknownPos,
|
UnknownPos,
|
||||||
|
|
||||||
|
/// M_URL_NOT_SET
|
||||||
|
UrlNotSet,
|
||||||
|
|
||||||
|
/// M_BAD_STATUS
|
||||||
|
BadStatus {
|
||||||
|
/// The HTTP status code of the response.
|
||||||
|
status: Option<http::StatusCode>,
|
||||||
|
|
||||||
|
/// The body of the response.
|
||||||
|
body: Option<String>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// M_CONNECTION_FAILED
|
||||||
|
ConnectionFailed,
|
||||||
|
|
||||||
|
/// M_CONNECTION_TIMEOUT
|
||||||
|
ConnectionTimeout,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_Custom { errcode: PrivOwnedStr, extra: Extra },
|
_Custom { errcode: PrivOwnedStr, extra: Extra },
|
||||||
}
|
}
|
||||||
@ -215,6 +233,10 @@ impl AsRef<str> for ErrorKind {
|
|||||||
Self::CannotOverwriteMedia => "M_CANNOT_OVERWRITE_MEDIA",
|
Self::CannotOverwriteMedia => "M_CANNOT_OVERWRITE_MEDIA",
|
||||||
#[cfg(feature = "unstable-msc3575")]
|
#[cfg(feature = "unstable-msc3575")]
|
||||||
Self::UnknownPos => "M_UNKNOWN_POS",
|
Self::UnknownPos => "M_UNKNOWN_POS",
|
||||||
|
Self::UrlNotSet => "M_URL_NOT_SET",
|
||||||
|
Self::BadStatus { .. } => "M_BAD_STATUS",
|
||||||
|
Self::ConnectionFailed => "M_CONNECTION_FAILED",
|
||||||
|
Self::ConnectionTimeout => "M_CONNECTION_TIMEOUT",
|
||||||
Self::_Custom { errcode, .. } => &errcode.0,
|
Self::_Custom { errcode, .. } => &errcode.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ enum Field<'de> {
|
|||||||
RetryAfterMs,
|
RetryAfterMs,
|
||||||
RoomVersion,
|
RoomVersion,
|
||||||
AdminContact,
|
AdminContact,
|
||||||
|
Status,
|
||||||
|
Body,
|
||||||
Other(Cow<'de, str>),
|
Other(Cow<'de, str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +35,8 @@ impl<'de> Field<'de> {
|
|||||||
"retry_after_ms" => Self::RetryAfterMs,
|
"retry_after_ms" => Self::RetryAfterMs,
|
||||||
"room_version" => Self::RoomVersion,
|
"room_version" => Self::RoomVersion,
|
||||||
"admin_contact" => Self::AdminContact,
|
"admin_contact" => Self::AdminContact,
|
||||||
|
"status" => Self::Status,
|
||||||
|
"body" => Self::Body,
|
||||||
_ => Self::Other(s),
|
_ => Self::Other(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +100,8 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
|
|||||||
let mut retry_after_ms = None;
|
let mut retry_after_ms = None;
|
||||||
let mut room_version = None;
|
let mut room_version = None;
|
||||||
let mut admin_contact = None;
|
let mut admin_contact = None;
|
||||||
|
let mut status = None;
|
||||||
|
let mut body = None;
|
||||||
let mut extra = BTreeMap::new();
|
let mut extra = BTreeMap::new();
|
||||||
|
|
||||||
macro_rules! set_field {
|
macro_rules! set_field {
|
||||||
@ -118,6 +124,8 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
|
|||||||
(@variant_containing retry_after_ms) => { ErrCode::LimitExceeded };
|
(@variant_containing retry_after_ms) => { ErrCode::LimitExceeded };
|
||||||
(@variant_containing room_version) => { ErrCode::IncompatibleRoomVersion };
|
(@variant_containing room_version) => { ErrCode::IncompatibleRoomVersion };
|
||||||
(@variant_containing admin_contact) => { ErrCode::ResourceLimitExceeded };
|
(@variant_containing admin_contact) => { ErrCode::ResourceLimitExceeded };
|
||||||
|
(@variant_containing status) => { ErrCode::BadStatus };
|
||||||
|
(@variant_containing body) => { ErrCode::BadStatus };
|
||||||
(@inner $field:ident) => {
|
(@inner $field:ident) => {
|
||||||
{
|
{
|
||||||
if $field.is_some() {
|
if $field.is_some() {
|
||||||
@ -135,6 +143,8 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
|
|||||||
Field::RetryAfterMs => set_field!(retry_after_ms),
|
Field::RetryAfterMs => set_field!(retry_after_ms),
|
||||||
Field::RoomVersion => set_field!(room_version),
|
Field::RoomVersion => set_field!(room_version),
|
||||||
Field::AdminContact => set_field!(admin_contact),
|
Field::AdminContact => set_field!(admin_contact),
|
||||||
|
Field::Status => set_field!(status),
|
||||||
|
Field::Body => set_field!(body),
|
||||||
Field::Other(other) => match extra.entry(other.into_owned()) {
|
Field::Other(other) => match extra.entry(other.into_owned()) {
|
||||||
Entry::Vacant(v) => {
|
Entry::Vacant(v) => {
|
||||||
v.insert(map.next_value()?);
|
v.insert(map.next_value()?);
|
||||||
@ -214,6 +224,20 @@ impl<'de> Visitor<'de> for ErrorKindVisitor {
|
|||||||
ErrCode::CannotOverwriteMedia => ErrorKind::CannotOverwriteMedia,
|
ErrCode::CannotOverwriteMedia => ErrorKind::CannotOverwriteMedia,
|
||||||
#[cfg(feature = "unstable-msc3575")]
|
#[cfg(feature = "unstable-msc3575")]
|
||||||
ErrCode::UnknownPos => ErrorKind::UnknownPos,
|
ErrCode::UnknownPos => ErrorKind::UnknownPos,
|
||||||
|
ErrCode::UrlNotSet => ErrorKind::UrlNotSet,
|
||||||
|
ErrCode::BadStatus => ErrorKind::BadStatus {
|
||||||
|
status: status
|
||||||
|
.map(|s| {
|
||||||
|
from_json_value::<u16>(s)
|
||||||
|
.map_err(de::Error::custom)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(de::Error::custom)
|
||||||
|
})
|
||||||
|
.transpose()?,
|
||||||
|
body: body.map(from_json_value).transpose().map_err(de::Error::custom)?,
|
||||||
|
},
|
||||||
|
ErrCode::ConnectionFailed => ErrorKind::ConnectionFailed,
|
||||||
|
ErrCode::ConnectionTimeout => ErrorKind::ConnectionTimeout,
|
||||||
ErrCode::_Custom(errcode) => ErrorKind::_Custom { errcode, extra },
|
ErrCode::_Custom(errcode) => ErrorKind::_Custom { errcode, extra },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -265,6 +289,10 @@ enum ErrCode {
|
|||||||
CannotOverwriteMedia,
|
CannotOverwriteMedia,
|
||||||
#[cfg(feature = "unstable-msc3575")]
|
#[cfg(feature = "unstable-msc3575")]
|
||||||
UnknownPos,
|
UnknownPos,
|
||||||
|
UrlNotSet,
|
||||||
|
BadStatus,
|
||||||
|
ConnectionFailed,
|
||||||
|
ConnectionTimeout,
|
||||||
_Custom(PrivOwnedStr),
|
_Custom(PrivOwnedStr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user