diff --git a/src/projections/xmpp/mod.rs b/src/projections/xmpp/mod.rs index 611a038..78a163e 100644 --- a/src/projections/xmpp/mod.rs +++ b/src/projections/xmpp/mod.rs @@ -1,5 +1,6 @@ mod proto; +use std::borrow::Borrow; use std::collections::HashMap; use std::fs::File; use std::io::BufReader as SyncBufReader; @@ -25,7 +26,7 @@ use crate::prelude::*; use crate::protos::xmpp; use crate::protos::xmpp::bind::{BindResponse, Jid, Name, Resource, Server}; use crate::protos::xmpp::client::{Iq, Presence}; -use crate::protos::xmpp::disco::InfoQuery; +use crate::protos::xmpp::disco::{InfoQuery, Feature, ItemQuery, Item}; use crate::protos::xmpp::roster::RosterQuery; use crate::protos::xmpp::session::Session; use crate::protos::xmpp::stream::*; @@ -320,6 +321,28 @@ async fn socket_final( }; req.serialize(&mut events); } + proto::IqClientBody::DiscoInfo(info) => { + let response = disco_info(iq.to.as_deref(), &info); + let req = Iq { + from: iq.to, + id: iq.id, + to: None, + r#type: xmpp::client::IqType::Result, + body: response, + }; + req.serialize(&mut events); + } + proto::IqClientBody::DiscoItem(item) => { + let response = disco_items(iq.to.as_deref(), &item); + let req = Iq { + from: iq.to, + id: iq.id, + to: None, + r#type: xmpp::client::IqType::Result, + body: response, + }; + req.serialize(&mut events); + } _ => { let req = Iq { from: None, @@ -354,6 +377,59 @@ async fn socket_final( Ok(()) } +fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery { + let feature = match to { + Some("localhost") => { + vec![ + Feature::new("http://jabber.org/protocol/disco#info"), + Feature::new("http://jabber.org/protocol/disco#items"), + Feature::new("iq"), + Feature::new("presence"), + ] + } + Some("rooms.localhost") => { + vec![ + Feature::new("http://jabber.org/protocol/disco#info"), + Feature::new("http://jabber.org/protocol/disco#items"), + Feature::new("http://jabber.org/protocol/muc"), + ] + } + _ => vec![], + }; + InfoQuery { node: None, identity: vec![], feature } +} + +fn disco_items(to: Option<&str>, req: &ItemQuery) -> ItemQuery { + let item = match to { + Some("localhost") => { + vec![ + Item { + jid: Jid { name: None, server: Server("rooms.localhost".to_string()), resource: None }, + name: None, + node: None, + } + ] + } + Some("rooms.localhost") => { + vec![ + Item { + jid: Jid { name: Some(Name("room1".to_string())), server: Server("rooms.localhost".to_string()), resource: None }, + name: None, + node: None, + }, + + Item { + jid: Jid { name: Some(Name("room2".to_string())), server: Server("rooms.localhost".to_string()), resource: None }, + name: None, + node: None, + } + ] + } + _ => vec![], + }; + ItemQuery { item } +} + async fn read_xml_header( xml_reader: &mut NsReader<(impl AsyncBufRead + Unpin)>, reader_buf: &mut Vec, diff --git a/src/protos/xmpp/disco.rs b/src/protos/xmpp/disco.rs index b5858c2..c4cd07f 100644 --- a/src/protos/xmpp/disco.rs +++ b/src/protos/xmpp/disco.rs @@ -8,7 +8,7 @@ use crate::util::xml::*; use super::bind::Jid; pub const XMLNS_INFO: &'static str = "http://jabber.org/protocol/disco#info"; -pub const XMLNS_ITEM: &'static str = "http://jabber.org/protocol/disco#item"; +pub const XMLNS_ITEM: &'static str = "http://jabber.org/protocol/disco#items"; #[derive(PartialEq, Eq, Debug)] pub struct InfoQuery { @@ -203,6 +203,12 @@ pub struct Feature { pub var: String, } +impl Feature { + pub fn new(s: &str) -> Feature { + Feature { var: s.to_string() } + } +} + impl FromXml for Feature { type P = impl Parser>;