Do not send subscribe presence just because, but send it as response to probe presence

This commit is contained in:
Jan Kaluza 2012-11-02 09:50:03 +01:00
parent dc1cc4170e
commit 3aff761db6
4 changed files with 88 additions and 5 deletions

View file

@ -131,6 +131,7 @@ class UserManager : public Swift::EntityCapsProvider {
void handleMessageReceived(Swift::Message::ref message);
void handleGeneralPresenceReceived(Swift::Presence::ref presence);
void handleProbePresence(Swift::Presence::ref presence);
void handleErrorPresence(Swift::Presence::ref presence);
void handleSubscription(Swift::Presence::ref presence);
void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
void handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info);

View file

@ -72,6 +72,11 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
}
void handleProbePresence() {
UserInfo info;
info.id = 1;
info.jid = "user@localhost";
storage->setUser(info);
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("localhost");
response->setFrom("user@localhost/resource");
@ -88,8 +93,44 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
presence = dynamic_cast<Swift::Presence *>(getStanza(received[2]));
CPPUNIT_ASSERT(presence);
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Probe, presence->getType());
received.clear();
response = Swift::Presence::create();
response->setTo("localhost");
response->setFrom("user@localhost");
response->setType(Swift::Presence::Unsubscribed);
dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
presence = dynamic_cast<Swift::Presence *>(getStanza(received[1]));
CPPUNIT_ASSERT(presence);
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribe, presence->getType());
received.clear();
response = Swift::Presence::create();
response->setTo("localhost");
response->setFrom("user@localhost");
response->setType(Swift::Presence::Error);
dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
presence = dynamic_cast<Swift::Presence *>(getStanza(received[0]));
CPPUNIT_ASSERT(presence);
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribe, presence->getType());
storage->removeUser(1);
received.clear();
response = Swift::Presence::create();
response->setTo("localhost");
response->setFrom("user@localhost");
response->setType(Swift::Presence::Unsubscribed);
dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
}
void connectTwoResources() {

View file

@ -281,9 +281,16 @@ void Component::handlePresence(Swift::Presence::ref presence) {
return;
}
if (presence->getType() == Presence::Error) {
return;
}
switch (presence->getType()) {
case Presence::Error:
case Presence::Subscribe:
case Presence::Subscribed:
case Presence::Unsubscribe:
case Presence::Unsubscribed:
return;
default:
break;
};
// check if we have this client's capabilities and ask for them
if (presence->getType() != Swift::Presence::Unavailable) {

View file

@ -195,13 +195,13 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
response->setType(Swift::Presence::Unavailable);
m_component->getStanzaChannel()->sendPresence(response);
// bother him with subscribe presence, just to be
// bother him with probe presence, just to be
// sure he is subscribed to us.
if (/*registered && */presence->getType() == Swift::Presence::Probe) {
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(presence->getFrom());
response->setFrom(presence->getTo());
response->setType(Swift::Presence::Subscribe);
response->setType(Swift::Presence::Probe);
m_component->getStanzaChannel()->sendPresence(response);
}
@ -382,6 +382,9 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) {
case Swift::Presence::Probe:
handleProbePresence(presence);
break;
case Swift::Presence::Error:
handleErrorPresence(presence);
break;
default:
break;
};
@ -407,7 +410,25 @@ void UserManager::handleProbePresence(Swift::Presence::ref presence) {
}
}
void UserManager::handleErrorPresence(Swift::Presence::ref presence) {
// Don't let RosterManager to handle presences for us
if (!presence->getTo().getNode().empty()) {
return;
}
std::string userkey = presence->getFrom().toBare().toString();
UserInfo res;
bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
if (registered) {
Swift::Presence::ref response = Swift::Presence::create();
response->setFrom(presence->getTo().toBare());
response->setTo(presence->getFrom().toBare());
response->setType(Swift::Presence::Subscribe);
m_component->getStanzaChannel()->sendPresence(response);
}
}
void UserManager::handleSubscription(Swift::Presence::ref presence) {
// answer to subscibe for transport itself
if (presence->getType() == Swift::Presence::Subscribe && presence->getTo().getNode().empty()) {
Swift::Presence::ref response = Swift::Presence::create();
@ -423,6 +444,19 @@ void UserManager::handleSubscription(Swift::Presence::ref presence) {
// m_component->getStanzaChannel()->sendPresence(response);
return;
}
else if (presence->getType() == Swift::Presence::Unsubscribed && presence->getTo().getNode().empty()) {
std::string userkey = presence->getFrom().toBare().toString();
UserInfo res;
bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
if (registered) {
Swift::Presence::ref response = Swift::Presence::create();
response->setFrom(presence->getTo().toBare());
response->setTo(presence->getFrom().toBare());
response->setType(Swift::Presence::Subscribe);
m_component->getStanzaChannel()->sendPresence(response);
}
return;
}
// Don't let RosterManager to handle presences for us
if (presence->getTo().getNode().empty()) {