Added testing swiften_raw backend which just changes to/from attributes and forwards unchanged stanzas

This commit is contained in:
HanzZ 2013-02-09 11:09:38 +01:00
parent 0b87eda806
commit 4f9457bdd8
16 changed files with 307 additions and 41 deletions

View file

@ -9,6 +9,7 @@ if (PROTOBUF_FOUND)
if (ENABLE_SWIFTEN)
ADD_SUBDIRECTORY(swiften)
ADD_SUBDIRECTORY(swiften_raw)
endif()
ADD_SUBDIRECTORY(template)

View file

@ -70,6 +70,8 @@ class Conversation {
/// \param nickname For MUC conversation this is nickname of room participant who sent this message.
void handleMessage(boost::shared_ptr<Swift::Message> &message, const std::string &nickname = "");
void handleRawMessage(boost::shared_ptr<Swift::Message> &message);
/// Handles participant change in MUC.
/// \param nickname Nickname of participant which changed.

View file

@ -65,6 +65,8 @@ class LocalBuddy : public Buddy {
std::string m_statusMessage;
std::string m_iconHash;
Swift::StatusShow m_status;
friend class NetworkPluginServer;
};
}

View file

@ -39,18 +39,20 @@ class NetworkPlugin {
class PluginConfig {
public:
PluginConfig() : m_needPassword(true), m_needRegistration(false), m_supportMUC(false) {}
PluginConfig() : m_needPassword(true), m_needRegistration(false), m_supportMUC(false), m_rawXML(false) {}
virtual ~PluginConfig() {}
void setNeedRegistration(bool needRegistration = false) { m_needRegistration = needRegistration; }
void setNeedPassword(bool needPassword = true) { m_needPassword = needPassword; }
void setSupportMUC(bool supportMUC = true) { m_supportMUC = supportMUC; }
void setExtraFields(const std::vector<std::string> &fields) { m_extraFields = fields; }
void setRawXML(bool rawXML = false) { m_rawXML = rawXML; }
private:
bool m_needPassword;
bool m_needRegistration;
bool m_supportMUC;
bool m_rawXML;
std::vector<std::string> m_extraFields;
friend class NetworkPlugin;
@ -67,6 +69,8 @@ class NetworkPlugin {
void sendConfig(const PluginConfig &cfg);
void sendRawXML(std::string &xml);
/// Call this function when legacy network buddy changed.
/// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld")
/// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com")
@ -245,6 +249,8 @@ class NetworkPlugin {
virtual void handleFTPauseRequest(unsigned long ftID) {}
virtual void handleFTContinueRequest(unsigned long ftID) {}
virtual void handleRawXML(const std::string &xml) {}
virtual void handleMemoryUsage(double &res, double &shared) {res = 0; shared = 0;}
virtual void handleExitRequest() { exit(1); }

View file

@ -28,6 +28,11 @@
#include "Swiften/Elements/ChatState.h"
#include "Swiften/Elements/RosterItemPayload.h"
#include "Swiften/Elements/VCard.h"
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
#include "Swiften/Parser/XMPPParser.h"
#include "Swiften/Parser/XMPPParserClient.h"
#include "Swiften/Serializer/XMPPSerializer.h"
#include "storagebackend.h"
#include "transport/filetransfermanager.h"
@ -47,7 +52,7 @@ class DummyReadBytestream;
class AdminInterface;
class DiscoItemsResponder;
class NetworkPluginServer {
class NetworkPluginServer : Swift::XMPPParserClient {
public:
struct Backend {
int pongReceived;
@ -116,6 +121,7 @@ class NetworkPluginServer {
void handleQueryPayload(Backend *b, const std::string &payload);
void handleBackendConfigPayload(const std::string &payload);
void handleRoomListPayload(const std::string &payload);
void handleRawXML(const std::string &xml);
void handleUserCreated(User *user);
void handleRoomJoined(User *user, const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password);
@ -149,6 +155,14 @@ class NetworkPluginServer {
Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false);
void connectWaitingUsers();
void loginDelayFinished();
void handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq);
void handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence);
void handleStreamStart(const Swift::ProtocolHeader&) {}
void handleElement(boost::shared_ptr<Swift::Element> element);
void handleStreamEnd() {}
UserManager *m_userManager;
VCardResponder *m_vcardResponder;
@ -171,6 +185,11 @@ class NetworkPluginServer {
bool m_startingBackend;
DiscoItemsResponder *m_discoItemsResponder;
time_t m_lastLogin;
Swift::XMPPParser *m_xmppParser;
Swift::FullPayloadParserFactoryCollection m_collection;
Swift::XMPPSerializer *m_serializer;
Swift::FullPayloadSerializerCollection m_collection2;
std::map <std::string, std::string> m_id2resource;
};
}

View file

@ -180,6 +180,7 @@ message WrapperMessage {
TYPE_QUERY = 31;
TYPE_ROOM_LIST = 32;
TYPE_CONV_MESSAGE_ACK = 33;
TYPE_RAW_XML = 34;
}
required Type type = 1;
optional bytes payload = 2;

View file

@ -30,9 +30,11 @@
#include "Swiften/Network/BoostIOServiceThread.h"
#include "Swiften/Server/UserRegistry.h"
#include "Swiften/Base/SafeByteArray.h"
#include "Swiften/Queries/IQHandler.h"
#include "Swiften/Jingle/JingleSessionManager.h"
#include "Swiften/Component/ComponentError.h"
#include "Swiften/Component/Component.h"
#include "Swiften/Queries/IQHandler.h"
#include <boost/bind.hpp>
#include "transport/config.h"
@ -52,7 +54,7 @@ namespace Transport {
///
/// In server mode it represents Jabber server to which users can connect and use
/// it as transport.
class Component {
class Component : Swift::IQHandler {
public:
/// Creates new Component instance.
@ -151,6 +153,8 @@ namespace Transport {
/// \param info disco#info with response.
boost::signal<void (const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info)> onUserDiscoInfoReceived;
boost::signal<void (boost::shared_ptr<Swift::IQ>)> onRawIQReceived;
private:
void handleConnected();
void handleConnectionError(const Swift::ComponentError &error);
@ -162,6 +166,9 @@ namespace Transport {
void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
void handleCapsChanged(const Swift::JID& jid);
void handleBackendConfigChanged();
bool handleIQ(boost::shared_ptr<Swift::IQ>);
Swift::NetworkFactories *m_factories;
Swift::Component *m_component;
Swift::Server *m_server;
@ -181,6 +188,7 @@ namespace Transport {
Swift::JID m_jid;
Factory *m_factory;
Swift::EventLoop *m_loop;
bool m_rawXML;
friend class User;
friend class UserRegistration;

View file

@ -133,6 +133,7 @@ class User : public Swift::EntityCapsProvider {
boost::signal<void ()> onReadyToConnect;
boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
boost::signal<void (Swift::Presence::ref presence)> onRawPresenceReceived;
boost::signal<void (const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
boost::signal<void (const std::string &room)> onRoomLeft;
boost::signal<void ()> onDisconnected;

View file

@ -73,6 +73,7 @@ void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
data += "[features]\n";
data += std::string("muc=") + (cfg.m_supportMUC ? "1" : "0") + "\n";
data += std::string("rawxml=") + (cfg.m_rawXML ? "1" : "0") + "\n";
pbnetwork::BackendConfig m;
m.set_config(data);
@ -85,6 +86,12 @@ void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
send(message);
}
void NetworkPlugin::sendRawXML(std::string &xml) {
WRAP(xml, pbnetwork::WrapperMessage_Type_TYPE_RAW_XML);
send(xml);
}
void NetworkPlugin::handleMessage(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname, const std::string &xhtml, const std::string &timestamp, bool headline, bool pm) {
pbnetwork::ConversationMessage m;
m.set_username(user);
@ -647,6 +654,9 @@ void NetworkPlugin::handleDataRead(std::string &data) {
case pbnetwork::WrapperMessage_Type_TYPE_EXIT:
handleExitRequest();
break;
case pbnetwork::WrapperMessage_Type_TYPE_RAW_XML:
handleRawXML(wrapper.payload());
break;
default:
return;
}

View file

@ -103,15 +103,19 @@ Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new)
}
Swift::Presence::ref presence = Swift::Presence::create();
presence->setFrom(m_jid);
presence->setTo(m_rosterManager->getUser()->getJID().toBare());
presence->setType(Swift::Presence::Available);
if (!statusMessage.empty())
presence->setStatus(statusMessage);
if (s.getType() == Swift::StatusShow::None)
if (s.getType() == Swift::StatusShow::None) {
presence->setType(Swift::Presence::Unavailable);
presence->setFrom(Swift::JID(m_jid.getNode(), m_jid.getDomain()));
}
else {
presence->setFrom(m_jid);
}
presence->setShow(s.getType());
if (presence->getType() != Swift::Presence::Unavailable) {

View file

@ -315,6 +315,7 @@ void Config::updateBackendConfig(const std::string &backendConfig) {
("registration.extraField", value<std::vector<std::string> >()->multitoken(), "")
("features.receipts", value<bool>()->default_value(false), "")
("features.muc", value<bool>()->default_value(false), "")
("features.rawxml", value<bool>()->default_value(false), "")
;
std::stringstream ifs(backendConfig);

View file

@ -39,6 +39,10 @@ Conversation::Conversation(ConversationManager *conversationManager, const std::
m_muc = isMUC;
m_jid = m_conversationManager->getUser()->getJID().toBare();
m_sentInitialPresence = false;
if (CONFIG_BOOL_DEFAULTED(conversationManager->getComponent()->getConfig(), "features.rawxml", false)) {
m_sentInitialPresence = true;
}
}
Conversation::~Conversation() {
@ -82,6 +86,47 @@ void Conversation::setRoom(const std::string &room) {
m_legacyName = m_room + "/" + m_legacyName;
}
void Conversation::handleRawMessage(boost::shared_ptr<Swift::Message> &message) {
if (message->getType() != Swift::Message::Groupchat) {
if (m_conversationManager->getComponent()->inServerMode() && m_conversationManager->getUser()->shouldCacheMessages()) {
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
delay->setStamp(timestamp);
message->addPayload(delay);
m_cachedMessages.push_back(message);
if (m_cachedMessages.size() > 100) {
m_cachedMessages.pop_front();
}
}
else {
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
}
}
else {
if (m_jids.empty()) {
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
delay->setStamp(timestamp);
message->addPayload(delay);
m_cachedMessages.push_back(message);
if (m_cachedMessages.size() > 100) {
m_cachedMessages.pop_front();
}
}
else {
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
message->setTo(jid);
// Subject has to be sent after our own presence (the one with code 110)
if (!message->getSubject().empty() && m_sentInitialPresence == false) {
m_subject = message;
return;
}
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
}
}
}
}
void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, const std::string &nickname) {
if (m_muc) {
message->setType(Swift::Message::Groupchat);
@ -137,20 +182,6 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
}
}
if (m_conversationManager->getComponent()->inServerMode() && m_conversationManager->getUser()->shouldCacheMessages()) {
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
delay->setStamp(timestamp);
message->addPayload(delay);
m_cachedMessages.push_back(message);
if (m_cachedMessages.size() > 100) {
m_cachedMessages.pop_front();
}
}
else {
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
}
}
else {
std::string legacyName = m_legacyName;
@ -164,29 +195,9 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
}
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
if (m_jids.empty()) {
boost::posix_time::ptime timestamp = boost::posix_time::second_clock::universal_time();
boost::shared_ptr<Swift::Delay> delay(boost::make_shared<Swift::Delay>());
delay->setStamp(timestamp);
message->addPayload(delay);
m_cachedMessages.push_back(message);
if (m_cachedMessages.size() > 100) {
m_cachedMessages.pop_front();
}
}
else {
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
message->setTo(jid);
// Subject has to be sent after our own presence (the one with code 110)
if (!message->getSubject().empty() && m_sentInitialPresence == false) {
m_subject = message;
return;
}
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
}
}
}
handleRawMessage(message);
}
void Conversation::sendParticipants(const Swift::JID &to) {

View file

@ -269,11 +269,16 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
m_adminInterface = NULL;
m_startingBackend = false;
m_lastLogin = 0;
m_xmppParser = new Swift::XMPPParser(this, &m_collection, component->getNetworkFactories()->getXMLParserFactory());
m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
m_serializer = new Swift::XMPPSerializer(&m_collection2, Swift::ClientStreamType);
m_discoItemsResponder = discoItemsResponder;
m_component->m_factory = new NetworkFactory(this);
m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1));
m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1));
m_component->onRawIQReceived.connect(boost::bind(&NetworkPluginServer::handleRawIQReceived, this, _1));
m_pingTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(20000);
m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this));
m_pingTimer->start();
@ -987,6 +992,133 @@ void NetworkPluginServer::handleRoomListPayload(const std::string &data) {
}
}
void NetworkPluginServer::handleElement(boost::shared_ptr<Swift::Element> element) {
boost::shared_ptr<Swift::Stanza> stanza = boost::dynamic_pointer_cast<Swift::Stanza>(element);
if (!stanza) {
return;
}
User *user = m_userManager->getUser(stanza->getTo().toBare());
if (!user)
return;
Swift::JID originalJID = stanza->getFrom();
LocalBuddy *buddy = (LocalBuddy *) user->getRosterManager()->getBuddy(stanza->getFrom().toBare());
if (buddy) {
const Swift::JID &jid = buddy->getJID();
if (stanza->getFrom().getResource().empty()) {
stanza->setFrom(Swift::JID(jid.getNode(), jid.getDomain()));
}
else {
stanza->setFrom(Swift::JID(jid.getNode(), jid.getDomain(), stanza->getFrom().getResource()));
}
}
else {
std::string name = stanza->getFrom().toBare();
if (CONFIG_BOOL_DEFAULTED(m_config, "service.jid_escaping", true)) {
name = Swift::JID::getEscapedNode(name);
}
else {
if (name.find_last_of("@") != std::string::npos) {
name.replace(name.find_last_of("@"), 1, "%");
}
}
if (stanza->getFrom().getResource().empty()) {
stanza->setFrom(Swift::JID(name, m_component->getJID().toString()));
}
else {
stanza->setFrom(Swift::JID(name, m_component->getJID().toString(), stanza->getFrom().getResource()));
}
}
boost::shared_ptr<Swift::Message> message = boost::dynamic_pointer_cast<Swift::Message>(stanza);
if (message) {
NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(originalJID.toBare());
if (conv) {
conv->handleRawMessage(message);
return;
}
m_component->getStanzaChannel()->sendMessage(message);
return;
}
boost::shared_ptr<Swift::Presence> presence = boost::dynamic_pointer_cast<Swift::Presence>(stanza);
if (presence) {
m_component->getStanzaChannel()->sendPresence(presence);
if (buddy) {
buddy->m_statusMessage = presence->getStatus();
buddy->m_status = Swift::StatusShow(presence->getShow());
}
return;
}
boost::shared_ptr<Swift::IQ> iq = boost::dynamic_pointer_cast<Swift::IQ>(stanza);
if (iq) {
if (m_id2resource.find(stanza->getTo().toBare().toString() + stanza->getID()) != m_id2resource.end()) {
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), m_id2resource[stanza->getTo().toBare().toString() + stanza->getID()]));
m_id2resource.erase(stanza->getTo().toBare().toString() + stanza->getID());
}
m_component->getIQRouter()->sendIQ(iq);
return;
}
}
void NetworkPluginServer::handleRawXML(const std::string &xml) {
m_xmppParser->parse(xml);
}
void NetworkPluginServer::handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence) {
User *user = m_userManager->getUser(presence->getFrom().toBare());
if (!user)
return;
Backend *c = (Backend *) user->getData();
if (!c) {
return;
}
Swift::JID legacyname = Swift::JID(Buddy::JIDToLegacyName(presence->getTo()));
if (!presence->getTo().getResource().empty()) {
presence->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain(), presence->getTo().getResource()));
}
else {
presence->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain()));
}
std::string xml = safeByteArrayToString(m_serializer->serializeElement(presence));
WRAP(xml, pbnetwork::WrapperMessage_Type_TYPE_RAW_XML);
send(c->connection, xml);
}
void NetworkPluginServer::handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq) {
User *user = m_userManager->getUser(iq->getFrom().toBare());
if (!user)
return;
Backend *c = (Backend *) user->getData();
if (!c) {
return;
}
if (iq->getType() == Swift::IQ::Get) {
m_id2resource[iq->getFrom().toBare().toString() + iq->getID()] = iq->getFrom().getResource();
}
Swift::JID legacyname = Swift::JID(Buddy::JIDToLegacyName(iq->getTo()));
if (!iq->getTo().getResource().empty()) {
iq->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain(), iq->getTo().getResource()));
}
else {
iq->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain()));
}
std::string xml = safeByteArrayToString(m_serializer->serializeElement(iq));
WRAP(xml, pbnetwork::WrapperMessage_Type_TYPE_RAW_XML);
send(c->connection, xml);
}
void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::SafeByteArray> data) {
// Append data to buffer
c->data.insert(c->data.end(), data->begin(), data->end());
@ -1098,6 +1230,9 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::Sa
case pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE_ACK:
handleConvMessageAckPayload(wrapper.payload());
break;
case pbnetwork::WrapperMessage_Type_TYPE_RAW_XML:
handleRawXML(wrapper.payload());
break;
default:
return;
}
@ -1267,6 +1402,7 @@ void NetworkPluginServer::handleUserCreated(User *user) {
// Don't forget to disconnect these in handleUserDestroyed!!!
user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
user->onPresenceChanged.connect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1));
user->onRawPresenceReceived.connect(boost::bind(&NetworkPluginServer::handleRawPresenceReceived, this, _1));
user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3, _4));
user->onRoomLeft.connect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
@ -1374,6 +1510,7 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
user->onReadyToConnect.disconnect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user));
user->onPresenceChanged.disconnect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1));
user->onRawPresenceReceived.disconnect(boost::bind(&NetworkPluginServer::handleRawPresenceReceived, this, _1));
user->onRoomJoined.disconnect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3, _4));
user->onRoomLeft.disconnect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
@ -1406,6 +1543,25 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &msg) {
conv->getConversationManager()->getUser()->updateLastActivity();
if (CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
Backend *c = (Backend *) conv->getConversationManager()->getUser()->getData();
if (!c) {
return;
}
Swift::JID legacyname = Swift::JID(Buddy::JIDToLegacyName(msg->getTo()));
if (!msg->getTo().getResource().empty()) {
msg->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain(), msg->getTo().getResource()));
}
else {
msg->setTo(Swift::JID(legacyname.getNode(), legacyname.getDomain()));
}
std::string xml = safeByteArrayToString(m_serializer->serializeElement(msg));
WRAP(xml, pbnetwork::WrapperMessage_Type_TYPE_RAW_XML);
send(c->connection, xml);
return;
}
boost::shared_ptr<Swift::ChatState> statePayload = msg->getPayload<Swift::ChatState>();
if (statePayload) {
pbnetwork::WrapperMessage_Type type = pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED;

View file

@ -53,6 +53,7 @@ class NetworkPluginServerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_TEST(handleBuddyChangedPayloadUserContactInRoster);
CPPUNIT_TEST(handleMessageHeadline);
CPPUNIT_TEST(handleConvMessageAckPayload);
CPPUNIT_TEST(handleRawXML);
CPPUNIT_TEST(benchmarkHandleBuddyChangedPayload);
CPPUNIT_TEST_SUITE_END();
@ -196,6 +197,17 @@ class NetworkPluginServerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
}
void handleRawXML() {
User *user = userManager->getUser("user@localhost");
std::string xml = "<presence from='buddy1@domain.tld' to='user@localhost'/>";
serv->handleRawXML(xml);
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(std::string("buddy1\\40domain.tld@localhost"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
}
void handleMessageHeadline() {
User *user = userManager->getUser("user@localhost");

View file

@ -52,6 +52,9 @@
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
#include "Swiften/Parser/GenericPayloadParserFactory.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
using namespace Swift;
using namespace boost;
@ -67,9 +70,11 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
m_server = NULL;
m_reconnectCount = 0;
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&Component::handleBackendConfigChanged, this));
m_factory = factory;
m_loop = loop;
m_userRegistry = userRegistry;
m_rawXML = false;
m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
@ -177,6 +182,30 @@ Component::~Component() {
}
}
bool Component::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
if (!m_rawXML) {
return false;
}
if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
if (iq->getTo().getNode().empty()) {
return false;
}
onRawIQReceived(iq);
return true;
}
void Component::handleBackendConfigChanged() {
if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
m_rawXML = true;
m_iqRouter->addHandler(this);
}
}
Swift::StanzaChannel *Component::getStanzaChannel() {
return m_stanzaChannel;
}

View file

@ -243,6 +243,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
if (getUserSetting("stay_connected") != "1") {
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
onRawPresenceReceived(presence);
onRoomLeft(room);
BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
@ -284,6 +285,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
}
if (forceJoin) {
onRawPresenceReceived(presence);
onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password);
}
return;
@ -311,6 +313,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
conv->setNickname(presence->getTo().getResource());
conv->addJID(presence->getFrom());
onRawPresenceReceived(presence);
onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password);
}
return;