Merge branch 'master' of github.com:hanzz/libtransport
This commit is contained in:
commit
a2ad0b2ee6
8 changed files with 520 additions and 0 deletions
69
include/transport/adhoccommand.h
Normal file
69
include/transport/adhoccommand.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class AdHocCommand {
|
||||
public:
|
||||
/// Creates new AdHocManager.
|
||||
|
||||
/// \param component Transport instance associated with this AdHocManager.
|
||||
AdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload) = 0;
|
||||
|
||||
const std::string &getId() {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void refreshLastActivity() {
|
||||
m_lastActivity = time(NULL);
|
||||
}
|
||||
|
||||
time_t getLastActivity() {
|
||||
return m_lastActivity;
|
||||
}
|
||||
|
||||
protected:
|
||||
Component *m_component;
|
||||
Swift::JID m_initiator;
|
||||
Swift::JID m_to;
|
||||
|
||||
private:
|
||||
std::string m_id;
|
||||
// This is used to remove AdHocCommand after long inactivity to prevent memory leaks
|
||||
// caused by users which disconnect before they finish the command.
|
||||
// AdHocManager uses this to garbage collect old AdHocCommands.
|
||||
time_t m_lastActivity;
|
||||
};
|
||||
|
||||
}
|
47
include/transport/adhoccommandfactory.h
Normal file
47
include/transport/adhoccommandfactory.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class AdHocCommandFactory {
|
||||
public:
|
||||
AdHocCommandFactory() {}
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocCommandFactory() {}
|
||||
|
||||
virtual AdHocCommand *createAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) = 0;
|
||||
|
||||
virtual std::string getNode() = 0;
|
||||
|
||||
virtual std::string getName() = 0;
|
||||
};
|
||||
|
||||
}
|
75
include/transport/adhocmanager.h
Normal file
75
include/transport/adhocmanager.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Conversation;
|
||||
class User;
|
||||
class Component;
|
||||
class DiscoItemsResponder;
|
||||
class AdHocCommandFactory;
|
||||
class AdHocCommand;
|
||||
|
||||
/// Listens for AdHoc commands and manages all AdHoc commands sessions
|
||||
class AdHocManager : public Swift::Responder<Swift::Command> {
|
||||
public:
|
||||
typedef std::map<std::string, AdHocCommand *> CommandsMap;
|
||||
typedef std::map<Swift::JID, CommandsMap> SessionsMap;
|
||||
/// Creates new AdHocManager.
|
||||
|
||||
/// \param component Transport instance associated with this AdHocManager.
|
||||
AdHocManager(Component *component, DiscoItemsResponder *discoItemsResponder);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~AdHocManager();
|
||||
|
||||
/// Starts handling AdHoc commands payloads.
|
||||
void start();
|
||||
|
||||
/// Stops handling AdHoc commands payloads and destroys all existing
|
||||
/// AdHoc commands sessions.
|
||||
void stop();
|
||||
|
||||
/// Adds factory to create new AdHoc commands sessions of particular type.
|
||||
void addAdHocCommand(AdHocCommandFactory *factory);
|
||||
|
||||
/// Remove sessions older than N seconds.
|
||||
void removeOldSessions();
|
||||
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload);
|
||||
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload);
|
||||
|
||||
Component *m_component;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
std::map<std::string, AdHocCommandFactory *> m_factories;
|
||||
SessionsMap m_sessions;
|
||||
Swift::Timer::ref m_collectTimer;
|
||||
};
|
||||
|
||||
}
|
63
include/transport/settingsadhoccommand.h
Normal file
63
include/transport/settingsadhoccommand.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
|
||||
class SettingsAdHocCommand : public AdHocCommand {
|
||||
public:
|
||||
SettingsAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~SettingsAdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
|
||||
};
|
||||
|
||||
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
|
||||
public:
|
||||
SettingsAdHocCommandFactory() {}
|
||||
virtual ~SettingsAdHocCommandFactory() {}
|
||||
|
||||
AdHocCommand *createAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
return new SettingsAdHocCommand(component, initiator, to);
|
||||
}
|
||||
|
||||
std::string getNode() {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return "Transport settings";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -15,6 +15,8 @@
|
|||
#include "transport/gatewayresponder.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/discoitemsresponder.h"
|
||||
#include "transport/adhocmanager.h"
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -317,6 +319,12 @@ int main(int argc, char **argv)
|
|||
DiscoItemsResponder discoItemsResponder(&transport);
|
||||
discoItemsResponder.start();
|
||||
|
||||
AdHocManager adhocmanager(&transport, &discoItemsResponder);
|
||||
adhocmanager.start();
|
||||
|
||||
SettingsAdHocCommandFactory settings;
|
||||
adhocmanager.addAdHocCommand(&settings);
|
||||
|
||||
eventLoop_ = &eventLoop;
|
||||
|
||||
eventLoop.run();
|
||||
|
|
48
src/adhoccommand.cpp
Normal file
48
src/adhoccommand.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "AdHocCommand");
|
||||
|
||||
AdHocCommand::AdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
m_component = component;
|
||||
m_initiator = initiator;
|
||||
m_to = to;
|
||||
|
||||
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
|
||||
for (int i = 0; i < 32; i++) {
|
||||
m_id += bucket[rand() % bucket.size()];
|
||||
}
|
||||
}
|
||||
|
||||
AdHocCommand::~AdHocCommand() {
|
||||
}
|
||||
|
||||
}
|
163
src/adhocmanager.cpp
Normal file
163
src/adhocmanager.cpp
Normal file
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/adhocmanager.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include "transport/discoitemsresponder.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "AdHocManager");
|
||||
|
||||
AdHocManager::AdHocManager(Component *component, DiscoItemsResponder *discoItemsResponder) : Swift::Responder<Swift::Command>(component->getIQRouter()){
|
||||
m_component = component;
|
||||
m_discoItemsResponder = discoItemsResponder;
|
||||
|
||||
m_collectTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(20);
|
||||
m_collectTimer->onTick.connect(boost::bind(&AdHocManager::removeOldSessions, this));
|
||||
m_collectTimer->start();
|
||||
}
|
||||
|
||||
AdHocManager::~AdHocManager() {
|
||||
m_collectTimer->stop();
|
||||
stop();
|
||||
}
|
||||
|
||||
void AdHocManager::start() {
|
||||
Swift::Responder<Swift::Command>::start();
|
||||
}
|
||||
|
||||
void AdHocManager::stop() {
|
||||
Swift::Responder<Swift::Command>::stop();
|
||||
|
||||
for (SessionsMap::iterator it = m_sessions.begin(); it != m_sessions.end(); it++) {
|
||||
std::vector<std::string> candidates;
|
||||
for (CommandsMap::iterator ct = it->second.begin(); ct != it->second.end(); ct++) {
|
||||
delete ct->second;
|
||||
}
|
||||
}
|
||||
|
||||
m_sessions.clear();
|
||||
}
|
||||
|
||||
void AdHocManager::addAdHocCommand(AdHocCommandFactory *factory) {
|
||||
if (m_factories.find(factory->getNode()) != m_factories.end()) {
|
||||
LOG4CXX_ERROR(logger, "Command with node " << factory->getNode() << " is already registered. Ignoring this attempt.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_factories[factory->getNode()] = factory;
|
||||
m_discoItemsResponder->addAdHocCommand(factory->getNode(), factory->getName());
|
||||
}
|
||||
|
||||
void AdHocManager::removeOldSessions() {
|
||||
unsigned long removedCommands = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::vector<std::string> toRemove;
|
||||
for (SessionsMap::iterator it = m_sessions.begin(); it != m_sessions.end(); it++) {
|
||||
std::vector<std::string> candidates;
|
||||
for (CommandsMap::iterator ct = it->second.begin(); ct != it->second.end(); ct++) {
|
||||
if (now - ct->second->getLastActivity() > 15*60) {
|
||||
candidates.push_back(it->first);
|
||||
delete ct->second;
|
||||
removedCommands++;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string &key, candidates) {
|
||||
it->second.erase(key);
|
||||
}
|
||||
|
||||
if (it->second.empty()) {
|
||||
toRemove.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string &key, toRemove) {
|
||||
m_sessions.erase(key);
|
||||
}
|
||||
|
||||
if (removedCommands > 0) {
|
||||
LOG4CXX_INFO(logger, "Removed " << removedCommands << " old commands sessions.");
|
||||
}
|
||||
}
|
||||
|
||||
bool AdHocManager::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdHocManager::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::Command> payload) {
|
||||
AdHocCommand *command = NULL;
|
||||
// Try to find AdHocCommand according to 'from' and session_id
|
||||
if (m_sessions.find(from) != m_sessions.end() && m_sessions[from].find(payload->getSessionID()) != m_sessions[from].end()) {
|
||||
command = m_sessions[from][payload->getSessionID()];
|
||||
}
|
||||
// Check if we can create command with this node
|
||||
else if (m_factories.find(payload->getNode()) != m_factories.end()) {
|
||||
command = m_factories[payload->getNode()]->createAdHocCommand(m_component, from, to);
|
||||
m_sessions[from][command->getId()] = command;
|
||||
LOG4CXX_INFO(logger, from.toString() << ": Started new AdHoc command session with node " << payload->getNode());
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, from.toString() << ": Unknown node " << payload->getNode() << ". Can't start AdHoc command session.");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!command) {
|
||||
LOG4CXX_ERROR(logger, from.toString() << ": createAdHocCommand for node " << payload->getNode() << " returned NULL pointer");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response = command->handleRequest(payload);
|
||||
if (!response) {
|
||||
LOG4CXX_ERROR(logger, from.toString() << ": handleRequest for node " << payload->getNode() << " returned NULL pointer");
|
||||
sendError(from, id, Swift::ErrorPayload::BadRequest, Swift::ErrorPayload::Modify);
|
||||
return true;
|
||||
}
|
||||
|
||||
response->setSessionID(command->getId());
|
||||
|
||||
sendResponse(from, id, response);
|
||||
|
||||
command->refreshLastActivity();
|
||||
|
||||
// Command completed, so we can remove it now
|
||||
if (response->getStatus() == Swift::Command::Completed) {
|
||||
m_sessions[from].erase(command->getId());
|
||||
if (m_sessions[from].empty()) {
|
||||
m_sessions.erase(from);
|
||||
}
|
||||
delete command;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
47
src/settingsadhoccommand.cpp
Normal file
47
src/settingsadhoccommand.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
|
||||
|
||||
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, initiator, to) {
|
||||
}
|
||||
|
||||
SettingsAdHocCommand::~SettingsAdHocCommand() {
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
|
||||
boost::shared_ptr<Swift::Command> response;
|
||||
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue