Merge branch 'master' of github.com:hanzz/libtransport

This commit is contained in:
HanzZ 2011-06-09 22:28:30 +02:00
commit 819c52172d
23 changed files with 363 additions and 9 deletions

View file

@ -110,6 +110,7 @@ ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(examples)
ADD_SUBDIRECTORY(spectrum)
ADD_SUBDIRECTORY(backends)
ADD_SUBDIRECTORY(tests)
if(DOXYGEN_FOUND)
message("Docs : yes")

View file

@ -17,6 +17,7 @@ MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, QObject*
{
this->np = np;
this->user = user;
connect(this, SIGNAL(disconnected()), SLOT(on_disconnected()));
}
void MyIrcSession::on_connected(){
@ -26,6 +27,7 @@ void MyIrcSession::on_connected(){
void MyIrcSession::on_disconnected()
{
std::cout << "disconnected:\n";
np->handleDisconnected(user, "", 0, "");
}
void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer)

View file

@ -118,7 +118,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
}
virtual void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
PurpleAccount *account = m_sessions[user];
if (account) {
serv_get_info(purple_account_get_connection(account), legacyName.c_str());
@ -126,6 +126,18 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
}
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::string &groups) {
PurpleAccount *account = m_sessions[user];
if (account) {
PurpleBuddy *buddy = purple_find_buddy(account, buddyName.c_str());
if (buddy) {
purple_blist_alias_buddy(buddy, alias.c_str());
purple_blist_server_alias_buddy(buddy, alias.c_str());
serv_alias_buddy(buddy);
}
}
}
std::map<std::string, PurpleAccount *> m_sessions;
std::map<PurpleAccount *, std::string> m_accounts;
std::map<std::string, unsigned int> m_vcards;
@ -479,6 +491,9 @@ static PurpleCoreUiOps coreUiOps =
};
static void signed_on(PurpleConnection *gc, gpointer unused) {
for (int i = 0; i<1500; i++) {
std::cout << "A\n";
}
PurpleAccount *account = purple_connection_get_account(gc);
np->handleConnected(np->m_accounts[account]);
}

View file

