From ab61e975bf1912e3c012d90f882e5571e7dab963 Mon Sep 17 00:00:00 2001 From: Nikita Vilunov Date: Sat, 6 Apr 2024 15:28:46 +0000 Subject: [PATCH] xmpp: send correct errors on unknown iqs --- crates/projection-xmpp/src/iq.rs | 6 +++-- crates/proto-xmpp/src/client.rs | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/projection-xmpp/src/iq.rs b/crates/projection-xmpp/src/iq.rs index 3ad0ae5..9c50ecc 100644 --- a/crates/projection-xmpp/src/iq.rs +++ b/crates/projection-xmpp/src/iq.rs @@ -4,7 +4,7 @@ use quick_xml::events::Event; use lavina_core::room::RoomRegistry; use proto_xmpp::bind::{BindResponse, Jid, Name, Resource, Server}; -use proto_xmpp::client::{Iq, IqType}; +use proto_xmpp::client::{Iq, IqError, IqErrorType, IqType}; use proto_xmpp::disco::{Feature, Identity, InfoQuery, Item, ItemQuery}; use proto_xmpp::roster::RosterQuery; use proto_xmpp::session::Session; @@ -79,7 +79,9 @@ impl<'a> XmppConnection<'a> { id: iq.id, to: None, r#type: IqType::Error, - body: (), + body: IqError { + r#type: IqErrorType::Cancel, + }, }; req.serialize(output); } diff --git a/crates/proto-xmpp/src/client.rs b/crates/proto-xmpp/src/client.rs index 8276d7c..4943283 100644 --- a/crates/proto-xmpp/src/client.rs +++ b/crates/proto-xmpp/src/client.rs @@ -255,6 +255,44 @@ impl MessageType { } } +/// Error response to an IQ request. +/// +/// https://xmpp.org/rfcs/rfc6120.html#stanzas-error +pub struct IqError { + pub r#type: IqErrorType, +} + +pub enum IqErrorType { + /// Retry after providing credentials + Auth, + /// Do not retry (the error cannot be remedied) + Cancel, + /// Proceed (the condition was only a warning) + Continue, + /// Retry after changing the data sent + Modify, + /// Retry after waiting (the error is temporary) + Wait, +} +impl IqErrorType { + pub fn as_str(&self) -> &'static str { + match self { + IqErrorType::Auth => "auth", + IqErrorType::Cancel => "cancel", + IqErrorType::Continue => "continue", + IqErrorType::Modify => "modify", + IqErrorType::Wait => "wait", + } + } +} + +impl ToXml for IqError { + fn serialize(&self, events: &mut Vec>) { + let bytes = BytesStart::new(format!(r#"error xmlns="{}" type="{}""#, XMLNS, self.r#type.as_str())); + events.push(Event::Empty(bytes)); + } +} + #[derive(PartialEq, Eq, Debug)] pub struct Iq { pub from: Option,