Port crates to use new XSO-based xmlstream
This commit is contained in:
parent
7cfda820a6
commit
ab10e30ac0
26 changed files with 623 additions and 973 deletions
|
|
@ -1,12 +1,12 @@
|
|||
use futures::stream::StreamExt;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use std::io;
|
||||
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use tokio::io::{AsyncBufRead, AsyncWrite};
|
||||
use xmpp_parsers::{component::Handshake, jid::Jid, ns};
|
||||
|
||||
use crate::{
|
||||
connect::ServerConnector,
|
||||
error::{AuthError, Error},
|
||||
proto::{Packet, XmppStream},
|
||||
};
|
||||
use crate::component::ServerConnector;
|
||||
use crate::error::{AuthError, Error};
|
||||
use crate::xmlstream::{ReadError, XmppStream, XmppStreamElement};
|
||||
|
||||
/// Log into an XMPP server as a client with a jid+pass
|
||||
pub async fn component_login<C: ServerConnector>(
|
||||
|
|
@ -15,32 +15,47 @@ pub async fn component_login<C: ServerConnector>(
|
|||
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)
|
||||
let mut stream = connector.connect(&jid, ns::COMPONENT).await?;
|
||||
let header = stream.take_header();
|
||||
let mut stream = stream.skip_features();
|
||||
let stream_id = match header.id {
|
||||
Some(ref v) => &**v,
|
||||
None => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"stream id missing on component stream",
|
||||
)
|
||||
.into())
|
||||
}
|
||||
};
|
||||
auth(&mut stream, stream_id, &password).await?;
|
||||
Ok(stream)
|
||||
}
|
||||
|
||||
pub async fn auth<S: AsyncRead + AsyncWrite + Unpin>(
|
||||
pub async fn auth<S: AsyncBufRead + AsyncWrite + Unpin>(
|
||||
stream: &mut XmppStream<S>,
|
||||
password: String,
|
||||
stream_id: &str,
|
||||
password: &str,
|
||||
) -> Result<(), Error> {
|
||||
let nonza = Handshake::from_password_and_stream_id(&password, &stream.id);
|
||||
stream.send_stanza(nonza).await?;
|
||||
let nonza = Handshake::from_password_and_stream_id(password, stream_id);
|
||||
stream
|
||||
.send(&XmppStreamElement::ComponentHandshake(nonza))
|
||||
.await?;
|
||||
|
||||
loop {
|
||||
match stream.next().await {
|
||||
Some(Ok(Packet::Stanza(ref stanza)))
|
||||
if stanza.is("handshake", ns::COMPONENT_ACCEPT) =>
|
||||
{
|
||||
Some(Ok(XmppStreamElement::ComponentHandshake(_))) => {
|
||||
return Ok(());
|
||||
}
|
||||
Some(Ok(Packet::Stanza(ref stanza)))
|
||||
if stanza.is("error", "http://etherx.jabber.org/streams") =>
|
||||
{
|
||||
Some(Ok(_)) => {
|
||||
return Err(AuthError::ComponentFail.into());
|
||||
}
|
||||
Some(_) => {}
|
||||
None => return Err(Error::Disconnected),
|
||||
Some(Err(ReadError::SoftTimeout)) => (),
|
||||
Some(Err(ReadError::HardError(e))) => return Err(e.into()),
|
||||
Some(Err(ReadError::ParseError(e))) => {
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidData, e).into())
|
||||
}
|
||||
Some(Err(ReadError::StreamFooterReceived)) | None => return Err(Error::Disconnected),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,12 @@
|
|||
//! 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::sink::SinkExt;
|
||||
use minidom::Element;
|
||||
use std::str::FromStr;
|
||||
use xmpp_parsers::{jid::Jid, ns};
|
||||
use xmpp_parsers::jid::Jid;
|
||||
|
||||
use crate::{
|
||||
component::login::component_login,
|
||||
connect::ServerConnector,
|
||||
proto::{add_stanza_id, XmppStream},
|
||||
Error,
|
||||
component::login::component_login, connect::ServerConnector, xmlstream::XmppStream, Error,
|
||||
Stanza,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "starttls", feature = "insecure-tcp"))]
|
||||
|
|
@ -33,8 +30,9 @@ pub struct Component<C: ServerConnector> {
|
|||
|
||||
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
|
||||
pub async fn send_stanza(&mut self, mut stanza: Stanza) -> Result<(), Error> {
|
||||
stanza.ensure_id();
|
||||
self.send(stanza).await
|
||||
}
|
||||
|
||||
/// End connection
|
||||
|
|
|
|||
|
|
@ -2,21 +2,27 @@
|
|||
//! 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};
|
||||
use crate::{
|
||||
component::Component, connect::ServerConnector, xmlstream::XmppStreamElement, Error, Stanza,
|
||||
};
|
||||
|
||||
impl<C: ServerConnector> Stream for Component<C> {
|
||||
type Item = Element;
|
||||
type Item = Stanza;
|
||||
|
||||
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(XmppStreamElement::Iq(stanza)))) => {
|
||||
return Poll::Ready(Some(Stanza::Iq(stanza)))
|
||||
}
|
||||
Poll::Ready(Some(Ok(XmppStreamElement::Message(stanza)))) => {
|
||||
return Poll::Ready(Some(Stanza::Message(stanza)))
|
||||
}
|
||||
Poll::Ready(Some(Ok(XmppStreamElement::Presence(stanza)))) => {
|
||||
return Poll::Ready(Some(Stanza::Presence(stanza)))
|
||||
}
|
||||
Poll::Ready(Some(Ok(_))) =>
|
||||
// unexpected
|
||||
|
|
@ -31,12 +37,12 @@ impl<C: ServerConnector> Stream for Component<C> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<C: ServerConnector> Sink<Element> for Component<C> {
|
||||
impl<C: ServerConnector> Sink<Stanza> for Component<C> {
|
||||
type Error = Error;
|
||||
|
||||
fn start_send(mut self: Pin<&mut Self>, item: Element) -> Result<(), Self::Error> {
|
||||
fn start_send(mut self: Pin<&mut Self>, item: Stanza) -> Result<(), Self::Error> {
|
||||
Pin::new(&mut self.stream)
|
||||
.start_send(Packet::Stanza(item))
|
||||
.start_send(&item.into())
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue