refactor jabber client
This commit is contained in:
		
							parent
							
								
									bcacf42dec
								
							
						
					
					
						commit
						abc3ffa736
					
				| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
[package]
 | 
			
		||||
name = "lâmpada"
 | 
			
		||||
name = "lampada"
 | 
			
		||||
authors = ["cel <cel@blos.sm>"]
 | 
			
		||||
version = "0.0.1"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,6 @@ edition = "2021"
 | 
			
		|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
quick-xml = { version = "0.29.0", features = ["async-tokio"] }
 | 
			
		||||
tokio = { version = "1.28", features = ["full"] }
 | 
			
		||||
trust-dns-resolver = "0.22.0"
 | 
			
		||||
xml-rs = "0.8.14"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										106
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										106
									
								
								src/lib.rs
								
								
								
								
							| 
						 | 
				
			
			@ -5,36 +5,37 @@ use std::{
 | 
			
		|||
    str::FromStr,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use tokio::net::TcpStream;
 | 
			
		||||
use jid::JID;
 | 
			
		||||
use quick_xml::{Reader, Writer};
 | 
			
		||||
use tokio::net::{
 | 
			
		||||
    tcp::{OwnedReadHalf, OwnedWriteHalf},
 | 
			
		||||
    TcpStream,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
mod jid;
 | 
			
		||||
pub mod jid;
 | 
			
		||||
 | 
			
		||||
pub struct Jabber {
 | 
			
		||||
    connection: Option<TcpStream>,
 | 
			
		||||
    login: jid::JID,
 | 
			
		||||
pub struct JabberData {
 | 
			
		||||
    jid: jid::JID,
 | 
			
		||||
    password: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Jabber {
 | 
			
		||||
    fn new(login: jid::JID, password: String) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            connection: None,
 | 
			
		||||
            login,
 | 
			
		||||
            password,
 | 
			
		||||
        }
 | 
			
		||||
impl JabberData {
 | 
			
		||||
    pub fn new(jid: JID, password: String) -> Self {
 | 
			
		||||
        Self { jid, password }
 | 
			
		||||
    }
 | 
			
		||||
    async fn resolve_client(&self) -> Vec<SocketAddr> {
 | 
			
		||||
 | 
			
		||||
    async fn get_sockets(&self) -> Vec<SocketAddr> {
 | 
			
		||||
        let mut socket_addrs = Vec::new();
 | 
			
		||||
 | 
			
		||||
        // if it's a socket/ip then just return that
 | 
			
		||||
 | 
			
		||||
        // socket
 | 
			
		||||
        if let Ok(socket_addr) = SocketAddr::from_str(&self.login.domainpart) {
 | 
			
		||||
        if let Ok(socket_addr) = SocketAddr::from_str(&self.jid.domainpart) {
 | 
			
		||||
            socket_addrs.push(socket_addr);
 | 
			
		||||
            return socket_addrs;
 | 
			
		||||
        }
 | 
			
		||||
        // ip
 | 
			
		||||
        if let Ok(ip) = IpAddr::from_str(&self.login.domainpart) {
 | 
			
		||||
        if let Ok(ip) = IpAddr::from_str(&self.jid.domainpart) {
 | 
			
		||||
            socket_addrs.push(SocketAddr::new(ip, 5222));
 | 
			
		||||
            socket_addrs.push(SocketAddr::new(ip, 5223));
 | 
			
		||||
            return socket_addrs;
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +46,7 @@ impl Jabber {
 | 
			
		|||
        // otherwise resolve
 | 
			
		||||
        if let Ok(resolver) = trust_dns_resolver::AsyncResolver::tokio_from_system_conf() {
 | 
			
		||||
            if let Ok(lookup) = resolver
 | 
			
		||||
                .srv_lookup(format!("_xmpp-client._tcp.{}", self.login.domainpart))
 | 
			
		||||
                .srv_lookup(format!("_xmpp-client._tcp.{}", self.jid.domainpart))
 | 
			
		||||
                .await
 | 
			
		||||
            {
 | 
			
		||||
                for srv in lookup {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +61,7 @@ impl Jabber {
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if let Ok(lookup) = resolver
 | 
			
		||||
                .srv_lookup(format!("_xmpps-client._tcp.{}", self.login.domainpart))
 | 
			
		||||
                .srv_lookup(format!("_xmpps-client._tcp.{}", self.jid.domainpart))
 | 
			
		||||
                .await
 | 
			
		||||
            {
 | 
			
		||||
                for srv in lookup {
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +77,7 @@ impl Jabber {
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            // in case cannot connect through SRV records
 | 
			
		||||
            resolver.lookup_ip(&self.login.domainpart).await.map(|ips| {
 | 
			
		||||
            resolver.lookup_ip(&self.jid.domainpart).await.map(|ips| {
 | 
			
		||||
                for ip in ips {
 | 
			
		||||
                    socket_addrs.push(SocketAddr::new(ip, 5222));
 | 
			
		||||
                    socket_addrs.push(SocketAddr::new(ip, 5223));
 | 
			
		||||
| 
						 | 
				
			
			@ -86,18 +87,67 @@ impl Jabber {
 | 
			
		|||
 | 
			
		||||
        socket_addrs
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    async fn connect(&mut self) {
 | 
			
		||||
        for socket_addr in self.resolve_client().await {
 | 
			
		||||
pub struct Jabber {
 | 
			
		||||
    reader: Reader<OwnedReadHalf>,
 | 
			
		||||
    writer: Writer<OwnedWriteHalf>,
 | 
			
		||||
    data: JabberData,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum JabberError {
 | 
			
		||||
    NotConnected,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Jabber {
 | 
			
		||||
    pub async fn connect(data: JabberData) -> Result<Self, JabberError> {
 | 
			
		||||
        for socket_addr in data.get_sockets().await {
 | 
			
		||||
            println!("trying {}", socket_addr);
 | 
			
		||||
            if let Ok(stream) = TcpStream::connect(socket_addr).await {
 | 
			
		||||
                println!("connected to {}", socket_addr);
 | 
			
		||||
                self.connection = Some(stream);
 | 
			
		||||
                let (read, write) = stream.into_split();
 | 
			
		||||
                return Ok(Self {
 | 
			
		||||
                    reader: Reader::from_reader(read),
 | 
			
		||||
                    writer: Writer::new(write),
 | 
			
		||||
                    data,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Err(JabberError::NotConnected)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn reconnect(&mut self) {
 | 
			
		||||
        for socket_addr in self.data.get_sockets().await {
 | 
			
		||||
            println!("trying {}", socket_addr);
 | 
			
		||||
            if let Ok(stream) = TcpStream::connect(socket_addr).await {
 | 
			
		||||
                println!("connected to {}", socket_addr);
 | 
			
		||||
                let (read, write) = stream.into_split();
 | 
			
		||||
                self.reader = Reader::from_reader(read);
 | 
			
		||||
                self.writer = Writer::new(write);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        println!("could not connect")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn begin_stream(&mut self) -> Result<(), JabberError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn starttls() -> Result<(), JabberError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn directtls() -> Result<(), JabberError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn auth(&mut self) -> Result<(), JabberError> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn close(&mut self) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +158,17 @@ mod tests {
 | 
			
		|||
 | 
			
		||||
    #[tokio::test]
 | 
			
		||||
    async fn get_sockets() {
 | 
			
		||||
        let client = Jabber::new(JID::from_str("cel@blos.sm").unwrap(), "password".to_owned());
 | 
			
		||||
        println!("{:?}", client.resolve_client().await)
 | 
			
		||||
        let data = JabberData::new(JID::from_str("cel@blos.sm").unwrap(), "password".to_owned());
 | 
			
		||||
        println!("{:?}", data.get_sockets().await)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test]
 | 
			
		||||
    async fn connect() {
 | 
			
		||||
        Jabber::connect(JabberData::new(
 | 
			
		||||
            JID::from_str("cel@blos.sm").unwrap(),
 | 
			
		||||
            "password".to_owned(),
 | 
			
		||||
        ))
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue