tokio-xmpp: Ensure id is added only to stanza

The previous commit didn't fix a bug where @id would be added to
elements that didn't need it / where it was invalid (e.g., stream
management).

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-06-04 19:27:46 +02:00
parent bc73af1e5e
commit ae67949e7a
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
4 changed files with 25 additions and 19 deletions

View file

@ -17,7 +17,7 @@ use crate::event::Event;
use crate::happy_eyeballs::{connect_to_host, connect_with_srv}; use crate::happy_eyeballs::{connect_to_host, connect_with_srv};
use crate::starttls::starttls; use crate::starttls::starttls;
use crate::xmpp_codec::Packet; use crate::xmpp_codec::Packet;
use crate::xmpp_stream::{self, make_id}; use crate::xmpp_stream::{self, add_stanza_id};
use crate::{Error, ProtocolError}; use crate::{Error, ProtocolError};
/// XMPP client connection and state /// XMPP client connection and state
@ -161,11 +161,8 @@ impl Client {
/// Send stanza /// Send stanza
pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> { pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> {
let mut el: Element = stanza; self.send(Packet::Stanza(add_stanza_id(stanza, ns::JABBER_CLIENT)))
if el.attr("id").is_none() { .await
el.set_attr("id", make_id());
}
self.send(Packet::Stanza(el)).await
} }
/// End connection by sending `</stream:stream>` /// End connection by sending `</stream:stream>`

View file

@ -17,7 +17,7 @@ use super::bind::bind;
use crate::happy_eyeballs::connect_with_srv; use crate::happy_eyeballs::connect_with_srv;
use crate::starttls::starttls; use crate::starttls::starttls;
use crate::xmpp_codec::Packet; use crate::xmpp_codec::Packet;
use crate::xmpp_stream::{self, make_id}; use crate::xmpp_stream::{self, add_stanza_id};
use crate::{Error, ProtocolError}; use crate::{Error, ProtocolError};
/// A simple XMPP client connection /// A simple XMPP client connection
@ -98,11 +98,11 @@ impl Client {
where where
E: Into<Element>, E: Into<Element>,
{ {
let mut el: Element = stanza.into(); self.send(Packet::Stanza(add_stanza_id(
if el.attr("id").is_none() { stanza.into(),
el.set_attr("id", make_id()); ns::JABBER_CLIENT,
} )))
self.send(Packet::Stanza(el.into())).await .await
} }
/// End connection by sending `</stream:stream>` /// End connection by sending `</stream:stream>`

View file

@ -12,7 +12,7 @@ use super::happy_eyeballs::connect_to_host;
use super::xmpp_codec::Packet; use super::xmpp_codec::Packet;
use super::xmpp_stream; use super::xmpp_stream;
use super::Error; use super::Error;
use crate::xmpp_stream::make_id; use crate::xmpp_stream::add_stanza_id;
mod auth; mod auth;
@ -54,11 +54,7 @@ impl Component {
/// Send stanza /// Send stanza
pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> { pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> {
let mut el: Element = stanza; self.send(add_stanza_id(stanza, ns::COMPONENT_ACCEPT)).await
if el.attr("id").is_none() {
el.set_attr("id", make_id());
}
self.send(el).await
} }
/// End connection /// End connection

View file

@ -14,11 +14,24 @@ use crate::stream_start;
use crate::xmpp_codec::{Packet, XMPPCodec}; use crate::xmpp_codec::{Packet, XMPPCodec};
use crate::Error; use crate::Error;
pub(crate) fn make_id() -> String { fn make_id() -> String {
let id: u64 = thread_rng().gen(); let id: u64 = thread_rng().gen();
format!("{}", id) format!("{}", id)
} }
pub(crate) fn add_stanza_id(mut stanza: Element, default_ns: &str) -> Element {
if stanza.is("iq", default_ns)
|| stanza.is("message", default_ns)
|| stanza.is("presence", default_ns)
{
if stanza.attr("id").is_none() {
stanza.set_attr("id", make_id());
}
}
stanza
}
/// Wraps a binary stream (tokio's `AsyncRead + AsyncWrite`) to decode /// Wraps a binary stream (tokio's `AsyncRead + AsyncWrite`) to decode
/// and encode XMPP packets. /// and encode XMPP packets.
/// ///