forked from lavina/lavina
1
0
Fork 0

split xmpp stanzas handling into functions

This commit is contained in:
Nikita Vilunov 2023-03-30 14:49:39 +02:00
parent 123781d145
commit 65471a6c7f
1 changed files with 114 additions and 93 deletions

View File

@ -1,6 +1,5 @@
mod proto; mod proto;
use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::BufReader as SyncBufReader; use std::io::BufReader as SyncBufReader;
@ -26,13 +25,15 @@ use crate::prelude::*;
use crate::protos::xmpp; use crate::protos::xmpp;
use crate::protos::xmpp::bind::{BindResponse, Jid, Name, Resource, Server}; use crate::protos::xmpp::bind::{BindResponse, Jid, Name, Resource, Server};
use crate::protos::xmpp::client::{Iq, Presence}; use crate::protos::xmpp::client::{Iq, Presence};
use crate::protos::xmpp::disco::{InfoQuery, Feature, ItemQuery, Item}; use crate::protos::xmpp::disco::{Feature, InfoQuery, Item, ItemQuery};
use crate::protos::xmpp::roster::RosterQuery; use crate::protos::xmpp::roster::RosterQuery;
use crate::protos::xmpp::session::Session; use crate::protos::xmpp::session::Session;
use crate::protos::xmpp::stream::*; use crate::protos::xmpp::stream::*;
use crate::util::xml::{Continuation, FromXml, Parser, ToXml}; use crate::util::xml::{Continuation, FromXml, Parser, ToXml};
use crate::util::Terminator; use crate::util::Terminator;
use self::proto::{ClientPacket, IqClientBody};
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct ServerConfig { pub struct ServerConfig {
pub listen_on: SocketAddr, pub listen_on: SocketAddr,
@ -285,85 +286,7 @@ async fn socket_final(
Continuation::Final(res) => { Continuation::Final(res) => {
let res = res?; let res = res?;
dbg!(&res); dbg!(&res);
match res { handle_packet(&mut events, res);
proto::ClientPacket::Iq(iq) => match iq.body {
proto::IqClientBody::Bind(b) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: BindResponse(Jid {
name: Some(Name("darova".to_string())),
server: Server("localhost".to_string()),
resource: Some(Resource("kek".to_string())),
}),
};
req.serialize(&mut events);
}
proto::IqClientBody::Session(_) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: Session,
};
req.serialize(&mut events);
}
proto::IqClientBody::Roster(_) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: RosterQuery,
};
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,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Error,
body: (),
};
req.serialize(&mut events);
}
},
proto::ClientPacket::Message(_) => todo!(),
proto::ClientPacket::Presence(p) => {
let response = Presence::<()> {
to: Some("darova@localhost/kek".to_string()),
from: Some("darova@localhost/kek".to_string()),
..Default::default()
};
response.serialize(&mut events);
}
}
for i in &events { for i in &events {
xml_writer.write_event_async(i).await?; xml_writer.write_event_async(i).await?;
} }
@ -374,7 +297,92 @@ async fn socket_final(
Continuation::Continue(p) => parser = p, Continuation::Continue(p) => parser = p,
} }
} }
Ok(()) }
fn handle_packet(output: &mut Vec<Event<'static>>, packet: ClientPacket) {
match packet {
proto::ClientPacket::Iq(iq) => handle_iq(output, iq),
proto::ClientPacket::Message(_) => todo!(),
proto::ClientPacket::Presence(p) => {
let response = Presence::<()> {
to: Some("darova@localhost/kek".to_string()),
from: Some("darova@localhost/kek".to_string()),
..Default::default()
};
response.serialize(output);
}
}
}
fn handle_iq(output: &mut Vec<Event<'static>>, iq: Iq<IqClientBody>) {
match iq.body {
proto::IqClientBody::Bind(b) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: BindResponse(Jid {
name: Some(Name("darova".to_string())),
server: Server("localhost".to_string()),
resource: Some(Resource("kek".to_string())),
}),
};
req.serialize(output);
}
proto::IqClientBody::Session(_) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: Session,
};
req.serialize(output);
}
proto::IqClientBody::Roster(_) => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Result,
body: RosterQuery,
};
req.serialize(output);
}
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(output);
}
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(output);
}
_ => {
let req = Iq {
from: None,
id: iq.id,
to: None,
r#type: xmpp::client::IqType::Error,
body: (),
};
req.serialize(output);
}
}
} }
fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery { fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery {
@ -396,33 +404,46 @@ fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery {
} }
_ => vec![], _ => vec![],
}; };
InfoQuery { node: None, identity: vec![], feature } InfoQuery {
node: None,
identity: vec![],
feature,
}
} }
fn disco_items(to: Option<&str>, req: &ItemQuery) -> ItemQuery { fn disco_items(to: Option<&str>, req: &ItemQuery) -> ItemQuery {
let item = match to { let item = match to {
Some("localhost") => { Some("localhost") => {
vec![ vec![Item {
Item { jid: Jid {
jid: Jid { name: None, server: Server("rooms.localhost".to_string()), resource: None },
name: None, name: None,
node: None, server: Server("rooms.localhost".to_string()),
} resource: None,
] },
name: None,
node: None,
}]
} }
Some("rooms.localhost") => { Some("rooms.localhost") => {
vec![ vec![
Item { Item {
jid: Jid { name: Some(Name("room1".to_string())), server: Server("rooms.localhost".to_string()), resource: None }, jid: Jid {
name: Some(Name("room1".to_string())),
server: Server("rooms.localhost".to_string()),
resource: None,
},
name: None, name: None,
node: None, node: None,
}, },
Item { Item {
jid: Jid { name: Some(Name("room2".to_string())), server: Server("rooms.localhost".to_string()), resource: None }, jid: Jid {
name: Some(Name("room2".to_string())),
server: Server("rooms.localhost".to_string()),
resource: None,
},
name: None, name: None,
node: None, node: None,
} },
] ]
} }
_ => vec![], _ => vec![],