From e33358e61f4286a7195e0057f74e783d5d47b1a6 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Mon, 8 Oct 2012 10:51:27 +0200 Subject: [PATCH] Do not join rooms before we're connected to legacy network. Otherwise join requests are lost --- include/transport/factory.h | 2 +- include/transport/user.h | 1 + src/networkpluginserver.cpp | 10 ++-------- src/tests/basictest.h | 4 ++-- src/tests/user.cpp | 38 +++++++++++++++++++++++++++++++++++++ src/user.cpp | 22 +++++++++++++++++++++ 6 files changed, 66 insertions(+), 11 deletions(-) diff --git a/include/transport/factory.h b/include/transport/factory.h index 85b7f37a..0c4595d7 100644 --- a/include/transport/factory.h +++ b/include/transport/factory.h @@ -40,7 +40,7 @@ class RosterManager; class Factory { public: - virtual Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) = 0; + virtual Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMuc = false) = 0; virtual Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) = 0; }; diff --git a/include/transport/user.h b/include/transport/user.h index 11c253b0..e89ba70b 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -142,6 +142,7 @@ class User : public Swift::EntityCapsProvider { std::vector > m_filetransfers; int m_resources; int m_reconnectCounter; + std::vector m_joinedRooms; }; } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 6855c36d..8b8f8cbc 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -92,8 +92,8 @@ class NetworkFactory : public Factory { virtual ~NetworkFactory() {} // Creates new conversation (NetworkConversation in this case) - Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) { - NetworkConversation *nc = new NetworkConversation(conversationManager, legacyName); + Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMuc) { + NetworkConversation *nc = new NetworkConversation(conversationManager, legacyName, isMuc); nc->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, m_nps, _1, _2)); return nc; } @@ -1191,12 +1191,6 @@ void NetworkPluginServer::handleRoomJoined(User *user, const Swift::JID &who, co return; } send(c->connection, message); - - NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true); - user->getConversationManager()->addConversation(conv); - conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2)); - conv->setNickname(nickname); - conv->addJID(who); } void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) { diff --git a/src/tests/basictest.h b/src/tests/basictest.h index 554ab5b6..1d270b20 100644 --- a/src/tests/basictest.h +++ b/src/tests/basictest.h @@ -67,8 +67,8 @@ class TestingFactory : public Factory { } // Creates new conversation (NetworkConversation in this case) - Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) { - TestingConversation *nc = new TestingConversation(conversationManager, legacyName); + Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMuc = false) { + TestingConversation *nc = new TestingConversation(conversationManager, legacyName, isMuc); nc->onMessageToSend.connect(boost::bind(&TestingFactory::handleMessageToSend, this, _1, _2)); return nc; } diff --git a/src/tests/user.cpp b/src/tests/user.cpp index bbafedbb..84914b6e 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -30,6 +30,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST(handlePresenceLeaveRoomTwoResources); CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesOneDisconnects); CPPUNIT_TEST(leaveJoinedRoom); + CPPUNIT_TEST(joinRoomBeforeConnected); CPPUNIT_TEST(handleDisconnected); CPPUNIT_TEST(handleDisconnectedReconnect); CPPUNIT_TEST_SUITE_END(); @@ -320,6 +321,43 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT(readyToConnect); } + void joinRoomBeforeConnected() { + User *user = userManager->getUser("user@localhost"); + user->setConnected(false); + + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("#room@localhost/hanzz"); + response->setFrom("user@localhost/resource"); + + Swift::MUCPayload *payload = new Swift::MUCPayload(); + payload->setPassword("password"); + response->addPayload(boost::shared_ptr(payload)); + injectPresence(response); + loop->processEvents(); + + // no presence received in server mode, just disco#info + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + + CPPUNIT_ASSERT_EQUAL(std::string(""), room); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); + + user->setConnected(true); + CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); + + room = ""; + roomNickname = ""; + roomPassword = ""; + + user->setConnected(true); + CPPUNIT_ASSERT_EQUAL(std::string(""), room); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION (UserTest); diff --git a/src/user.cpp b/src/user.cpp index f791b992..cf0b2f1c 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -176,6 +176,13 @@ void User::setConnected(bool connected) { updateLastActivity(); sendCurrentPresence(); + + if (m_connected) { + BOOST_FOREACH(Swift::Presence::ref &presence, m_joinedRooms) { + handlePresence(presence); + } + m_joinedRooms.clear(); + } } void User::handlePresence(Swift::Presence::ref presence) { @@ -241,7 +248,16 @@ void User::handlePresence(Swift::Presence::ref presence) { m_readyForConnect = true; onReadyToConnect(); } + std::string room = Buddy::JIDToLegacyName(presence->getTo()); + + if (!m_connected) { + LOG4CXX_INFO(logger, m_jid.toString() << ": Joining room " << room << " postponed, because use is not connected to legacy network yet."); + m_joinedRooms.push_back(presence); + return; + } + + Conversation *conv = m_conversationManager->getConversation(room); if (conv != NULL) { if (std::find(conv->getJIDs().begin(), conv->getJIDs().end(), presence->getFrom()) != conv->getJIDs().end()) { @@ -259,6 +275,12 @@ void User::handlePresence(Swift::Presence::ref presence) { if (presence->getPayload() != NULL) { password = presence->getPayload()->getPassword() ? *presence->getPayload()->getPassword() : ""; } + + conv = m_component->getFactory()->createConversation(m_conversationManager, room, true); + m_conversationManager->addConversation(conv); + conv->setNickname(presence->getTo().getResource()); + conv->addJID(presence->getFrom()); + onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password); } return;