diff --git a/include/Swiften/Server/ServerStanzaChannel.cpp b/include/Swiften/Server/ServerStanzaChannel.cpp index 9597cc1ca0a2503a20eb4e33f31b094f59ca1cf4..af7dc7529ace35dbe7622ca8efcdde1e9b8874ed 100644 --- a/include/Swiften/Server/ServerStanzaChannel.cpp +++ b/include/Swiften/Server/ServerStanzaChannel.cpp @@ -1,176 +1,179 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include "Swiften/Server/ServerStanzaChannel.h" -#include "Swiften/Base/Error.h" -#include - -#include - -namespace Swift { - -namespace { -// struct PriorityLessThan { -// bool operator()(const ServerSession* s1, const ServerSession* s2) const { -// return s1->getPriority() < s2->getPriority(); -// } -// }; - - struct HasJID { - HasJID(const JID& jid) : jid(jid) {} - bool operator()(const boost::shared_ptr session) const { - return session->getRemoteJID().equals(jid, JID::WithResource); - } - JID jid; - }; -} - -void ServerStanzaChannel::addSession(boost::shared_ptr session) { - sessions[session->getRemoteJID().toBare().toString()].push_back(session); - session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); - session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); - session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); -} - -void ServerStanzaChannel::removeSession(boost::shared_ptr session) { - session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); - session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); - session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); - std::list > &lst = sessions[session->getRemoteJID().toBare().toString()]; - lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end()); -} - -void ServerStanzaChannel::sendIQ(boost::shared_ptr iq) { - send(iq); -} - -void ServerStanzaChannel::sendMessage(boost::shared_ptr message) { - send(message); -} - -void ServerStanzaChannel::sendPresence(boost::shared_ptr presence) { - send(presence); -} - -void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr &session) { - if (safeByteArrayToString(data).find("") != std::string::npos) { - Swift::Presence::ref presence = Swift::Presence::create(); - presence->setFrom(session->getRemoteJID()); - presence->setType(Swift::Presence::Unavailable); - onPresenceReceived(presence); - } -} - -void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr element, bool last) { - std::vector > candidateSessions; - for (std::list >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) { - candidateSessions.push_back(*i); - } - - for (std::vector >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) { - removeSession(*i); - if (element) { - (*i)->sendElement(element); - } - - if (last && (*i)->getRemoteJID().isValid()) { - Swift::Presence::ref presence = Swift::Presence::create(); - presence->setFrom((*i)->getRemoteJID()); - presence->setType(Swift::Presence::Unavailable); - onPresenceReceived(presence); - } - - (*i)->finishSession(); -// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n"; - if (last) { - break; - } - } -} - -std::string ServerStanzaChannel::getNewIQID() { - return idGenerator.generateID(); -} - -void ServerStanzaChannel::send(boost::shared_ptr stanza) { - JID to = stanza->getTo(); - assert(to.isValid()); - - // For a full JID, first try to route to a session with the full JID - if (!to.isBare()) { - std::list >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to)); - if (i != sessions[stanza->getTo().toBare().toString()].end()) { - (*i)->sendElement(stanza); - return; - } - } - - // Look for candidate sessions - to = to.toBare(); - std::vector > candidateSessions; - for (std::list >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) { - if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) { - candidateSessions.push_back(*i); - (*i)->sendElement(stanza); - } - } - if (candidateSessions.empty()) { - return; - } - - // Find the session with the highest priority -// std::vector::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan()); -// (*i)->sendStanza(stanza); - return; -} - -void ServerStanzaChannel::handleSessionFinished(const boost::optional&, const boost::shared_ptr& session) { - removeSession(session); - -// if (!session->initiatedFinish()) { - Swift::Presence::ref presence = Swift::Presence::create(); - presence->setFrom(session->getRemoteJID()); - presence->setType(Swift::Presence::Unavailable); - onPresenceReceived(presence); -// } -} - -void ServerStanzaChannel::handleElement(boost::shared_ptr element, const boost::shared_ptr& session) { - boost::shared_ptr stanza = boost::dynamic_pointer_cast(element); - if (!stanza) { - return; - } - - stanza->setFrom(session->getRemoteJID()); - - if (!stanza->getFrom().isValid()) - return; - - - boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); - if (message) { - onMessageReceived(message); - return; - } - - boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); - if (presence) { - onPresenceReceived(presence); - return; - } - - boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); - if (iq) { - onIQReceived(iq); - return; - } -} - -void ServerStanzaChannel::handleSessionInitialized() { - onAvailableChanged(true); -} - -} +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Base/Error.h" +#include + +#include + +namespace Swift { + +namespace { +// struct PriorityLessThan { +// bool operator()(const ServerSession* s1, const ServerSession* s2) const { +// return s1->getPriority() < s2->getPriority(); +// } +// }; + + struct HasJID { + HasJID(const JID& jid) : jid(jid) {} + bool operator()(const boost::shared_ptr session) const { + return session->getRemoteJID().equals(jid, JID::WithResource); + } + JID jid; + }; +} + +void ServerStanzaChannel::addSession(boost::shared_ptr session) { + sessions[session->getRemoteJID().toBare().toString()].push_back(session); + session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); + session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); + session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); +} + +void ServerStanzaChannel::removeSession(boost::shared_ptr session) { + session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); + session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); + session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); + std::list > &lst = sessions[session->getRemoteJID().toBare().toString()]; + lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end()); +} + +void ServerStanzaChannel::sendIQ(boost::shared_ptr iq) { + send(iq); +} + +void ServerStanzaChannel::sendMessage(boost::shared_ptr message) { + send(message); +} + +void ServerStanzaChannel::sendPresence(boost::shared_ptr presence) { + send(presence); +} + +void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr &session) { + if (safeByteArrayToString(data).find("") != std::string::npos) { + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setFrom(session->getRemoteJID()); + presence->setType(Swift::Presence::Unavailable); + onPresenceReceived(presence); + } +} +#if HAVE_SWIFTEN_3 +void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr element, bool last) { +#else +void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr element, bool last) { +#endif + std::vector > candidateSessions; + for (std::list >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) { + candidateSessions.push_back(*i); + } + + for (std::vector >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) { + removeSession(*i); + if (element) { + (*i)->sendElement(element); + } + + if (last && (*i)->getRemoteJID().isValid()) { + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setFrom((*i)->getRemoteJID()); + presence->setType(Swift::Presence::Unavailable); + onPresenceReceived(presence); + } + + (*i)->finishSession(); +// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n"; + if (last) { + break; + } + } +} + +std::string ServerStanzaChannel::getNewIQID() { + return idGenerator.generateID(); +} + +void ServerStanzaChannel::send(boost::shared_ptr stanza) { + JID to = stanza->getTo(); + assert(to.isValid()); + + // For a full JID, first try to route to a session with the full JID + if (!to.isBare()) { + std::list >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to)); + if (i != sessions[stanza->getTo().toBare().toString()].end()) { + (*i)->sendElement(stanza); + return; + } + } + + // Look for candidate sessions + to = to.toBare(); + std::vector > candidateSessions; + for (std::list >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) { + if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) { + candidateSessions.push_back(*i); + (*i)->sendElement(stanza); + } + } + if (candidateSessions.empty()) { + return; + } + + // Find the session with the highest priority +// std::vector::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan()); +// (*i)->sendStanza(stanza); + return; +} + +void ServerStanzaChannel::handleSessionFinished(const boost::optional&, const boost::shared_ptr& session) { + removeSession(session); + +// if (!session->initiatedFinish()) { + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setFrom(session->getRemoteJID()); + presence->setType(Swift::Presence::Unavailable); + onPresenceReceived(presence); +// } +} + +void ServerStanzaChannel::handleElement(boost::shared_ptr element, const boost::shared_ptr& session) { + boost::shared_ptr stanza = boost::dynamic_pointer_cast(element); + if (!stanza) { + return; + } + + stanza->setFrom(session->getRemoteJID()); + + if (!stanza->getFrom().isValid()) + return; + + + boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); + if (message) { + onMessageReceived(message); + return; + } + + boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); + if (presence) { + onPresenceReceived(presence); + return; + } + + boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); + if (iq) { + onIQReceived(iq); + return; + } +} + +void ServerStanzaChannel::handleSessionInitialized() { + onAvailableChanged(true); +} + +}