Reorganize component modules
This commit is contained in:
parent
e6863bd9dd
commit
cc3400bac7
4 changed files with 102 additions and 91 deletions
|
|
@ -1,15 +0,0 @@
|
||||||
use xmpp_parsers::{jid::Jid, ns};
|
|
||||||
|
|
||||||
use crate::{component::auth::auth, connect::ServerConnector, proto::XmppStream, Error};
|
|
||||||
|
|
||||||
/// Log into an XMPP server as a client with a jid+pass
|
|
||||||
pub async fn component_login<C: ServerConnector>(
|
|
||||||
connector: C,
|
|
||||||
jid: Jid,
|
|
||||||
password: String,
|
|
||||||
) -> Result<XmppStream<C::Stream>, Error> {
|
|
||||||
let password = password;
|
|
||||||
let mut xmpp_stream = connector.connect(&jid, ns::COMPONENT).await?;
|
|
||||||
auth(&mut xmpp_stream, password).await?;
|
|
||||||
Ok(xmpp_stream)
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,24 @@
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use tokio::io::{AsyncRead, AsyncWrite};
|
use tokio::io::{AsyncRead, AsyncWrite};
|
||||||
use xmpp_parsers::{component::Handshake, ns};
|
use xmpp_parsers::{component::Handshake, jid::Jid, ns};
|
||||||
|
|
||||||
use crate::error::{AuthError, Error};
|
use crate::{
|
||||||
use crate::proto::{Packet, XmppStream};
|
connect::ServerConnector,
|
||||||
|
error::{AuthError, Error},
|
||||||
|
proto::{Packet, XmppStream},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Log into an XMPP server as a client with a jid+pass
|
||||||
|
pub async fn component_login<C: ServerConnector>(
|
||||||
|
connector: C,
|
||||||
|
jid: Jid,
|
||||||
|
password: String,
|
||||||
|
) -> Result<XmppStream<C::Stream>, Error> {
|
||||||
|
let password = password;
|
||||||
|
let mut xmpp_stream = connector.connect(&jid, ns::COMPONENT).await?;
|
||||||
|
auth(&mut xmpp_stream, password).await?;
|
||||||
|
Ok(xmpp_stream)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn auth<S: AsyncRead + AsyncWrite + Unpin>(
|
pub async fn auth<S: AsyncRead + AsyncWrite + Unpin>(
|
||||||
stream: &mut XmppStream<S>,
|
stream: &mut XmppStream<S>,
|
||||||
|
|
@ -1,27 +1,25 @@
|
||||||
//! Components in XMPP are services/gateways that are logged into an
|
//! Components in XMPP are services/gateways that are logged into an
|
||||||
//! XMPP server under a JID consisting of just a domain name. They are
|
//! XMPP server under a JID consisting of just a domain name. They are
|
||||||
//! allowed to use any user and resource identifiers in their stanzas.
|
//! allowed to use any user and resource identifiers in their stanzas.
|
||||||
use futures::{sink::SinkExt, task::Poll, Sink, Stream};
|
use futures::sink::SinkExt;
|
||||||
use minidom::Element;
|
use minidom::Element;
|
||||||
use std::pin::Pin;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::task::Context;
|
|
||||||
use xmpp_parsers::{jid::Jid, ns};
|
use xmpp_parsers::{jid::Jid, ns};
|
||||||
|
|
||||||
use self::connect::component_login;
|
use crate::{
|
||||||
|
component::login::component_login,
|
||||||
use crate::connect::ServerConnector;
|
connect::ServerConnector,
|
||||||
use crate::proto::{add_stanza_id, Packet, XmppStream};
|
proto::{add_stanza_id, XmppStream},
|
||||||
use crate::Error;
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "starttls", feature = "insecure-tcp"))]
|
#[cfg(any(feature = "starttls", feature = "insecure-tcp"))]
|
||||||
use crate::connect::DnsConfig;
|
use crate::connect::DnsConfig;
|
||||||
#[cfg(feature = "insecure-tcp")]
|
#[cfg(feature = "insecure-tcp")]
|
||||||
use crate::connect::TcpServerConnector;
|
use crate::connect::TcpServerConnector;
|
||||||
|
|
||||||
mod auth;
|
mod login;
|
||||||
|
mod stream;
|
||||||
pub(crate) mod connect;
|
|
||||||
|
|
||||||
/// Component connection to an XMPP server
|
/// Component connection to an XMPP server
|
||||||
///
|
///
|
||||||
|
|
@ -33,20 +31,34 @@ pub struct Component<C: ServerConnector> {
|
||||||
stream: XmppStream<C::Stream>,
|
stream: XmppStream<C::Stream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<C: ServerConnector> Component<C> {
|
||||||
|
/// Send stanza
|
||||||
|
pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> {
|
||||||
|
self.send(add_stanza_id(stanza, ns::COMPONENT_ACCEPT)).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// End connection
|
||||||
|
pub async fn send_end(&mut self) -> Result<(), Error> {
|
||||||
|
self.close().await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "insecure-tcp")]
|
#[cfg(feature = "insecure-tcp")]
|
||||||
impl Component<TcpServerConnector> {
|
impl Component<TcpServerConnector> {
|
||||||
/// Start a new XMPP component over plaintext TCP to localhost:5347
|
/// Start a new XMPP component over plaintext TCP to localhost:5347
|
||||||
|
#[cfg(feature = "insecure-tcp")]
|
||||||
pub async fn new(jid: &str, password: &str) -> Result<Self, Error> {
|
pub async fn new(jid: &str, password: &str) -> Result<Self, Error> {
|
||||||
Self::new_plaintext(jid, password, DnsConfig::addr("127.0.0.1:5347")).await
|
Self::new_plaintext(jid, password, DnsConfig::addr("127.0.0.1:5347")).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a new XMPP component over plaintext TCP
|
/// Start a new XMPP component over plaintext TCP
|
||||||
|
#[cfg(feature = "insecure-tcp")]
|
||||||
pub async fn new_plaintext(
|
pub async fn new_plaintext(
|
||||||
jid: &str,
|
jid: &str,
|
||||||
password: &str,
|
password: &str,
|
||||||
dns_config: DnsConfig,
|
dns_config: DnsConfig,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Self::new_with_connector(jid, password, TcpServerConnector::from(dns_config)).await
|
Component::new_with_connector(jid, password, TcpServerConnector::from(dns_config)).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,65 +77,4 @@ impl<C: ServerConnector> Component<C> {
|
||||||
let stream = component_login(connector, jid.clone(), password).await?;
|
let stream = component_login(connector, jid.clone(), password).await?;
|
||||||
Ok(Component { jid, stream })
|
Ok(Component { jid, stream })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send stanza
|
|
||||||
pub async fn send_stanza(&mut self, stanza: Element) -> Result<(), Error> {
|
|
||||||
self.send(add_stanza_id(stanza, ns::COMPONENT_ACCEPT)).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// End connection
|
|
||||||
pub async fn send_end(&mut self) -> Result<(), Error> {
|
|
||||||
self.close().await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: ServerConnector> Stream for Component<C> {
|
|
||||||
type Item = Element;
|
|
||||||
|
|
||||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
|
||||||
loop {
|
|
||||||
match Pin::new(&mut self.stream).poll_next(cx) {
|
|
||||||
Poll::Ready(Some(Ok(Packet::Stanza(stanza)))) => return Poll::Ready(Some(stanza)),
|
|
||||||
Poll::Ready(Some(Ok(Packet::Text(_)))) => {
|
|
||||||
// retry
|
|
||||||
}
|
|
||||||
Poll::Ready(Some(Ok(_))) =>
|
|
||||||
// unexpected
|
|
||||||
{
|
|
||||||
return Poll::Ready(None)
|
|
||||||
}
|
|
||||||
Poll::Ready(Some(Err(_))) => return Poll::Ready(None),
|
|
||||||
Poll::Ready(None) => return Poll::Ready(None),
|
|
||||||
Poll::Pending => return Poll::Pending,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: ServerConnector> Sink<Element> for Component<C> {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn start_send(mut self: Pin<&mut Self>, item: Element) -> Result<(), Self::Error> {
|
|
||||||
Pin::new(&mut self.stream)
|
|
||||||
.start_send(Packet::Stanza(item))
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
|
||||||
Pin::new(&mut self.stream)
|
|
||||||
.poll_ready(cx)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
|
||||||
Pin::new(&mut self.stream)
|
|
||||||
.poll_flush(cx)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
|
||||||
Pin::new(&mut self.stream)
|
|
||||||
.poll_close(cx)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
tokio-xmpp/src/component/stream.rs
Normal file
60
tokio-xmpp/src/component/stream.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
//! Components in XMPP are services/gateways that are logged into an
|
||||||
|
//! XMPP server under a JID consisting of just a domain name. They are
|
||||||
|
//! allowed to use any user and resource identifiers in their stanzas.
|
||||||
|
use futures::{task::Poll, Sink, Stream};
|
||||||
|
use minidom::Element;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::Context;
|
||||||
|
|
||||||
|
use crate::{component::Component, connect::ServerConnector, proto::Packet, Error};
|
||||||
|
|
||||||
|
impl<C: ServerConnector> Stream for Component<C> {
|
||||||
|
type Item = Element;
|
||||||
|
|
||||||
|
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||||
|
loop {
|
||||||
|
match Pin::new(&mut self.stream).poll_next(cx) {
|
||||||
|
Poll::Ready(Some(Ok(Packet::Stanza(stanza)))) => return Poll::Ready(Some(stanza)),
|
||||||
|
Poll::Ready(Some(Ok(Packet::Text(_)))) => {
|
||||||
|
// retry
|
||||||
|
}
|
||||||
|
Poll::Ready(Some(Ok(_))) =>
|
||||||
|
// unexpected
|
||||||
|
{
|
||||||
|
return Poll::Ready(None)
|
||||||
|
}
|
||||||
|
Poll::Ready(Some(Err(_))) => return Poll::Ready(None),
|
||||||
|
Poll::Ready(None) => return Poll::Ready(None),
|
||||||
|
Poll::Pending => return Poll::Pending,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: ServerConnector> Sink<Element> for Component<C> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn start_send(mut self: Pin<&mut Self>, item: Element) -> Result<(), Self::Error> {
|
||||||
|
Pin::new(&mut self.stream)
|
||||||
|
.start_send(Packet::Stanza(item))
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Pin::new(&mut self.stream)
|
||||||
|
.poll_ready(cx)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Pin::new(&mut self.stream)
|
||||||
|
.poll_flush(cx)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Pin::new(&mut self.stream)
|
||||||
|
.poll_close(cx)
|
||||||
|
.map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue