Changeset - 4f9457bdd83a
[Not reviewed]
0 16 0
HanzZ - 13 years ago 2013-02-09 11:09:38
hanzz.k@gmail.com
Added testing swiften_raw backend which just changes to/from attributes and forwards unchanged stanzas
16 files changed with 307 insertions and 41 deletions:
0 comments (0 inline, 0 general)
backends/CMakeLists.txt
Show inline comments
 
if (PROTOBUF_FOUND)
 
	if (PURPLE_FOUND)
 
		ADD_SUBDIRECTORY(libpurple)
 
	endif()
 

	
 
	if (IRC_FOUND)
 
		ADD_SUBDIRECTORY(libcommuni)
 
	endif()
 

	
 
	if (ENABLE_SWIFTEN)
 
		ADD_SUBDIRECTORY(swiften)
 
		ADD_SUBDIRECTORY(swiften_raw)
 
	endif()
 

	
 
	ADD_SUBDIRECTORY(template)
 
	if(ENABLE_TWITTER)
 
		ADD_SUBDIRECTORY(twitter)
 
	endif()
 
	if (NOT WIN32)
 
		if(ENABLE_SMSTOOLS3)
 
			ADD_SUBDIRECTORY(smstools3)
 
		endif()
 
		if(ENABLE_FROTZ)
 
			ADD_SUBDIRECTORY(frotz)
include/transport/conversation.h
Show inline comments
 
@@ -61,24 +61,26 @@ class Conversation {
 

	
 
		/// Returns legacy network name of this conversation.
 

	
 
		/// \return legacy network name of this conversation.
 
		const std::string &getLegacyName() { return m_legacyName; }
 

	
 
		/// Handles new message from Legacy network and forwards it to XMPP.
 

	
 
		/// \param message Message received from legacy network.
 
		/// \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.
 
		/// \param flag ParticipantFlag.
 
		/// \param status Current status of this participant.
 
		/// \param statusMessage Current status message of this participant.
 
		/// \param newname If participant was renamed, this variable contains his new name.
 
		void handleParticipantChanged(const std::string &nickname, ParticipantFlag flag, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "");
 

	
 
		/// Sets XMPP user nickname in MUC rooms.
 

	
 
		/// \param nickname XMPP user nickname in MUC rooms.
include/transport/localbuddy.h
Show inline comments
 
@@ -56,17 +56,19 @@ class LocalBuddy : public Buddy {
 
		bool isValid() {
 
			std::string safeName = getSafeName();
 
			return m_jid.isValid() && safeName.find("/") == std::string::npos;
 
		}
 

	
 
	private:
 
		std::string m_name;
 
		std::string m_alias;
 
		std::vector<std::string> m_groups;
 
		std::string m_statusMessage;
 
		std::string m_iconHash;
 
		Swift::StatusShow m_status;
 

	
 
	friend class NetworkPluginServer;
 
};
 

	
 
}
 

	
 
#endif
include/transport/networkplugin.h
Show inline comments
 
@@ -30,52 +30,56 @@ namespace Transport {
 

	
 
/// Represents Spectrum2 legacy network plugin.
 

	
 
/// This class is base class for all C++ legacy network plugins. It provides a way to connect 
 
/// Spectrum2 NetworkPluginServer and allows to use high-level API for legacy network plugins
 
/// development.
 
class NetworkPlugin {
 
	public:
 
		enum ExitCode { StorageBackendNeeded = -2 };
 

	
 
		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;
 
		};
 

	
 
		/// Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer.
 
		/// \param loop Event loop.
 
		/// \param host Host where Spectrum2 NetworkPluginServer runs.
 
		/// \param port Port.
 
		NetworkPlugin();
 

	
 
		/// Destructor.
 
		virtual ~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")
 
		/// \param alias Alias of legacy network buddy. If empty, then it's not changed on XMPP side.
 
		/// \param groups Groups in which buddy currently is. If empty, then it's not changed on XMPP side.
 
		/// \param status Status of this buddy.
 
		/// \param statusMessage Status message of this buddy.
 
		/// \param iconHash MD5 hash of buddy icon. Empty if none buddy icon.
 
		/// \param blocked True if this buddy is blocked in privacy lists in legacy network.
 
		void handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias,
 
			const std::vector<std::string> &groups, pbnetwork::StatusType status, const std::string &statusMessage = "", const std::string &iconHash = "",
 
			bool blocked = false
 
@@ -236,24 +240,26 @@ class NetworkPlugin {
 
		virtual void handleBuddyBlockToggled(const std::string &/*user*/, const std::string &/*buddyName*/, bool /*blocked*/) {}
 

	
 
		virtual void handleTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}
 
		virtual void handleTypedRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}
 
		virtual void handleStoppedTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {}
 
		virtual void handleAttentionRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*message*/) {}
 

	
 
		virtual void handleFTStartRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*fileName*/, unsigned long size, unsigned long ftID) {}
 
		virtual void handleFTFinishRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*fileName*/, unsigned long size, unsigned long ftID) {}
 
		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); }
 
		void handleDataRead(std::string &data);
 
		virtual void sendData(const std::string &string) {}
 

	
 
		void checkPing();
 

	
 
	private:
 
		void handleLoginPayload(const std::string &payload);
 
		void handleLogoutPayload(const std::string &payload);
 
		void handleStatusChangedPayload(const std::string &payload);
include/transport/networkpluginserver.h
Show inline comments
 
@@ -19,44 +19,49 @@
 
 */
 

	
 
#pragma once
 

	
 
#include <time.h>
 
#include "Swiften/Presence/PresenceOracle.h"
 
#include "Swiften/Disco/EntityCapsManager.h"
 
#include "Swiften/Network/BoostConnectionServer.h"
 
#include "Swiften/Network/Connection.h"
 
#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"
 

	
 
namespace Transport {
 

	
 
class UserManager;
 
class User;
 
class Component;
 
class Buddy;
 
class LocalBuddy;
 
class Config;
 
class NetworkConversation;
 
class VCardResponder;
 
class RosterResponder;
 
class BlockResponder;
 
class DummyReadBytestream;
 
class AdminInterface;
 
class DiscoItemsResponder;
 

	
 
class NetworkPluginServer {
 
class NetworkPluginServer : Swift::XMPPParserClient {
 
	public:
 
		struct Backend {
 
			int pongReceived;
 
			std::list<User *> users;
 
			Swift::SafeByteArray data;
 
			boost::shared_ptr<Swift::Connection> connection;
 
			unsigned long res;
 
			unsigned long init_res;
 
			unsigned long shared;
 
			bool acceptUsers;
 
			bool longRun;
 
			bool willDie;
 
@@ -107,24 +112,25 @@ class NetworkPluginServer {
 
		void handleRoomChangedPayload(const std::string &payload);
 
		void handleVCardPayload(const std::string &payload);
 
		void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
 
		void handleAuthorizationPayload(const std::string &payload);
 
		void handleAttentionPayload(const std::string &payload);
 
		void handleStatsPayload(Backend *c, const std::string &payload);
 
		void handleFTStartPayload(const std::string &payload);
 
		void handleFTFinishPayload(const std::string &payload);
 
		void handleFTDataPayload(Backend *b, const std::string &payload);
 
		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);
 
		void handleRoomLeft(User *user, const std::string &room);
 
		void handleUserReadyToConnect(User *user);
 
		void handleUserPresenceChanged(User *user, Swift::Presence::ref presence);
 
		void handleUserDestroyed(User *user);
 

	
 
		void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
 
		void handleBuddyRemoved(Buddy *buddy);
 
		void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
 
		void handleUserBuddyAdded(User *user, Buddy *buddy);
 
@@ -140,37 +146,50 @@ class NetworkPluginServer {
 
		void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
 
		void handleFTDataNeeded(Backend *b, unsigned long ftid);
 

	
 
		void handlePIDTerminated(unsigned long pid);
 
	private:
 
		void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
 

	
 
		void pingTimeout();
 
		void sendPing(Backend *c);
 
		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;
 
		RosterResponder *m_rosterResponder;
 
		BlockResponder *m_blockResponder;
 
		Config *m_config;
 
		boost::shared_ptr<Swift::ConnectionServer> m_server;
 
		std::list<Backend *>  m_clients;
 
		std::vector<unsigned long> m_pids;
 
		Swift::Timer::ref m_pingTimer;
 
		Swift::Timer::ref m_collectTimer;
 
		Swift::Timer::ref m_loginTimer;
 
		Component *m_component;
 
		std::list<User *> m_waitingUsers;
 
		bool m_isNextLongRun;
 
		std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
 
		FileTransferManager *m_ftManager;
 
		std::vector<std::string> m_crashedBackends;
 
		AdminInterface *m_adminInterface;
 
		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;
 
};
 

	
 
}
include/transport/protocol.proto
Show inline comments
 
@@ -171,17 +171,18 @@ message WrapperMessage {
 
		TYPE_ATTENTION				= 22;
 
		TYPE_STATS					= 23;
 
		TYPE_FT_START				= 24;
 
		TYPE_FT_FINISH				= 25;
 
		TYPE_FT_DATA				= 26;
 
		TYPE_FT_PAUSE				= 27;
 
		TYPE_FT_CONTINUE			= 28;
 
		TYPE_EXIT					= 29;
 
		TYPE_BACKEND_CONFIG			= 30;
 
		TYPE_QUERY					= 31;
 
		TYPE_ROOM_LIST				= 32;
 
		TYPE_CONV_MESSAGE_ACK		= 33;
 
		TYPE_RAW_XML				= 34;
 
	}
 
