2020-03-05 01:25:24 +01:00
|
|
|
use futures::stream::StreamExt;
|
|
|
|
|
use tokio::io::{AsyncRead, AsyncWrite};
|
2019-09-08 21:28:44 +02:00
|
|
|
use xmpp_parsers::bind::{BindQuery, BindResponse};
|
2018-12-18 19:04:31 +01:00
|
|
|
use xmpp_parsers::iq::{Iq, IqType};
|
2017-06-19 02:16:47 +02:00
|
|
|
|
2018-12-18 18:29:31 +01:00
|
|
|
use crate::xmpp_codec::Packet;
|
|
|
|
|
use crate::xmpp_stream::XMPPStream;
|
|
|
|
|
use crate::{Error, ProtocolError};
|
2017-06-19 02:16:47 +02:00
|
|
|
|
|
|
|
|
const BIND_REQ_ID: &str = "resource-bind";
|
|
|
|
|
|
2020-03-05 01:25:24 +01:00
|
|
|
pub async fn bind<S: AsyncRead + AsyncWrite + Unpin>(
|
|
|
|
|
mut stream: XMPPStream<S>,
|
|
|
|
|
) -> Result<XMPPStream<S>, Error> {
|
2020-03-18 01:12:48 +01:00
|
|
|
if stream.stream_features.can_bind() {
|
2023-06-20 14:35:28 +02:00
|
|
|
let resource = stream
|
|
|
|
|
.jid
|
2024-03-03 16:15:04 +01:00
|
|
|
.resource()
|
|
|
|
|
.and_then(|resource| Some(resource.to_string()));
|
2020-03-18 01:12:48 +01:00
|
|
|
let iq = Iq::from_set(BIND_REQ_ID, BindQuery::new(resource));
|
|
|
|
|
stream.send_stanza(iq).await?;
|
2017-06-19 02:16:47 +02:00
|
|
|
|
2020-03-18 01:12:48 +01:00
|
|
|
loop {
|
|
|
|
|
match stream.next().await {
|
|
|
|
|
Some(Ok(Packet::Stanza(stanza))) => match Iq::try_from(stanza) {
|
|
|
|
|
Ok(iq) if iq.id == BIND_REQ_ID => match iq.payload {
|
|
|
|
|
IqType::Result(payload) => {
|
|
|
|
|
payload
|
|
|
|
|
.and_then(|payload| BindResponse::try_from(payload).ok())
|
|
|
|
|
.map(|bind| stream.jid = bind.into());
|
|
|
|
|
return Ok(stream);
|
|
|
|
|
}
|
|
|
|
|
_ => return Err(ProtocolError::InvalidBindResponse.into()),
|
2020-03-05 01:25:24 +01:00
|
|
|
},
|
2020-03-18 01:12:48 +01:00
|
|
|
_ => {}
|
|
|
|
|
},
|
|
|
|
|
Some(Ok(_)) => {}
|
|
|
|
|
Some(Err(e)) => return Err(e),
|
|
|
|
|
None => return Err(Error::Disconnected),
|
2020-03-05 01:25:24 +01:00
|
|
|
}
|
2017-06-19 02:16:47 +02:00
|
|
|
}
|
2020-03-18 01:12:48 +01:00
|
|
|
} else {
|
|
|
|
|
// No resource binding available,
|
|
|
|
|
// return the (probably // usable) stream immediately
|
|
|
|
|
return Ok(stream);
|
2017-06-19 02:16:47 +02:00
|
|
|
}
|
|
|
|
|
}
|