@ -64,6 +64,7 @@ class NetworkPlugin {
virtual void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/) {}
virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {}
virtual void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/) {}
virtual void handleBuddyUpdatedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*alias*/, const std::string &/*groups*/) {}
private:
@ -74,6 +75,7 @@ class NetworkPlugin {
void handleJoinRoomPayload(const std::string &payload);
void handleLeaveRoomPayload(const std::string &payload);
void handleVCardPayload(const std::string &payload);
void handleBuddyChangedPayload(const std::string &payload);
void handleDataRead(const Swift::SafeByteArray&);
void _handleConnected(bool error);
void handleDisconnected();

View file

@ -74,6 +74,10 @@ class NetworkPluginServer {
void handleUserReadyToConnect(User *user);
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 handleVCardRequired(User *user, const std::string &name, unsigned int id);
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);

View file

@ -60,6 +60,8 @@ class RosterManager {
void setStorageBackend(StorageBackend *storageBackend);
void storeBuddy(Buddy *buddy);
Swift::RosterPayload::ref generateRosterPayload();
/// Returns user associated with this roster.

View file

@ -28,12 +28,19 @@
namespace Transport {
class UserManager;
class Buddy;
class RosterResponder : public Swift::Responder<Swift::RosterPayload> {
public:
RosterResponder(Swift::IQRouter *router, UserManager *userManager);
~RosterResponder();
boost::signal<void (Buddy *, const Swift::RosterItemPayload &item)> onBuddyUpdated;
boost::signal<void (Buddy *)> onBuddyRemoved;
boost::signal<void (Buddy *, const Swift::RosterItemPayload &item)> onBuddyAdded;
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::RosterPayload> payload);
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::RosterPayload> payload);

View file

@ -31,6 +31,7 @@
#include "Swiften/Network/BoostTimerFactory.h"
#include "Swiften/Network/BoostIOServiceThread.h"
#include "Swiften/Server/UserRegistry.h"
#include "Swiften/Base/SafeByteArray.h"
#include <boost/bind.hpp>
#include "transport/config.h"
#include "transport/factory.h"

View file

@ -24,6 +24,7 @@
namespace Transport {
LocalBuddy::LocalBuddy(RosterManager *rosterManager, long id) : Buddy(rosterManager, id) {
m_status = Swift::StatusShow::None;
}
LocalBuddy::~LocalBuddy() {

View file

@ -265,8 +265,18 @@ void NetworkPlugin::handleVCardPayload(const std::string &data) {
handleVCardRequest(payload.username(), payload.buddyname(), payload.id());
}
void NetworkPlugin::handleBuddyChangedPayload(const std::string &data) {
pbnetwork::Buddy payload;
if (payload.ParseFromString(data) == false) {
// TODO: ERROR
return;
}
handleBuddyUpdatedRequest(payload.username(), payload.buddyname(), payload.alias(), payload.groups());
}
void NetworkPlugin::handleDataRead(const Swift::SafeByteArray &data) {
m_data.insert(m_data.begin(), data.begin(), data.end());
m_data.insert(m_data.end(), data.begin(), data.end());
while (m_data.size() != 0) {
unsigned int expected_size;
@ -310,6 +320,9 @@ void NetworkPlugin::handleDataRead(const Swift::SafeByteArray &data) {
case pbnetwork::WrapperMessage_Type_TYPE_VCARD:
handleVCardPayload(wrapper.payload());
break;
case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED:
handleBuddyChangedPayload(wrapper.payload());
break;
default:
return;
}

View file

@ -90,7 +90,7 @@ static int exec_(const char *path, const char *host, const char *port, const cha
if ( pid == 0 ) {
// child process
execlp(path, path, "--host", host, "--port", port, config, NULL);
exit(1);
abort();
} else if ( pid < 0 ) {
// fork failed
status = -1;
@ -128,6 +128,9 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U
m_vcardResponder->start();
m_rosterResponder = new RosterResponder(component->getIQRouter(), userManager);
m_rosterResponder->onBuddyAdded.connect(boost::bind(&NetworkPluginServer::handleBuddyAdded, this, _1, _2));
m_rosterResponder->onBuddyRemoved.connect(boost::bind(&NetworkPluginServer::handleBuddyRemoved, this, _1));
m_rosterResponder->onBuddyUpdated.connect(boost::bind(&NetworkPluginServer::handleBuddyUpdated, this, _1, _2));
m_rosterResponder->start();
m_server = component->getNetworkFactories()->getConnectionFactory()->createConnectionServer(10000);
@ -195,12 +198,12 @@ void NetworkPluginServer::handleDisconnectedPayload(const std::string &data) {
return;
}
m_component->m_userRegistry->onPasswordInvalid(payload.user());
User *user = m_userManager->getUser(payload.user());
if (!user) {
return;
}
m_component->m_userRegistry->onPasswordInvalid(payload.user());
user->handleDisconnected(payload.message());
}
@ -322,8 +325,7 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool
}
void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray &data) {
c->data.insert(c->data.begin(), data.begin(), data.end());
c->data.insert(c->data.end(), data.begin(), data.end());
while (c->data.size() != 0) {
unsigned int expected_size;
@ -339,8 +341,9 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray &
pbnetwork::WrapperMessage wrapper;
if (wrapper.ParseFromArray(&c->data[4], expected_size) == false) {
std::cout << "PARSING ERROR " << expected_size << "\n";
c->data.erase(c->data.begin(), c->data.begin() + 4 + expected_size);
return;
continue;
}
c->data.erase(c->data.begin(), c->data.begin() + 4 + expected_size);
@ -399,6 +402,10 @@ void NetworkPluginServer::pingTimeout() {
void NetworkPluginServer::handleUserCreated(User *user) {
Client *c = getFreeClient();
if (!c) {
user->handleDisconnected("Internal Server Error, please reconnect.");
return;
}
user->setData(c);
c->users.push_back(user);
@ -513,6 +520,36 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost
send(c->connection, message);
}
void NetworkPluginServer::handleBuddyRemoved(Buddy *buddy) {
}
void NetworkPluginServer::handleBuddyUpdated(Buddy *b, const Swift::RosterItemPayload &item) {
User *user = b->getRosterManager()->getUser();
dynamic_cast<LocalBuddy *>(b)->setAlias(item.getName());
user->getRosterManager()->storeBuddy(b);
pbnetwork::Buddy buddy;
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
buddy.set_groups(b->getGroups().size() == 0 ? "" : b->getGroups()[0]);
buddy.set_status(Swift::StatusShow::None);
std::string message;
buddy.SerializeToString(&message);
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED);
Client *c = (Client *) user->getData();
send(c->connection, message);
}
void NetworkPluginServer::handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item) {
handleBuddyUpdated(buddy, item);
}
void NetworkPluginServer::handleVCardRequired(User *user, const std::string &name, unsigned int id) {
std::cout << "VCARD REQUIRED " << name << " " << id << "\n";
pbnetwork::VCard vcard;

View file

@ -119,6 +119,12 @@ void RosterManager::unsetBuddy(Buddy *buddy) {
onBuddyUnset(buddy);
}
void RosterManager::storeBuddy(Buddy *buddy) {
if (m_rosterStorage) {
m_rosterStorage->storeBuddy(buddy);
}
}
void RosterManager::handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error, const std::string &key) {
if (m_buddies[key] != NULL) {
m_buddies[key]->handleBuddyChanged();

View file

@ -27,6 +27,7 @@
#include "transport/user.h"
#include "transport/usermanager.h"
#include "transport/rostermanager.h"
#include "transport/buddy.h"
using namespace Swift;
using namespace boost;
@ -67,6 +68,41 @@ bool RosterResponder::handleGetRequest(const Swift::JID& from, const Swift::JID&
bool RosterResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::RosterPayload> payload) {
sendResponse(from, id, boost::shared_ptr<RosterPayload>(new RosterPayload()));
User *user = m_userManager->getUser(from.toBare().toString());
if (!user) {
return true;
}
if (payload->getItems().size() == 0) {
return true;
}
Swift::RosterItemPayload item = payload->getItems()[0];
Buddy *buddy = user->getRosterManager()->getBuddy(Buddy::JIDToLegacyName(item.getJID()));
if (buddy) {
if (item.getSubscription() == Swift::RosterItemPayload::Remove) {
onBuddyRemoved(buddy);
}
else {
onBuddyUpdated(buddy, item);
}
}
else if (item.getSubscription() != Swift::RosterItemPayload::Remove) {
// Roster push for this new buddy is sent by RosterManager
BuddyInfo buddyInfo;
buddyInfo.id = -1;
buddyInfo.alias = item.getName();
buddyInfo.legacyName = Buddy::JIDToLegacyName(item.getJID());
buddyInfo.subscription = "both";
buddyInfo.flags = 0;
buddy = user->getComponent()->getFactory()->createBuddy(user->getRosterManager(), buddyInfo);
user->getRosterManager()->setBuddy(buddy);
onBuddyAdded(buddy, item);
}
return true;
}

View file

@ -240,7 +240,7 @@ long SQLite3Backend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
BIND_INT(m_addBuddy, userId);
BIND_STR(m_addBuddy, buddyInfo.legacyName);
BIND_STR(m_addBuddy, buddyInfo.subscription);
BIND_STR(m_addBuddy, buddyInfo.groups[0]); // TODO: serialize groups
BIND_STR(m_addBuddy, buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]); // TODO: serialize groups
BIND_STR(m_addBuddy, buddyInfo.alias);
BIND_INT(m_addBuddy, buddyInfo.flags);

5
tests/CMakeLists.txt Normal file
View file

@ -0,0 +1,5 @@
ADD_SUBDIRECTORY(login)
ADD_SUBDIRECTORY(login_bad_name)
ADD_SUBDIRECTORY(login_bad_name2)
add_custom_target(tests python runtests.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

View file

@ -0,0 +1,6 @@
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(login_test ${SRC})
TARGET_LINK_LIBRARIES(login_test transport ${SWIFTEN_LIBRARIES} -lgconf-2 -lgobject-2.0 -lglib-2.0)

44
tests/login/main.cpp Normal file
View file

@ -0,0 +1,44 @@
#include <iostream>
#include <boost/bind.hpp>
#include <Swiften/Swiften.h>
#include <Swiften/Client/ClientOptions.h>
using namespace Swift;
using namespace boost;
Client* client;
static void handleDisconnected(const boost::optional<ClientError> &) {
exit(1);
}
static void handleConnected() {
exit(0);
}
static void handleMessageReceived(Message::ref message) {
// Echo back the incoming message
message->setTo(message->getFrom());
message->setFrom(JID());
client->sendMessage(message);
}
int main(int, char **argv) {
SimpleEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
client = new Client(argv[1], argv[2], &networkFactories);
client->setAlwaysTrustCertificates();
client->onConnected.connect(&handleConnected);
client->onDisconnected.connect(bind(&handleDisconnected, _1));
client->onMessageReceived.connect(bind(&handleMessageReceived, _1));
ClientOptions opt;
opt.allowPLAINOverNonTLS = true;
client->connect(opt);
eventLoop.run();
delete client;
return 0;
}

View file

@ -0,0 +1,6 @@
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(login_bad_name_test ${SRC})
TARGET_LINK_LIBRARIES(login_bad_name_test transport ${SWIFTEN_LIBRARIES} -lgconf-2 -lgobject-2.0 -lglib-2.0)

View file

@ -0,0 +1,45 @@
#include <iostream>
#include <boost/bind.hpp>
#include <Swiften/Swiften.h>
#include <Swiften/Client/ClientOptions.h>
using namespace Swift;
using namespace boost;
Client* client;
static void handleDisconnected(const boost::optional<ClientError> &error) {
exit(error->getType() != ClientError::AuthenticationFailedError);
}
static void handleConnected() {
exit(1);
}
static void handleMessageReceived(Message::ref message) {
// Echo back the incoming message
message->setTo(message->getFrom());
message->setFrom(JID());
client->sendMessage(message);
}
int main(int, char **argv) {
SimpleEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
JID jid(JID(argv[1]).getNode() + "something", JID(argv[1]).getDomain());
client = new Client(jid, argv[2], &networkFactories);
client->setAlwaysTrustCertificates();
client->onConnected.connect(&handleConnected);
client->onDisconnected.connect(bind(&handleDisconnected, _1));
client->onMessageReceived.connect(bind(&handleMessageReceived, _1));
ClientOptions opt;
opt.allowPLAINOverNonTLS = true;
client->connect(opt);
eventLoop.run();
delete client;
return 0;
}

View file

View file

@ -0,0 +1,6 @@
FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(login_bad_name2_test ${SRC})
TARGET_LINK_LIBRARIES(login_bad_name2_test transport ${SWIFTEN_LIBRARIES} -lgconf-2 -lgobject-2.0 -lglib-2.0)

View file

@ -0,0 +1,45 @@
#include <iostream>
#include <boost/bind.hpp>
#include <Swiften/Swiften.h>
#include <Swiften/Client/ClientOptions.h>
using namespace Swift;
using namespace boost;
Client* client;
static void handleDisconnected(const boost::optional<ClientError> &error) {
exit(error->getType() != ClientError::AuthenticationFailedError);
}
static void handleConnected() {
exit(1);
}
static void handleMessageReceived(Message::ref message) {
// Echo back the incoming message
message->setTo(message->getFrom());
message->setFrom(JID());
client->sendMessage(message);
}
int main(int, char **argv) {
SimpleEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
JID jid(std::string("something") + JID(argv[1]).getNode(), JID(argv[1]).getDomain());
client = new Client(jid, argv[2], &networkFactories);
client->setAlwaysTrustCertificates();
client->onConnected.connect(&handleConnected);
client->onDisconnected.connect(bind(&handleDisconnected, _1));
client->onMessageReceived.connect(bind(&handleMessageReceived, _1));
ClientOptions opt;
opt.allowPLAINOverNonTLS = true;
client->connect(opt);
eventLoop.run();
delete client;
return 0;
}

70
tests/runtests.py Normal file
View file

@ -0,0 +1,70 @@
import os
import sys
from subprocess import *
import time
def run_spectrum(backend, test):
os.system("rm test.sql")
f = open("sample.cfg", "w")
f.write("\
[service]\n\
jid = localhost\n\
password = secret\n\
server = 127.0.0.1\n\
port = 5222\n\
server_mode = 1\n\
backend=../backends/%s/%s_backend\n\
protocol=prpl-jabber\n\
\
[database]\n\
database = test.sql\n\
prefix=icq\n\
" % (backend, backend)
)
f.close()
p = Popen("../spectrum/src/spectrum sample.cfg > " + backend + "_" + test + ".log 2>&1", shell=True)
time.sleep(4)
return p
def one_test_run():
os.system("killall spectrum 2> /dev/null")
os.system("rm *.log")
for backend in os.listdir("../backends"):
if not os.path.isdir("../backends/" + backend) or backend == "CMakeFiles":
continue
for d in os.listdir("."):
binary = d + "/" + d + "_test"
if not os.path.exists(binary):
continue
if os.path.exists(d + "/.no" + backend):
continue
p = run_spectrum(backend, d)
if backend.find("purple") >= 0:
p = Popen(binary + " pyjim%jabber.cz@localhost test", shell=True)
else:
p = Popen(binary + " testnickname%irc.freenode.net@localhost test", shell=True)
seconds = 0
while p.poll() is None and seconds < 20:
time.sleep(1)
seconds += 1
if p.returncode == 0 and seconds < 20:
print "[ PASS ]", backend, binary
else:
if seconds == 20:
print "[ TIME ]", backend, binary
else:
print "[ FAIL ]", backend, binary
os.system("killall spectrum 2> /dev/null")
one_test_run()