	required Type type = 1;
 
	optional bytes payload = 2;
 
}
 
;
include/transport/transport.h
Show inline comments
 
@@ -21,47 +21,49 @@
 
#pragma once
 

	
 
#include <vector>
 
#include "Swiften/Server/Server.h"
 
#include "Swiften/Disco/GetDiscoInfoRequest.h"
 
#include "Swiften/Disco/EntityCapsManager.h"
 
#include "Swiften/Disco/CapsManager.h"
 
#include "Swiften/Disco/CapsMemoryStorage.h"
 
#include "Swiften/Network/BoostTimerFactory.h"
 
#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"
 
#include "transport/factory.h"
 
#include "transport/presenceoracle.h"
 
#include <Swiften/Network/BoostConnectionServer.h>
 

	
 
namespace Transport {
 
	class StorageBackend;
 
	class Factory;
 
	class UserRegistry;
 

	
 
	/// Represents one transport instance.
 

	
 
	/// It's used to connect the Jabber server and provides transaction layer
 
	/// between Jabber server and other classes.
 
	///
 
	/// 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.
 

	
 
			/// \param loop Main event loop.
 
			/// \param config Cofiguration; this class uses following Config values:
 
			/// 	- service.jid
 
			/// 	- service.password
 
			/// 	- service.server
 
			/// 	- service.port
 
			/// 	- service.server_mode
 
			/// \param factories Swift::NetworkFactories.
 
			/// \param factory Transport Abstract factory used to create basic transport structures.
 
@@ -142,48 +144,54 @@ namespace Transport {
 
			/// It's emitted only for presences addressed to transport itself
 
			/// (for example to="j2j.domain.tld") and for presences comming to
 
			/// MUC (for example to="#chat%irc.freenode.org@irc.domain.tld")
 
			/// \param presence Presence.
 
			boost::signal<void (Swift::Presence::ref presence)> onUserPresenceReceived;
 

	
 
			/// Component class asks the XMPP clients automatically for their capabilities.
 
			/// This signal is emitted when capabilities have been received or changed.
 
			/// \param jid JID of the client for which we received capabilities
 
			/// \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);
 
			void handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e);
 
			void handlePresence(Swift::Presence::ref presence);
 
			void handleDataRead(const Swift::SafeByteArray &data);
 
			void handleDataWritten(const Swift::SafeByteArray &data);
 

	
 
			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;
 
			Swift::Timer::ref m_reconnectTimer;
 
			Swift::EntityCapsManager *m_entityCapsManager;
 
			Swift::CapsManager *m_capsManager;
 
			Swift::CapsMemoryStorage *m_capsMemoryStorage;
 
			PresenceOracle *m_presenceOracle;
 
			Swift::StanzaChannel *m_stanzaChannel;
 
			Swift::IQRouter *m_iqRouter;
 
			
 
			Transport::UserRegistry *m_userRegistry;
 
			StorageBackend *m_storageBackend;
 
			int m_reconnectCount;
 
			Config* m_config;
 
			std::string m_protocol;
 
			Swift::JID m_jid;
 
			Factory *m_factory;
 
			Swift::EventLoop *m_loop;
 
			bool m_rawXML;
 

	
 
		friend class User;
 
		friend class UserRegistration;
 
		friend class NetworkPluginServer;
 
	};
 
}
include/transport/user.h
Show inline comments
 
@@ -124,24 +124,25 @@ class User : public Swift::EntityCapsProvider {
 
		const std::string &getUserSetting(const std::string &key) {
 
			return m_settings[key];
 
		}
 

	
 
		void setCacheMessages(bool cacheMessages);
 

	
 
		bool shouldCacheMessages() {
 
			return m_cacheMessages;
 
		}
 

	
 
		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;
 

	
 
	private:
 
		void onConnectingTimeout();
 

	
 
		Swift::JID m_jid;
 
		Component *m_component;
 
		RosterManager *m_rosterManager;
 
		UserManager *m_userManager;
 
		ConversationManager *m_conversationManager;
plugin/cpp/networkplugin.cpp
Show inline comments
 
@@ -64,36 +64,43 @@ NetworkPlugin::~NetworkPlugin() {
 

	
 
void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
 
	std::string data = "[registration]\n";
 
	data += std::string("needPassword=") + (cfg.m_needPassword ? "1" : "0") + "\n";
 
	data += std::string("needRegistration=") + (cfg.m_needRegistration ? "1" : "0") + "\n";
 

	
 
	for (std::vector<std::string>::const_iterator it = cfg.m_extraFields.begin(); it != cfg.m_extraFields.end(); it++) {
 
		data += std::string("extraField=") + (*it) + "\n";
 
	}
 

	
 
	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);
 

	
 
	std::string message;
 
	m.SerializeToString(&message);
 

	
 
	WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BACKEND_CONFIG);
 

	
 
	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);
 
	m.set_buddyname(legacyName);
 
	m.set_message(msg);
 
	m.set_nickname(nickname);
 
	m.set_xhtml(xhtml);
 
	m.set_timestamp(timestamp);
 
	m.set_headline(headline);
 
	m.set_pm(pm);
 

	
 
	std::string message;
 
@@ -638,24 +645,27 @@ void NetworkPlugin::handleDataRead(std::string &data) {
 
			case pbnetwork::WrapperMessage_Type_TYPE_FT_FINISH:
 
				handleFTFinishPayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_FT_PAUSE:
 
				handleFTPausePayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_FT_CONTINUE:
 
				handleFTContinuePayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_EXIT:
 
				handleExitRequest();
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_RAW_XML:
 
				handleRawXML(wrapper.payload());
 
				break;
 
			default:
 
				return;
 
		}
 
	}
 
}
 

	
 
void NetworkPlugin::send(const std::string &data) {
 
	uint32_t size = htonl(data.size());
 
	char *header = (char *) &size;
 
	sendData(std::string(header, 4) + data);
 
}
 

	
src/buddy.cpp
Show inline comments
 
@@ -94,33 +94,37 @@ Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new)
 
	std::string name = getSafeName();
 

	
 
	Swift::StatusShow s;
 
	std::string statusMessage;
 
	if (!getStatus(s, statusMessage))
 
		return Swift::Presence::ref();
 

	
 
	if (m_jid.getNode().empty()) {
 
		generateJID();
 
	}
 

	
 
	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) {
 
		// caps
 
		
 
		presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::CapsInfo(m_rosterManager->getUser()->getUserManager()->getDiscoResponder()->getBuddyCapsInfo())));
 

	
 
// 		if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) {
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::VCardUpdate (getIconHash())));
 
// 		}
 
		if (isBlocked()) {
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Transport::BlockPayload ()));
src/config.cpp
Show inline comments
 
@@ -306,24 +306,25 @@ std::string Config::getCommandLineArgs() const {
 

	
 
	return commandLineArgs.str();
 
}
 

	
 
