aboutsummaryrefslogtreecommitdiff
path: root/src/QXmppStream.cpp
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2010-08-11 11:32:26 +0000
committerJeremy Lainé <jeremy.laine@m4x.org>2010-08-11 11:32:26 +0000
commit2eaf60879ebaac742f9e3e5c65ffec69dbf3623a (patch)
tree8d4aa7f112507785a061291ae67c5f129ac859ac /src/QXmppStream.cpp
parentc50b56bb5214c89019ab825d061cda4a9969f529 (diff)
downloadqxmpp-2eaf60879ebaac742f9e3e5c65ffec69dbf3623a.tar.gz
clarify QXmppStream::parser by exiting earlier
Diffstat (limited to 'src/QXmppStream.cpp')
-rw-r--r--src/QXmppStream.cpp913
1 files changed, 448 insertions, 465 deletions
diff --git a/src/QXmppStream.cpp b/src/QXmppStream.cpp
index 05892dab..424b1f00 100644
--- a/src/QXmppStream.cpp
+++ b/src/QXmppStream.cpp
@@ -267,537 +267,536 @@ void QXmppStream::warning(const QString &data)
void QXmppStream::parser(const QByteArray& data)
{
- QDomDocument doc;
- QByteArray completeXml;
-
d->dataBuffer.append(data);
- if(hasStartStreamElement(d->dataBuffer))
- {
+ // FIXME : maybe these QRegExps could be static?
+ QRegExp startStreamRegex("^(<\\?xml.*\\?>)?\\s*<stream:stream.*>");
+ startStreamRegex.setMinimal(true);
+ QRegExp endStreamRegex("</stream:stream>$");
+ endStreamRegex.setMinimal(true);
+
+ // check whether we need to add stream start / end elements
+ QByteArray completeXml;
+ const QString strData = QString::fromUtf8(d->dataBuffer);
+ if(strData.contains(startStreamRegex))
completeXml = d->dataBuffer + streamRootElementEnd;
- }
- else if(hasEndStreamElement(data))
- {
+ else if(strData.contains(endStreamRegex))
completeXml = streamRootElementStart + d->dataBuffer;
- }
else
- {
completeXml = streamRootElementStart + d->dataBuffer + streamRootElementEnd;
- }
-
- if(doc.setContent(completeXml, true))
- {
- emit logMessage(QXmppLogger::ReceivedMessage, QString::fromUtf8(d->dataBuffer));
- flushDataBuffer();
- QDomElement nodeRecv = doc.documentElement().firstChildElement();
+ // check whether we have a valid XML document
+ QDomDocument doc;
+ if(!doc.setContent(completeXml, true))
+ return;
- if(nodeRecv.isNull())
+ // process stanzas
+ emit logMessage(QXmppLogger::ReceivedMessage, strData);
+ flushDataBuffer();
+
+ // process stanzas
+ QDomElement nodeRecv = doc.documentElement().firstChildElement();
+ if(nodeRecv.isNull())
+ {
+ QDomElement streamElement = doc.documentElement();
+ if(d->streamId.isEmpty())
+ d->streamId = streamElement.attribute("id");
+ if(d->XMPPVersion.isEmpty())
{
- QDomElement streamElement = doc.documentElement();
- if(d->streamId.isEmpty())
- d->streamId = streamElement.attribute("id");
+ d->XMPPVersion = streamElement.attribute("version");
if(d->XMPPVersion.isEmpty())
{
- d->XMPPVersion = streamElement.attribute("version");
- if(d->XMPPVersion.isEmpty())
- {
- // no version specified, signals XMPP Version < 1.0.
- // switch to old auth mechanism
- sendNonSASLAuthQuery(doc.documentElement().attribute("from"));
- }
+ // no version specified, signals XMPP Version < 1.0.
+ // switch to old auth mechanism
+ sendNonSASLAuthQuery(doc.documentElement().attribute("from"));
}
}
- else
- {
- //TODO: Make a login error here.
- }
- while(!nodeRecv.isNull())
- {
+ }
+ else
+ {
+ //TODO: Make a login error here.
+ }
+ while(!nodeRecv.isNull())
+ {
- QString ns = nodeRecv.namespaceURI();
+ QString ns = nodeRecv.namespaceURI();
- // if we receive any kind of data, stop the timeout timer
- d->timeoutTimer->stop();
+ // if we receive any kind of data, stop the timeout timer
+ d->timeoutTimer->stop();
- bool handled = false;
- emit elementReceived(nodeRecv, handled);
+ bool handled = false;
+ emit elementReceived(nodeRecv, handled);
- if(handled)
- {
- // already handled by client, do nothing
- }
- else if(ns == ns_stream && nodeRecv.tagName() == "features")
- {
- bool nonSaslAvailable = nodeRecv.firstChildElement("auth").
- namespaceURI() == ns_authFeature;
- bool saslAvailable = nodeRecv.firstChildElement("mechanisms").
- namespaceURI() == ns_sasl;
- bool useSasl = configuration().useSASLAuthentication();
+ if(handled)
+ {
+ // already handled by client, do nothing
+ }
+ else if(ns == ns_stream && nodeRecv.tagName() == "features")
+ {
+ bool nonSaslAvailable = nodeRecv.firstChildElement("auth").
+ namespaceURI() == ns_authFeature;
+ bool saslAvailable = nodeRecv.firstChildElement("mechanisms").
+ namespaceURI() == ns_sasl;
+ bool useSasl = configuration().useSASLAuthentication();
- if (!d->socket.isEncrypted())
+ if (!d->socket.isEncrypted())
+ {
+ // parse remote TLS mode
+ QXmppConfiguration::StreamSecurityMode remoteSecurity;
+ QDomElement tlsElement = nodeRecv.firstChildElement("starttls");
+ if (tlsElement.namespaceURI() == ns_tls)
{
- // parse remote TLS mode
- QXmppConfiguration::StreamSecurityMode remoteSecurity;
- QDomElement tlsElement = nodeRecv.firstChildElement("starttls");
- if (tlsElement.namespaceURI() == ns_tls)
- {
- if (tlsElement.firstChildElement().tagName() == "required")
- remoteSecurity = QXmppConfiguration::TLSRequired;
- else
- remoteSecurity = QXmppConfiguration::TLSEnabled;
- } else {
- remoteSecurity = QXmppConfiguration::TLSDisabled;
- }
-
- // determine TLS mode to use
- const QXmppConfiguration::StreamSecurityMode localSecurity = configuration().streamSecurityMode();
- if (!d->socket.supportsSsl() &&
- (localSecurity == QXmppConfiguration::TLSRequired ||
- remoteSecurity == QXmppConfiguration::TLSRequired))
- {
- warning("Disconnecting as TLS is required, but SSL support is not available");
- disconnect();
- return;
- }
- if (localSecurity == QXmppConfiguration::TLSRequired &&
- remoteSecurity == QXmppConfiguration::TLSDisabled)
- {
- warning("Disconnecting as TLS is required, but not supported by the server");
- disconnect();
- return;
- }
-
- if (d->socket.supportsSsl() &&
- (remoteSecurity == QXmppConfiguration::TLSRequired ||
- localSecurity != QXmppConfiguration::TLSDisabled))
- {
- // enable TLS as it is required by the server
- // or supported by the client
- sendToServer("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
- return;
- }
+ if (tlsElement.firstChildElement().tagName() == "required")
+ remoteSecurity = QXmppConfiguration::TLSRequired;
+ else
+ remoteSecurity = QXmppConfiguration::TLSEnabled;
+ } else {
+ remoteSecurity = QXmppConfiguration::TLSDisabled;
}
- if((saslAvailable && nonSaslAvailable && !useSasl) ||
- (!saslAvailable && nonSaslAvailable))
+ // determine TLS mode to use
+ const QXmppConfiguration::StreamSecurityMode localSecurity = configuration().streamSecurityMode();
+ if (!d->socket.supportsSsl() &&
+ (localSecurity == QXmppConfiguration::TLSRequired ||
+ remoteSecurity == QXmppConfiguration::TLSRequired))
{
- sendNonSASLAuthQuery(doc.documentElement().attribute("from"));
- }
- else if(saslAvailable)
- {
- // parse advertised SASL Authentication mechanisms
- QList<QXmppConfiguration::SASLAuthMechanism> mechanisms;
- QDomElement element = nodeRecv.firstChildElement("mechanisms");
- QDomElement subElement = element.firstChildElement("mechanism");
- debug("SASL Authentication mechanisms:");
- while(!subElement.isNull())
- {
- debug(subElement.text());
- if (subElement.text() == QLatin1String("PLAIN"))
- mechanisms << QXmppConfiguration::SASLPlain;
- else if (subElement.text() == QLatin1String("DIGEST-MD5"))
- mechanisms << QXmppConfiguration::SASLDigestMD5;
- else if (subElement.text() == QLatin1String("ANONYMOUS"))
- mechanisms << QXmppConfiguration::SASLAnonymous;
- subElement = subElement.nextSiblingElement("mechanism");
- }
-
- // determine SASL Authentication mechanism to use
- QXmppConfiguration::SASLAuthMechanism mechanism = configuration().sASLAuthMechanism();
- if (mechanisms.isEmpty())
- {
- warning("No supported SASL Authentication mechanism available");
- disconnect();
- return;
- }
- else if (!mechanisms.contains(mechanism))
- {
- info("Desired SASL Auth mechanism is not available, selecting first available one");
- mechanism = mechanisms.first();
- }
-
- // send SASL Authentication request
- switch(mechanism)
- {
- case QXmppConfiguration::SASLPlain:
- {
- QString userPass('\0' + configuration().user() +
- '\0' + configuration().passwd());
- QByteArray data = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>";
- data += userPass.toUtf8().toBase64();
- data += "</auth>";
- sendToServer(data);
- }
- break;
- case QXmppConfiguration::SASLDigestMD5:
- sendToServer("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>");
- break;
- case QXmppConfiguration::SASLAnonymous:
- sendToServer("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>");
- break;
- }
+ warning("Disconnecting as TLS is required, but SSL support is not available");
+ disconnect();
+ return;
}
-
- if(nodeRecv.firstChildElement("bind").
- namespaceURI() == ns_bind)
+ if (localSecurity == QXmppConfiguration::TLSRequired &&
+ remoteSecurity == QXmppConfiguration::TLSDisabled)
{
- sendBindIQ();
+ warning("Disconnecting as TLS is required, but not supported by the server");
+ disconnect();
+ return;
}
- if(nodeRecv.firstChildElement("session").
- namespaceURI() == ns_session)
+ if (d->socket.supportsSsl() &&
+ (remoteSecurity == QXmppConfiguration::TLSRequired ||
+ localSecurity != QXmppConfiguration::TLSDisabled))
{
- d->sessionAvailable = true;
+ // enable TLS as it is required by the server
+ // or supported by the client
+ sendToServer("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+ return;
}
}
- else if(ns == ns_stream && nodeRecv.tagName() == "error")
+
+ if((saslAvailable && nonSaslAvailable && !useSasl) ||
+ (!saslAvailable && nonSaslAvailable))
{
- if (!nodeRecv.firstChildElement("conflict").isNull())
- d->xmppStreamError = QXmppStanza::Error::Conflict;
- else
- d->xmppStreamError = QXmppStanza::Error::UndefinedCondition;
- emit error(QXmppClient::XmppStreamError);
+ sendNonSASLAuthQuery(doc.documentElement().attribute("from"));
}
- else if(ns == ns_tls)
+ else if(saslAvailable)
{
- if(nodeRecv.tagName() == "proceed")
+ // parse advertised SASL Authentication mechanisms
+ QList<QXmppConfiguration::SASLAuthMechanism> mechanisms;
+ QDomElement element = nodeRecv.firstChildElement("mechanisms");
+ QDomElement subElement = element.firstChildElement("mechanism");
+ debug("SASL Authentication mechanisms:");
+ while(!subElement.isNull())
{
- debug("Starting encryption");
- d->socket.startClientEncryption();
+ debug(subElement.text());
+ if (subElement.text() == QLatin1String("PLAIN"))
+ mechanisms << QXmppConfiguration::SASLPlain;
+ else if (subElement.text() == QLatin1String("DIGEST-MD5"))
+ mechanisms << QXmppConfiguration::SASLDigestMD5;
+ else if (subElement.text() == QLatin1String("ANONYMOUS"))
+ mechanisms << QXmppConfiguration::SASLAnonymous;
+ subElement = subElement.nextSiblingElement("mechanism");
+ }
+
+ // determine SASL Authentication mechanism to use
+ QXmppConfiguration::SASLAuthMechanism mechanism = configuration().sASLAuthMechanism();
+ if (mechanisms.isEmpty())
+ {
+ warning("No supported SASL Authentication mechanism available");
+ disconnect();
return;
}
- }
- else if(ns == ns_sasl)
- {
- if(nodeRecv.tagName() == "success")
+ else if (!mechanisms.contains(mechanism))
{
- debug("Authenticated");
- sendStartStream();
+ info("Desired SASL Auth mechanism is not available, selecting first available one");
+ mechanism = mechanisms.first();
}
- else if(nodeRecv.tagName() == "challenge")
+
+ // send SASL Authentication request
+ switch(mechanism)
{
- // TODO: Track which mechanism was used for when other SASL protocols which use challenges are supported
- d->authStep++;
- switch (d->authStep)
+ case QXmppConfiguration::SASLPlain:
{
- case 1 :
- sendAuthDigestMD5ResponseStep1(nodeRecv.text());
- break;
- case 2 :
- sendAuthDigestMD5ResponseStep2();
- break;
- default :
- warning("Too many authentication steps");
- disconnect();
- break;
+ QString userPass('\0' + configuration().user() +
+ '\0' + configuration().passwd());
+ QByteArray data = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>";
+ data += userPass.toUtf8().toBase64();
+ data += "</auth>";
+ sendToServer(data);
}
+ break;
+ case QXmppConfiguration::SASLDigestMD5:
+ sendToServer("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>");
+ break;
+ case QXmppConfiguration::SASLAnonymous:
+ sendToServer("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>");
+ break;
}
- else if(nodeRecv.tagName() == "failure")
- {
- if (!nodeRecv.firstChildElement("not-authorized").isNull())
- d->xmppStreamError = QXmppStanza::Error::NotAuthorized;
- else
- d->xmppStreamError = QXmppStanza::Error::UndefinedCondition;
- emit error(QXmppClient::XmppStreamError);
+ }
+
+ if(nodeRecv.firstChildElement("bind").
+ namespaceURI() == ns_bind)
+ {
+ sendBindIQ();
+ }
- warning("Authentication failure");
+ if(nodeRecv.firstChildElement("session").
+ namespaceURI() == ns_session)
+ {
+ d->sessionAvailable = true;
+ }
+ }
+ else if(ns == ns_stream && nodeRecv.tagName() == "error")
+ {
+ if (!nodeRecv.firstChildElement("conflict").isNull())
+ d->xmppStreamError = QXmppStanza::Error::Conflict;
+ else
+ d->xmppStreamError = QXmppStanza::Error::UndefinedCondition;
+ emit error(QXmppClient::XmppStreamError);
+ }
+ else if(ns == ns_tls)
+ {
+ if(nodeRecv.tagName() == "proceed")
+ {
+ debug("Starting encryption");
+ d->socket.startClientEncryption();
+ return;
+ }
+ }
+ else if(ns == ns_sasl)
+ {
+ if(nodeRecv.tagName() == "success")
+ {
+ debug("Authenticated");
+ sendStartStream();
+ }
+ else if(nodeRecv.tagName() == "challenge")
+ {
+ // TODO: Track which mechanism was used for when other SASL protocols which use challenges are supported
+ d->authStep++;
+ switch (d->authStep)
+ {
+ case 1 :
+ sendAuthDigestMD5ResponseStep1(nodeRecv.text());
+ break;
+ case 2 :
+ sendAuthDigestMD5ResponseStep2();
+ break;
+ default :
+ warning("Too many authentication steps");
disconnect();
+ break;
}
}
- else if(ns == ns_client)
+ else if(nodeRecv.tagName() == "failure")
{
+ if (!nodeRecv.firstChildElement("not-authorized").isNull())
+ d->xmppStreamError = QXmppStanza::Error::NotAuthorized;
+ else
+ d->xmppStreamError = QXmppStanza::Error::UndefinedCondition;
+ emit error(QXmppClient::XmppStreamError);
- if(nodeRecv.tagName() == "iq")
+ warning("Authentication failure");
+ disconnect();
+ }
+ }
+ else if(ns == ns_client)
+ {
+
+ if(nodeRecv.tagName() == "iq")
+ {
+ QDomElement element = nodeRecv.firstChildElement();
+ QString id = nodeRecv.attribute("id");
+ QString type = nodeRecv.attribute("type");
+ if(type.isEmpty())
+ warning("QXmppStream: iq type can't be empty");
+
+ if(id == d->sessionId)
{
- QDomElement element = nodeRecv.firstChildElement();
- QString id = nodeRecv.attribute("id");
- QString type = nodeRecv.attribute("type");
- if(type.isEmpty())
- warning("QXmppStream: iq type can't be empty");
+ QXmppSession session;
+ session.parse(nodeRecv);
- if(id == d->sessionId)
- {
- QXmppSession session;
- session.parse(nodeRecv);
+ // get back add configuration whether to send
+ // roster and intial presence in beginning
+ // process SessionIq
- // get back add configuration whether to send
- // roster and intial presence in beginning
- // process SessionIq
+ // xmpp connection made
+ emit xmppConnected();
+ }
+ else if(QXmppBind::isBind(nodeRecv) && id == d->bindId)
+ {
+ QXmppBind bind;
+ bind.parse(nodeRecv);
- // xmpp connection made
- emit xmppConnected();
- }
- else if(QXmppBind::isBind(nodeRecv) && id == d->bindId)
+ // bind result
+ if (bind.type() == QXmppIq::Result)
{
- QXmppBind bind;
- bind.parse(nodeRecv);
-
- // bind result
- if (bind.type() == QXmppIq::Result)
+ if (!bind.jid().isEmpty())
{
- if (!bind.jid().isEmpty())
+ QRegExp jidRegex("^([^@/]+)@([^@/]+)/(.+)$");
+ if (jidRegex.exactMatch(bind.jid()))
{
- QRegExp jidRegex("^([^@/]+)@([^@/]+)/(.+)$");
- if (jidRegex.exactMatch(bind.jid()))
- {
- configuration().setUser(jidRegex.cap(1));
- configuration().setDomain(jidRegex.cap(2));
- configuration().setResource(jidRegex.cap(3));
- } else {
- warning("Bind IQ received with invalid JID: " + bind.jid());
- }
+ configuration().setUser(jidRegex.cap(1));
+ configuration().setDomain(jidRegex.cap(2));
+ configuration().setResource(jidRegex.cap(3));
+ } else {
+ warning("Bind IQ received with invalid JID: " + bind.jid());
}
- if (d->sessionAvailable)
- sendSessionIQ();
}
+ if (d->sessionAvailable)
+ sendSessionIQ();
}
- else if(QXmppRosterIq::isRosterIq(nodeRecv))
- {
- QXmppRosterIq rosterIq;
- rosterIq.parse(nodeRecv);
- emit rosterIqReceived(rosterIq);
- }
- // extensions
+ }
+ else if(QXmppRosterIq::isRosterIq(nodeRecv))
+ {
+ QXmppRosterIq rosterIq;
+ rosterIq.parse(nodeRecv);
+ emit rosterIqReceived(rosterIq);
+ }
+ // extensions
- // XEP-0009: Jabber-RPC
- else if(QXmppRpcInvokeIq::isRpcInvokeIq(nodeRecv))
- {
- QXmppRpcInvokeIq rpcIqPacket;
- rpcIqPacket.parse(nodeRecv);
- emit rpcCallInvoke(rpcIqPacket);
- }
- else if(QXmppRpcResponseIq::isRpcResponseIq(nodeRecv))
- {
- QXmppRpcResponseIq rpcResponseIq;
- rpcResponseIq.parse(nodeRecv);
- emit rpcCallResponse(rpcResponseIq);
- }
- else if(QXmppRpcErrorIq::isRpcErrorIq(nodeRecv))
- {
- QXmppRpcErrorIq rpcErrorIq;
- rpcErrorIq.parse(nodeRecv);
- emit rpcCallError(rpcErrorIq);
- }
+ // XEP-0009: Jabber-RPC
+ else if(QXmppRpcInvokeIq::isRpcInvokeIq(nodeRecv))
+ {
+ QXmppRpcInvokeIq rpcIqPacket;
+ rpcIqPacket.parse(nodeRecv);
+ emit rpcCallInvoke(rpcIqPacket);
+ }
+ else if(QXmppRpcResponseIq::isRpcResponseIq(nodeRecv))
+ {
+ QXmppRpcResponseIq rpcResponseIq;
+ rpcResponseIq.parse(nodeRecv);
+ emit rpcCallResponse(rpcResponseIq);
+ }
+ else if(QXmppRpcErrorIq::isRpcErrorIq(nodeRecv))
+ {
+ QXmppRpcErrorIq rpcErrorIq;
+ rpcErrorIq.parse(nodeRecv);
+ emit rpcCallError(rpcErrorIq);
+ }
- // XEP-0030: Service Discovery
- else if(QXmppDiscoveryIq::isDiscoveryIq(nodeRecv))
- {
- QXmppDiscoveryIq discoIq;
- discoIq.parse(nodeRecv);
+ // XEP-0030: Service Discovery
+ else if(QXmppDiscoveryIq::isDiscoveryIq(nodeRecv))
+ {
+ QXmppDiscoveryIq discoIq;
+ discoIq.parse(nodeRecv);
- if (discoIq.type() == QXmppIq::Get &&
- discoIq.queryType() == QXmppDiscoveryIq::InfoQuery &&
- (discoIq.queryNode().isEmpty() || discoIq.queryNode().startsWith(capabilitiesNode)))
- {
- // respond to info query
- QXmppDiscoveryIq qxmppFeatures = capabilities();
- qxmppFeatures.setId(discoIq.id());
- qxmppFeatures.setTo(discoIq.from());
- qxmppFeatures.setQueryNode(discoIq.queryNode());
- sendPacket(qxmppFeatures);
- } else {
- emit discoveryIqReceived(discoIq);
- }
- }
- // XEP-0045: Multi-User Chat
- else if (QXmppMucAdminIq::isMucAdminIq(nodeRecv))
- {
- QXmppMucAdminIq mucIq;
- mucIq.parse(nodeRecv);
- emit mucAdminIqReceived(mucIq);
- }
- else if (QXmppMucOwnerIq::isMucOwnerIq(nodeRecv))
- {
- QXmppMucOwnerIq mucIq;
- mucIq.parse(nodeRecv);
- emit mucOwnerIqReceived(mucIq);
- }
- // XEP-0047 In-Band Bytestreams
- else if(QXmppIbbCloseIq::isIbbCloseIq(nodeRecv))
- {
- QXmppIbbCloseIq ibbCloseIq;
- ibbCloseIq.parse(nodeRecv);
- emit ibbCloseIqReceived(ibbCloseIq);
- }
- else if(QXmppIbbDataIq::isIbbDataIq(nodeRecv))
- {
- QXmppIbbDataIq ibbDataIq;
- ibbDataIq.parse(nodeRecv);
- emit ibbDataIqReceived(ibbDataIq);
- }
- else if(QXmppIbbOpenIq::isIbbOpenIq(nodeRecv))
- {
- QXmppIbbOpenIq ibbOpenIq;
- ibbOpenIq.parse(nodeRecv);
- emit ibbOpenIqReceived(ibbOpenIq);
- }
- // XEP-0054: vcard-temp
- else if(nodeRecv.firstChildElement("vCard").
- namespaceURI() == ns_vcard)
- {
- QXmppVCard vcardIq;
- vcardIq.parse(nodeRecv);
- emit vCardIqReceived(vcardIq);
- }
- // XEP-0065: SOCKS5 Bytestreams
- else if(QXmppByteStreamIq::isByteStreamIq(nodeRecv))
+ if (discoIq.type() == QXmppIq::Get &&
+ discoIq.queryType() == QXmppDiscoveryIq::InfoQuery &&
+ (discoIq.queryNode().isEmpty() || discoIq.queryNode().startsWith(capabilitiesNode)))
{
- QXmppByteStreamIq byteStreamIq;
- byteStreamIq.parse(nodeRecv);
- emit byteStreamIqReceived(byteStreamIq);
+ // respond to info query
+ QXmppDiscoveryIq qxmppFeatures = capabilities();
+ qxmppFeatures.setId(discoIq.id());
+ qxmppFeatures.setTo(discoIq.from());
+ qxmppFeatures.setQueryNode(discoIq.queryNode());
+ sendPacket(qxmppFeatures);
+ } else {
+ emit discoveryIqReceived(discoIq);
}
- // XEP-0078: Non-SASL Authentication
- else if(id == d->nonSASLAuthId && type == "result")
- {
- // successful Non-SASL Authentication
- debug("Authenticated (Non-SASL)");
+ }
+ // XEP-0045: Multi-User Chat
+ else if (QXmppMucAdminIq::isMucAdminIq(nodeRecv))
+ {
+ QXmppMucAdminIq mucIq;
+ mucIq.parse(nodeRecv);
+ emit mucAdminIqReceived(mucIq);
+ }
+ else if (QXmppMucOwnerIq::isMucOwnerIq(nodeRecv))
+ {
+ QXmppMucOwnerIq mucIq;
+ mucIq.parse(nodeRecv);
+ emit mucOwnerIqReceived(mucIq);
+ }
+ // XEP-0047 In-Band Bytestreams
+ else if(QXmppIbbCloseIq::isIbbCloseIq(nodeRecv))
+ {
+ QXmppIbbCloseIq ibbCloseIq;
+ ibbCloseIq.parse(nodeRecv);
+ emit ibbCloseIqReceived(ibbCloseIq);
+ }
+ else if(QXmppIbbDataIq::isIbbDataIq(nodeRecv))
+ {
+ QXmppIbbDataIq ibbDataIq;
+ ibbDataIq.parse(nodeRecv);
+ emit ibbDataIqReceived(ibbDataIq);
+ }
+ else if(QXmppIbbOpenIq::isIbbOpenIq(nodeRecv))
+ {
+ QXmppIbbOpenIq ibbOpenIq;
+ ibbOpenIq.parse(nodeRecv);
+ emit ibbOpenIqReceived(ibbOpenIq);
+ }
+ // XEP-0054: vcard-temp
+ else if(nodeRecv.firstChildElement("vCard").
+ namespaceURI() == ns_vcard)
+ {
+ QXmppVCard vcardIq;
+ vcardIq.parse(nodeRecv);
+ emit vCardIqReceived(vcardIq);
+ }
+ // XEP-0065: SOCKS5 Bytestreams
+ else if(QXmppByteStreamIq::isByteStreamIq(nodeRecv))
+ {
+ QXmppByteStreamIq byteStreamIq;
+ byteStreamIq.parse(nodeRecv);
+ emit byteStreamIqReceived(byteStreamIq);
+ }
+ // XEP-0078: Non-SASL Authentication
+ else if(id == d->nonSASLAuthId && type == "result")
+ {
+ // successful Non-SASL Authentication
+ debug("Authenticated (Non-SASL)");
- // xmpp connection made
- emit xmppConnected();
- }
- else if(nodeRecv.firstChildElement("query").
- namespaceURI() == ns_auth)
+ // xmpp connection made
+ emit xmppConnected();
+ }
+ else if(nodeRecv.firstChildElement("query").
+ namespaceURI() == ns_auth)
+ {
+ if(type == "result")
{
- if(type == "result")
- {
- bool digest = !nodeRecv.firstChildElement("query").
- firstChildElement("digest").isNull();
- bool plain = !nodeRecv.firstChildElement("query").
- firstChildElement("password").isNull();
- bool plainText = false;
+ bool digest = !nodeRecv.firstChildElement("query").
+ firstChildElement("digest").isNull();
+ bool plain = !nodeRecv.firstChildElement("query").
+ firstChildElement("password").isNull();
+ bool plainText = false;
- if(plain && digest)
- {
- if(configuration().nonSASLAuthMechanism() ==
- QXmppConfiguration::NonSASLDigest)
- plainText = false;
- else
- plainText = true;
- }
- else if(plain)
- plainText = true;
- else if(digest)
+ if(plain && digest)
+ {
+ if(configuration().nonSASLAuthMechanism() ==
+ QXmppConfiguration::NonSASLDigest)
plainText = false;
else
- {
- //TODO Login error
- return;
- }
- sendNonSASLAuth(plainText);
+ plainText = true;
}
- }
- // XEP-0092: Software Version
- else if(QXmppVersionIq::isVersionIq(nodeRecv))
- {
- QXmppVersionIq versionIq;
- versionIq.parse(nodeRecv);
-
- if (versionIq.type() == QXmppIq::Get)
+ else if(plain)
+ plainText = true;
+ else if(digest)
+ plainText = false;
+ else
{
- // respond to query
- QXmppVersionIq responseIq;
- responseIq.setType(QXmppIq::Result);
- responseIq.setId(versionIq.id());
- responseIq.setTo(versionIq.from());
- responseIq.setName(qApp->applicationName());
- responseIq.setVersion(qApp->applicationVersion());
- sendPacket(responseIq);
- } else {
- emit iqReceived(versionIq);
+ //TODO Login error
+ return;
}
-
- }
- // XEP-0095: Stream Initiation
- else if(QXmppStreamInitiationIq::isStreamInitiationIq(nodeRecv))
- {
- QXmppStreamInitiationIq siIq;
- siIq.parse(nodeRecv);
- emit streamInitiationIqReceived(siIq);
+ sendNonSASLAuth(plainText);
}
- // XEP-0136: Message Archiving
- else if(QXmppArchiveChatIq::isArchiveChatIq(nodeRecv))
- {
- QXmppArchiveChatIq archiveIq;
- archiveIq.parse(nodeRecv);
- emit archiveChatIqReceived(archiveIq);
- }
- else if(QXmppArchiveListIq::isArchiveListIq(nodeRecv))
- {
- QXmppArchiveListIq archiveIq;
- archiveIq.parse(nodeRecv);
- emit archiveListIqReceived(archiveIq);
- }
- else if(QXmppArchivePrefIq::isArchivePrefIq(nodeRecv))
- {
- QXmppArchivePrefIq archiveIq;
- archiveIq.parse(nodeRecv);
- emit archivePrefIqReceived(archiveIq);
- }
- // XEP-0166: Jingle
- else if(QXmppJingleIq::isJingleIq(nodeRecv))
- {
- QXmppJingleIq jingleIq;
- jingleIq.parse(nodeRecv);
- emit jingleIqReceived(jingleIq);
- }
- // XEP-0199: XMPP Ping
- else if(QXmppPingIq::isPingIq(nodeRecv))
- {
- QXmppPingIq req;
- req.parse(nodeRecv);
+ }
+ // XEP-0092: Software Version
+ else if(QXmppVersionIq::isVersionIq(nodeRecv))
+ {
+ QXmppVersionIq versionIq;
+ versionIq.parse(nodeRecv);
- QXmppIq iq(QXmppIq::Result);
- iq.setId(req.id());
- iq.setTo(req.from());
- iq.setFrom(req.to());
- sendPacket(iq);
- }
- else
+ if (versionIq.type() == QXmppIq::Get)
{
- QXmppIq iqPacket;
- iqPacket.parse(nodeRecv);
-
- // if we didn't understant the iq, reply with error
- // except for "result" and "error" iqs
- if (type != "result" && type != "error")
- {
- QXmppIq iq(QXmppIq::Error);
- iq.setId(iqPacket.id());
- iq.setTo(iqPacket.from());
- iq.setFrom(iqPacket.to());
- QXmppStanza::Error error(QXmppStanza::Error::Cancel,
- QXmppStanza::Error::FeatureNotImplemented);
- iq.setError(error);
- sendPacket(iq);
- } else {
- emit iqReceived(iqPacket);
- }
+ // respond to query
+ QXmppVersionIq responseIq;
+ responseIq.setType(QXmppIq::Result);
+ responseIq.setId(versionIq.id());
+ responseIq.setTo(versionIq.from());
+ responseIq.setName(qApp->applicationName());
+ responseIq.setVersion(qApp->applicationVersion());
+ sendPacket(responseIq);
+ } else {
+ emit iqReceived(versionIq);
}
+
}
- else if(nodeRecv.tagName() == "presence")
+ // XEP-0095: Stream Initiation
+ else if(QXmppStreamInitiationIq::isStreamInitiationIq(nodeRecv))
{
- QXmppPresence presence;
- presence.parse(nodeRecv);
-
- // emit presence
- emit presenceReceived(presence);
+ QXmppStreamInitiationIq siIq;
+ siIq.parse(nodeRecv);
+ emit streamInitiationIqReceived(siIq);
+ }
+ // XEP-0136: Message Archiving
+ else if(QXmppArchiveChatIq::isArchiveChatIq(nodeRecv))
+ {
+ QXmppArchiveChatIq archiveIq;
+ archiveIq.parse(nodeRecv);
+ emit archiveChatIqReceived(archiveIq);
+ }
+ else if(QXmppArchiveListIq::isArchiveListIq(nodeRecv))
+ {
+ QXmppArchiveListIq archiveIq;
+ archiveIq.parse(nodeRecv);
+ emit archiveListIqReceived(archiveIq);
+ }
+ else if(QXmppArchivePrefIq::isArchivePrefIq(nodeRecv))
+ {
+ QXmppArchivePrefIq archiveIq;
+ archiveIq.parse(nodeRecv);
+ emit archivePrefIqReceived(archiveIq);
+ }
+ // XEP-0166: Jingle
+ else if(QXmppJingleIq::isJingleIq(nodeRecv))
+ {
+ QXmppJingleIq jingleIq;
+ jingleIq.parse(nodeRecv);
+ emit jingleIqReceived(jingleIq);
}
- else if(nodeRecv.tagName() == "message")
+ // XEP-0199: XMPP Ping
+ else if(QXmppPingIq::isPingIq(nodeRecv))
{
- QXmppMessage message;
- message.parse(nodeRecv);
+ QXmppPingIq req;
+ req.parse(nodeRecv);
+
+ QXmppIq iq(QXmppIq::Result);
+ iq.setId(req.id());
+ iq.setTo(req.from());
+ iq.setFrom(req.to());
+ sendPacket(iq);
+ }
+ else
+ {
+ QXmppIq iqPacket;
+ iqPacket.parse(nodeRecv);
- // emit message
- emit messageReceived(message);
+ // if we didn't understant the iq, reply with error
+ // except for "result" and "error" iqs
+ if (type != "result" && type != "error")
+ {
+ QXmppIq iq(QXmppIq::Error);
+ iq.setId(iqPacket.id());
+ iq.setTo(iqPacket.from());
+ iq.setFrom(iqPacket.to());
+ QXmppStanza::Error error(QXmppStanza::Error::Cancel,
+ QXmppStanza::Error::FeatureNotImplemented);
+ iq.setError(error);
+ sendPacket(iq);
+ } else {
+ emit iqReceived(iqPacket);
+ }
}
}
- nodeRecv = nodeRecv.nextSiblingElement();
+ else if(nodeRecv.tagName() == "presence")
+ {
+ QXmppPresence presence;
+ presence.parse(nodeRecv);
+
+ // emit presence
+ emit presenceReceived(presence);
+ }
+ else if(nodeRecv.tagName() == "message")
+ {
+ QXmppMessage message;
+ message.parse(nodeRecv);
+
+ // emit message
+ emit messageReceived(message);
+ }
}
- }
- else
- {
- //wait for complete packet
+ nodeRecv = nodeRecv.nextSiblingElement();
}
}
@@ -818,22 +817,6 @@ bool QXmppStream::sendToServer(const QByteArray& packet)
return d->socket.write( packet ) == packet.size();
}
-bool QXmppStream::hasStartStreamElement(const QByteArray& data)
-{
- QString str(data);
- QRegExp regex("^(<\\?xml.*\\?>)?\\s*<stream:stream.*>");
- regex.setMinimal(true);
- return str.contains(regex);
-}
-
-bool QXmppStream::hasEndStreamElement(const QByteArray& data)
-{
- QString str(data);
- QRegExp regex("</stream:stream>$");
- regex.setMinimal(true);
- return str.contains(regex);
-}
-
void QXmppStream::sendNonSASLAuth(bool plainText)
{
QXmppNonSASLAuthIq authQuery;