void Config::updateBackendConfig(const std::string &backendConfig) {
 
	options_description opts("Backend options");
 
	opts.add_options()
 
		("registration.needPassword", value<bool>()->default_value(true), "")
 
		("registration.needRegistration", value<bool>()->default_value(false), "")
 
		("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);
 
	parsed_options parsed = parse_config_file(ifs, opts, true);
 

	
 
	store(parsed, m_backendConfig);
 
	notify(m_backendConfig);
 

	
 
	onBackendConfigUpdated();
 
}
 

	
 
Config *Config::createFromArgs(int argc, char **argv, std::string &error, std::string &host, int &port) {
src/conversation.cpp
Show inline comments
 
@@ -30,24 +30,28 @@
 
#include "Swiften/Elements/MUCOccupant.h"
 
#include "Swiften/Elements/MUCUserPayload.h"
 
#include "Swiften/Elements/Delay.h"
 
#include "Swiften/Elements/MUCPayload.h"
 

	
 
namespace Transport {
 

	
 
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
 
	m_legacyName = legacyName;
 
	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() {
 
}
 

	
 
void Conversation::destroyRoom() {
 
	if (m_muc) {
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		std::string legacyName = m_legacyName;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
@@ -73,24 +77,65 @@ void Conversation::destroyRoom() {
 
		BOOST_FOREACH(const Swift::JID &jid, m_jids) {
 
			presence->setTo(jid);
 
			m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
		}
 
	}
 
}
 

	
 
void Conversation::setRoom(const std::string &room) {
 
	m_room = 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);
 
	}
 
	else {
 
		if (message->getType() == Swift::Message::Headline) {
 
			if (m_conversationManager->getUser()->getUserSetting("send_headlines") != "1") {
 
				message->setType(Swift::Message::Chat);
 
			}
 
		}
 
		else {
 
			message->setType(Swift::Message::Chat);
 
@@ -128,74 +173,40 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
		else {
 
			if (m_room.empty()) {
 
				message->setFrom(Swift::JID(n, m_conversationManager->getComponent()->getJID().toBare(), "user"));
 
			}
 
			else {
 
				std::string legacyName = m_room;
 
				if (legacyName.find_last_of("@") != std::string::npos) {
 
					legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
				}
 
				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;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 

	
 
		std::string n = nickname;
 
		if (n.empty()) {
 
			n = " ";
 
		}
 

	
 
		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) {
 
	for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
 
		Swift::Presence::ref presence = generatePresence(it->first, it->second.flag, it->second.status, it->second.statusMessage, "");
 
		presence->setTo(to);
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
 
	}
 
}
 

	
 
void Conversation::sendCachedMessages(const Swift::JID &to) {
 
	for (std::list<boost::shared_ptr<Swift::Message> >::const_iterator it = m_cachedMessages.begin(); it != m_cachedMessages.end(); it++) {
src/networkpluginserver.cpp
Show inline comments
 
@@ -260,29 +260,34 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa
 
}
 

	
 
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder) {
 
	_server = this;
 
	m_ftManager = ftManager;
 
	m_userManager = userManager;
 
	m_config = config;
 
	m_component = component;
 
	m_isNextLongRun = false;
 
	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();
 

	
 
	m_loginTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(config, "service.login_delay") * 1000);
 
	m_loginTimer->onTick.connect(boost::bind(&NetworkPluginServer::loginDelayFinished, this));
 
	m_loginTimer->start();
 

	
 
	if (CONFIG_INT(m_config, "service.memory_collector_time") != 0) {
 
		m_collectTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(m_config, "service.memory_collector_time"));
 
		m_collectTimer->onTick.connect(boost::bind(&NetworkPluginServer::collectBackend, this));
 
		m_collectTimer->start();
 
@@ -978,24 +983,151 @@ void NetworkPluginServer::handleRoomListPayload(const std::string &data) {
 
	pbnetwork::RoomList payload;
 
	if (payload.ParseFromString(data) == false) {
 
		// TODO: ERROR
 
		return;
 
	}
 

	
 
	m_discoItemsResponder->clearRooms();
 
	for (int i = 0; i < payload.room_size() && i < payload.name_size(); i++) {
 
		m_discoItemsResponder->addRoom(Swift::JID::getEscapedNode(payload.room(i)) + "@" + m_component->getJID().toString(), payload.name(i));
 
	}
 
}
 

	
 
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());
 

	
 
	// Parse data while there are some
 
	while (c->data.size() != 0) {
 
		// expected_size of wrapper message
 
		unsigned int expected_size;
 

	
 
		// if data is >= 4, we have whole header and we can
 
		// read expected_size.
 
		if (c->data.size() >= 4) {
 
@@ -1089,24 +1221,27 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::Sa
 
			case pbnetwork::WrapperMessage_Type_TYPE_QUERY:
 
				handleQueryPayload(c, wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_BACKEND_CONFIG:
 
				handleBackendConfigPayload(wrapper.payload());
 
				break;
 
			case pbnetwork::WrapperMessage_Type_TYPE_ROOM_LIST:
 
				handleRoomListPayload(wrapper.payload());
 
				break;
 
			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;
 
		}
 
	}
 
}
 

	
 
void NetworkPluginServer::send(boost::shared_ptr<Swift::Connection> &c, const std::string &data) {
 
	// generate header - size of wrapper message
 
	uint32_t size = htonl(data.size());
 
	char *header = (char *) &size;
 

	
 
	// send header together with wrapper message
 
@@ -1258,24 +1393,25 @@ void NetworkPluginServer::handleUserCreated(User *user) {
 
		LOG4CXX_INFO(logger, "There is no backend to handle user " << user->getJID().toString() << ". Adding him to queue.");
 
		m_waitingUsers.push_back(user);
 
		return;
 
	}
 

	
 
	// Associate users with backend
 
	user->setData(c);
 
	c->users.push_back(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));
 

	
 
	user->getRosterManager()->onBuddyAdded.connect(boost::bind(&NetworkPluginServer::handleUserBuddyAdded, this, user, _1));
 
	user->getRosterManager()->onBuddyRemoved.connect(boost::bind(&NetworkPluginServer::handleUserBuddyRemoved, this, user, _1));
 
}
 

	
 
void NetworkPluginServer::handleUserReadyToConnect(User *user) {
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	pbnetwork::Login login;
 
	login.set_user(user->getJID().toBare());
 
@@ -1365,24 +1501,25 @@ void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
 
	if (!c) {
 
		return;
 
	}
 
	send(c->connection, message);
 
}
 

	
 
void NetworkPluginServer::handleUserDestroyed(User *user) {
 
	m_waitingUsers.remove(user);
 
	UserInfo userInfo = user->getUserInfo();
 

	
 
	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));
 

	
 
	user->getRosterManager()->onBuddyAdded.disconnect(boost::bind(&NetworkPluginServer::handleUserBuddyAdded, this, user, _1));
 
	user->getRosterManager()->onBuddyRemoved.disconnect(boost::bind(&NetworkPluginServer::handleUserBuddyRemoved, this, user, _1));
 

	
 
	pbnetwork::Logout logout;
 
	logout.set_user(user->getJID().toBare());
 
	logout.set_legacyname(userInfo.uin);
 

	
 
	std::string message;
 
	logout.SerializeToString(&message);
 
@@ -1397,24 +1534,43 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
 
	c->users.remove(user);
 

	
 
	// If backend should handle only one user, it must not accept another one before 
 
	// we kill it, so set up willDie to true
 
	if (c->users.size() == 0 && CONFIG_INT(m_config, "service.users_per_backend") == 1) {
 
		LOG4CXX_INFO(logger, "Backend " << c->id << " will die, because the last user disconnected");
 
		c->willDie = true;
 
	}
 
}
 

	
 
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;
 
		switch (statePayload->getChatState()) {
 
			case Swift::ChatState::Active:
 
				type = pbnetwork::WrapperMessage_Type_TYPE_BUDDY_STOPPED_TYPING;
 
				break;
 
			case Swift::ChatState::Composing:
 
				type = pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPING;
 
				break;
 
			case Swift::ChatState::Paused:
 
				type = pbnetwork::WrapperMessage_Type_TYPE_BUDDY_TYPED;
src/tests/networkpluginserver.cpp
Show inline comments
 
@@ -44,24 +44,25 @@ class Clock {
 
		double elapsedTime() const {
 
			return m_elapsedTime;
 
		}
 
};
 

	
 
class NetworkPluginServerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(NetworkPluginServerTest);
 
	CPPUNIT_TEST(handleBuddyChangedPayload);
 
	CPPUNIT_TEST(handleBuddyChangedPayloadNoEscaping);
 
	CPPUNIT_TEST(handleBuddyChangedPayloadUserContactInRoster);
 
	CPPUNIT_TEST(handleMessageHeadline);
 
	CPPUNIT_TEST(handleConvMessageAckPayload);
 
	CPPUNIT_TEST(handleRawXML);
 

	
 
	CPPUNIT_TEST(benchmarkHandleBuddyChangedPayload);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		NetworkPluginServer *serv;
 

	
 
		void setUp (void) {
 
			setMeUp();
 

	
 
			serv = new NetworkPluginServer(component, cfg, userManager, NULL, NULL);
 
			connectUser();
 
@@ -187,24 +188,35 @@ class NetworkPluginServerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 

	
 
			pbnetwork::Buddy buddy;
 
			buddy.set_username("user@localhost");
 
			buddy.set_buddyname("user");
 

	
 
			std::string message;
 
			buddy.SerializeToString(&message);
 

	
 
			serv->handleBuddyChangedPayload(message);
 
			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");
 

	
 
			pbnetwork::ConversationMessage m;
 
			m.set_username("user@localhost");
 
			m.set_buddyname("user");
 
			m.set_message("msg");
 
			m.set_nickname("");
 
			m.set_xhtml("");
 
			m.set_timestamp("");
 
			m.set_headline(true);
 

	
src/transport.cpp
Show inline comments
 
@@ -43,42 +43,47 @@
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
 
#include "transport/BlockParser.h"
 
#include "transport/BlockSerializer.h"
 
#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;
 

	
 
namespace Transport {
 
	
 
DEFINE_LOGGER(logger, "Component");
 
DEFINE_LOGGER(logger_xml, "Component.XML");
 

	
 
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
 
	m_component = NULL;
 
	m_userRegistry = NULL;
 
	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"));
 

	
 
	m_factories = factories;
 

	
 
	m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
 
	m_reconnectTimer->onTick.connect(bind(&Component::start, this)); 
 

	
 
	if (CONFIG_BOOL(m_config, "service.server_mode")) {
 
		LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
@@ -168,24 +173,48 @@ Component::~Component() {
 
	delete m_presenceOracle;
 
	delete m_entityCapsManager;
 
	delete m_capsManager;
 
	delete m_capsMemoryStorage;
 
	if (m_component)
 
		delete m_component;
 
	if (m_server) {
 
		m_server->stop();
 
		delete m_server;
 
	}
 
}
 

	
 
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;
 
}
 

	
 
Transport::PresenceOracle *Component::getPresenceOracle() {
 
	return m_presenceOracle;
 
}
 

	
 
void Component::start() {
 
	if (m_component && !m_component->isAvailable()) {
 
		LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
 
		if (CONFIG_INT(m_config, "service.port") == 5222) {
src/user.cpp
Show inline comments
 
@@ -234,24 +234,25 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
 
			if (conv) {
 
				conv->removeJID(presence->getFrom());
 
				if (!conv->getJIDs().empty()) {
 
					return;
 
				}
 
			}
 
			else {
 
				return;
 
			}
 

	
 
			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) {
 
					if (p->getTo() == presence->getTo()) {
 
						m_joinedRooms.remove(p);
 
						break;
 
					}
 
				}
 

	
 
				if (conv) {
 
					m_conversationManager->removeConversation(conv);
 
					delete conv;
 
@@ -275,24 +276,25 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
 
			Conversation *conv = m_conversationManager->getConversation(room);
 
			if (conv != NULL) {
 
				if (std::find(conv->getJIDs().begin(), conv->getJIDs().end(), presence->getFrom()) != conv->getJIDs().end()) {
 
					LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource());
 
				}
 
				else {
 
					conv->addJID(presence->getFrom());
 
					conv->sendParticipants(presence->getFrom());
 
					conv->sendCachedMessages(presence->getFrom());
 
				}
 

	
 
				if (forceJoin) {
 
					onRawPresenceReceived(presence);
 
					onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password);
 
				}
 
				return;
 
			}
 

	
 
			bool isInJoined = false;
 
			BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
 
				if (p->getTo() == presence->getTo()) {
 
					isInJoined = true;
 
				}
 
			}
 
			if (!isInJoined) {
 
@@ -302,24 +304,25 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
 
			if (!m_connected) {
 
				LOG4CXX_INFO(logger, m_jid.toString() << ": Joining room " << room << " postponed, because use is not connected to legacy network yet.");
 
				return;
 
			}
 

	
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << room << " as " << presence->getTo().getResource());
 

	
 
			conv = m_component->getFactory()->createConversation(m_conversationManager, room, true);
 
			m_conversationManager->addConversation(conv);
 
			conv->setNickname(presence->getTo().getResource());
 
			conv->addJID(presence->getFrom());
 

	
 
			onRawPresenceReceived(presence);
 
			onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password);
 
		}
 
		return;
 
	}
 

	
 
	int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size();
 

	
 
	m_conversationManager->resetResources();
 

	
 

	
 
	if (presence->getType() == Swift::Presence::Unavailable) {
 
		m_conversationManager->removeJID(presence->getFrom());
0 comments (0 inline, 0 general)