From 3d043d8abd30407bb868c7579677074c56068277 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 26 Jan 2022 11:50:43 +0300 Subject: [PATCH] WIP --- CMakeLists.txt | 4 +- backends/frotz/CMakeLists.txt | 2 +- backends/frotz/main.cpp | 614 +++++++++--------- backends/libcommuni/CMakeLists.txt | 8 +- backends/libcommuni/ircnetworkplugin.cpp | 2 +- backends/libcommuni/ircnetworkplugin.h | 3 +- backends/libcommuni/main.cpp | 5 +- backends/libcommuni/session.h | 1 - backends/smstools3/CMakeLists.txt | 2 +- backends/smstools3/main.cpp | 53 +- backends/swiften/CMakeLists.txt | 6 +- backends/template/CMakeLists.txt | 12 +- backends/template/main.cpp | 9 +- backends/template/plugin.cpp | 74 +-- backends/template/plugin.h | 23 +- backends/twitter/CMakeLists.txt | 2 +- backends/twitter/HTTPRequest.h | 37 -- .../twitter/Requests/CreateFriendRequest.cpp | 2 +- backends/twitter/Requests/FetchFriends.cpp | 2 +- .../twitter/Requests/ProfileImageRequest.cpp | 2 +- .../twitter/Requests/ProfileImageRequest.h | 1 - backends/twitter/TwitterPlugin.cpp | 91 ++- backends/twitter/TwitterPlugin.h | 29 +- backends/twitter/libtwitcurl/oauthlib.h | 1 - backends/twitter/main.cpp | 7 +- include/transport/BoostNetworkPlugin.h | 45 ++ include/transport/HTTPRequest.h | 87 +-- include/transport/HTTPRequestQueue.h | 40 -- include/transport/NetworkPlugin.h | 7 +- include/transport/ThreadPool.h | 6 +- libtransport/CMakeLists.txt | 4 - libtransport/HTTPRequest.cpp | 159 ----- libtransport/HTTPRequestQueue.cpp | 64 -- libtransport/OAuth2.cpp | 17 +- libtransport/WebSocketClient.cpp | 20 +- plugin/cpp/BoostNetworkPlugin.cpp | 76 +++ plugin/cpp/CMakeLists.txt | 9 +- .../twitter => plugin/cpp}/HTTPRequest.cpp | 2 +- plugin/cpp/MemoryUsage.cpp | 1 - {libtransport => plugin/cpp}/MySQLBackend.cpp | 0 {libtransport => plugin/cpp}/PQXXBackend.cpp | 0 .../cpp}/SQLite3Backend.cpp | 0 .../cpp}/StorageBackend.cpp | 25 +- {libtransport => plugin/cpp}/ThreadPool.cpp | 6 +- plugin/cpp/networkplugin.cpp | 14 +- spectrum/src/CMakeLists.txt | 7 +- spectrum/src/frontends/CMakeLists.txt | 2 + spectrum/src/frontends/xmpp/XMPPFrontend.cpp | 2 +- .../src/frontends/xmpp/gatewayresponder.cpp | 2 +- spectrum/src/main.cpp | 2 + tests/libtransport/CMakeLists.txt | 10 +- tests/libtransport/HTTPRequest.cpp | 49 +- tests/libtransport/main.cpp | 18 +- .../{ => slack}/AdminInterface.cpp | 0 .../{ => slack}/BasicSlackTest.cpp | 0 .../libtransport/{ => slack}/BasicSlackTest.h | 0 tests/libtransport/{ => slack}/SlackRTM.cpp | 0 57 files changed, 665 insertions(+), 1001 deletions(-) delete mode 100644 backends/twitter/HTTPRequest.h create mode 100644 include/transport/BoostNetworkPlugin.h delete mode 100644 include/transport/HTTPRequestQueue.h delete mode 100644 libtransport/HTTPRequest.cpp delete mode 100644 libtransport/HTTPRequestQueue.cpp create mode 100644 plugin/cpp/BoostNetworkPlugin.cpp rename {backends/twitter => plugin/cpp}/HTTPRequest.cpp (98%) rename {libtransport => plugin/cpp}/MySQLBackend.cpp (100%) rename {libtransport => plugin/cpp}/PQXXBackend.cpp (100%) rename {libtransport => plugin/cpp}/SQLite3Backend.cpp (100%) rename {libtransport => plugin/cpp}/StorageBackend.cpp (74%) rename {libtransport => plugin/cpp}/ThreadPool.cpp (92%) rename tests/libtransport/{ => slack}/AdminInterface.cpp (100%) rename tests/libtransport/{ => slack}/BasicSlackTest.cpp (100%) rename tests/libtransport/{ => slack}/BasicSlackTest.h (100%) rename tests/libtransport/{ => slack}/SlackRTM.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f2c7699ba..cfac86fea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ option(ENABLE_SMSTOOLS3 "Build SMSTools3 plugin" ON) option(ENABLE_XMPP "Build XMPP plugin" ON) option(ENABLE_TWITTER "Build Twitter plugin" ON) option(ENABLE_WEBUI "Build Web UI" ON) - +option(ENABLE_SLACK_FRONTEND "Build Slack frontend" OFF) option(ENABLE_DOCS "Build Docs" ON) # option(ENABLE_LOG "Build with logging using Log4cxx" ON) option(ENABLE_TESTS "Build Tests using CppUnit" OFF) @@ -99,6 +99,8 @@ if(WIN32) link_directories("$ENV{CMAKE_PREFIX_PATH}/lib") endif(WIN32) +find_package( Threads ) + set(Boost_FIND_QUIETLY ON) find_package(Boost COMPONENTS program_options date_time system filesystem regex thread locale REQUIRED) diff --git a/backends/frotz/CMakeLists.txt b/backends/frotz/CMakeLists.txt index 22b4852ff..f0a6a3176 100644 --- a/backends/frotz/CMakeLists.txt +++ b/backends/frotz/CMakeLists.txt @@ -5,6 +5,6 @@ file(GLOB SRC *.c *.cpp) add_executable(spectrum2_frotz_backend ${SRC}) -target_link_libraries(spectrum2_frotz_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) +target_link_libraries(spectrum2_frotz_backend transport ${Boost_LIBRARIES} ${LOG4CXX_LIBRARIES}) install(TARGETS spectrum2_frotz_backend RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) diff --git a/backends/frotz/main.cpp b/backends/frotz/main.cpp index 05e50b21c..ec68af5a3 100644 --- a/backends/frotz/main.cpp +++ b/backends/frotz/main.cpp @@ -9,349 +9,349 @@ */ #include "transport/Config.h" -#include "transport/NetworkPlugin.h" -#include -#include -#include "unistd.h" +#include "transport/BoostNetworkPlugin.h" +#include + #include "signal.h" -#include "sys/wait.h" #include "sys/signal.h" -Swift::SimpleEventLoop *loop_; +#include "sys/wait.h" +#include "unistd.h" +#include +#include +#include +using namespace boost::asio::ip; using namespace boost::program_options; + using namespace Transport; class FrotzNetworkPlugin; -FrotzNetworkPlugin * np = NULL; +FrotzNetworkPlugin *np = NULL; -#define PARENT_READ p.readpipe[0] -#define CHILD_WRITE p.readpipe[1] -#define CHILD_READ p.writepipe[0] -#define PARENT_WRITE p.writepipe[1] +#define PARENT_READ p.readpipe[0] +#define CHILD_WRITE p.readpipe[1] +#define CHILD_READ p.writepipe[0] +#define PARENT_WRITE p.writepipe[1] typedef struct dfrotz_ { - pid_t pid; - std::string game; - int readpipe[2]; - int writepipe[2]; + pid_t pid; + std::string game; + int readpipe[2]; + int writepipe[2]; } dfrotz; using namespace boost::filesystem; -static const char *howtoplay = "To move around, just type the direction you want to go. Directions can be\n" -"abbreviated: NORTH to N, SOUTH to S, EAST to E, WEST to W, NORTHEAST to\n" -"NE, NORTHWEST to NW, SOUTHEAST to SE, SOUTHWEST to SW, UP to U, and DOWN\n" -"to D. IN and OUT will also work in certain places.\n" -"\n" -"There are many differnet kinds of sentences used in Interactive Fiction.\n" -"Here are some examples:\n" -"\n" -"> WALK TO THE NORTH\n" -"> WEST\n" -"> NE\n" -"> DOWN\n" -"> TAKE THE BIRDCAGE\n" -"> READ ABOUT DIMWIT FLATHEAD\n" -"> LOOK UP MEGABOZ IN THE ENCYCLOPEDIA\n" -"> LIE DOWN IN THE PINK SOFA\n" -"> EXAMINE THE SHINY COIN\n" -"> PUT THE RUSTY KEY IN THE CARDBOARD BOX\n" -"> SHOW MY BOW TIE TO THE BOUNCER\n" -"> HIT THE CRAWLING CRAB WITH THE GIANT NUTCRACKER\n" -"> ASK THE COWARDLY KING ABOUT THE CROWN JEWELS\n" -"\n" -"You can use multiple objects with certain verbs if you separate them by\n" -"the word \"AND\" or by a comma. Here are some examples:\n" -"\n" -"> TAKE THE BOOK AND THE FROG\n" -"> DROP THE JAR OF PEANUT BUTTER, THE SPOON, AND THE LEMMING FOOD\n" -"> PUT THE EGG AND THE PENCIL IN THE CABINET\n" -"\n" -"You can include several inputs on one line if you separate them by the\n" -"word \"THEN\" or by a period. Each input will be handled in order, as\n" -"though you had typed them individually at seperate prompts. For example,\n" -"you could type all of the following at once, before pressing the ENTER (or\n" -"RETURN) key:\n" -"\n" -"> TURN ON THE LIGHT. TAKE THE BOOK THEN READ ABOUT THE JESTER IN THE BOOK\n" -"\n" -"If the story doesn't understand one of the sentences on your input line,\n" -"or if an unusual event occurs, it will ignore the rest of your input line.\n" -"\n" -"The words \"IT\" and \"ALL\" can be very useful. For example:\n" -"\n" -"> EXAMINE THE APPLE. TAKE IT. EAT IT\n" -"> CLOSE THE HEAVY METAL DOOR. LOCK IT\n" -"> PICK UP THE GREEN BOOT. SMELL IT. PUT IT ON.\n" -"> TAKE ALL\n" -"> TAKE ALL THE TOOLS\n" -"> DROP ALL THE TOOLS EXCEPT THE WRENCH AND MINIATURE HAMMER\n" -"> TAKE ALL FROM THE CARTON\n" -"> GIVE ALL BUT THE RUBY SLIPPERS TO THE WICKED WITCH\n" -"\n" -"The word \"ALL\" refers to every visible object except those inside\n" -"something else. If there were an apple on the ground and an orange inside\n" -"a cabinet, \"TAKE ALL\" would take the apple but not the orange.\n" -"\n" -"There are three kinds of questions you can ask: \"WHERE IS (something)\",\n" -"\"WHAT IS (something)\", and \"WHO IS (someone)\". For example:\n" -"\n" -"> WHO IS LORD DIMWIT?\n" -"> WHAT IS A GRUE?\n" -"> WHERE IS EVERYBODY?\n" -"\n" -"When you meet intelligent creatures, you can talk to them by typing their\n" -"name, then a comma, then whatever you want to say to them. Here are some\n" -"examples:\n" -"\n" -"> JESTER, HELLO\n" -"> GUSTAR WOOMAX, TELL ME ABOUT THE COCONUT\n" -"> UNCLE OTTO, GIVE ME YOUR WALLET\n" -"> HORSE, WHERE IS YOUR SADDLE?\n" -"> BOY, RUN HOME THEN CALL THE POLICE\n" -"> MIGHTY WIZARD, TAKE THIS POISONED APPLE. EAT IT\n" -"\n" -"Notice that in the last two examples, you are giving the characters more\n" -"than one command on the same input line. Keep in mind, however, that many\n" -"creatures don't care for idle chatter; your actions will speak louder than\n" -"your words. \n"; - +static const char *howtoplay = + "To move around, just type the direction you want to go. Directions can " + "be\n" + "abbreviated: NORTH to N, SOUTH to S, EAST to E, WEST to W, NORTHEAST to\n" + "NE, NORTHWEST to NW, SOUTHEAST to SE, SOUTHWEST to SW, UP to U, and DOWN\n" + "to D. IN and OUT will also work in certain places.\n" + "\n" + "There are many differnet kinds of sentences used in Interactive Fiction.\n" + "Here are some examples:\n" + "\n" + "> WALK TO THE NORTH\n" + "> WEST\n" + "> NE\n" + "> DOWN\n" + "> TAKE THE BIRDCAGE\n" + "> READ ABOUT DIMWIT FLATHEAD\n" + "> LOOK UP MEGABOZ IN THE ENCYCLOPEDIA\n" + "> LIE DOWN IN THE PINK SOFA\n" + "> EXAMINE THE SHINY COIN\n" + "> PUT THE RUSTY KEY IN THE CARDBOARD BOX\n" + "> SHOW MY BOW TIE TO THE BOUNCER\n" + "> HIT THE CRAWLING CRAB WITH THE GIANT NUTCRACKER\n" + "> ASK THE COWARDLY KING ABOUT THE CROWN JEWELS\n" + "\n" + "You can use multiple objects with certain verbs if you separate them by\n" + "the word \"AND\" or by a comma. Here are some examples:\n" + "\n" + "> TAKE THE BOOK AND THE FROG\n" + "> DROP THE JAR OF PEANUT BUTTER, THE SPOON, AND THE LEMMING FOOD\n" + "> PUT THE EGG AND THE PENCIL IN THE CABINET\n" + "\n" + "You can include several inputs on one line if you separate them by the\n" + "word \"THEN\" or by a period. Each input will be handled in order, as\n" + "though you had typed them individually at seperate prompts. For " + "example,\n" + "you could type all of the following at once, before pressing the ENTER " + "(or\n" + "RETURN) key:\n" + "\n" + "> TURN ON THE LIGHT. TAKE THE BOOK THEN READ ABOUT THE JESTER IN THE " + "BOOK\n" + "\n" + "If the story doesn't understand one of the sentences on your input line,\n" + "or if an unusual event occurs, it will ignore the rest of your input " + "line.\n" + "\n" + "The words \"IT\" and \"ALL\" can be very useful. For example:\n" + "\n" + "> EXAMINE THE APPLE. TAKE IT. EAT IT\n" + "> CLOSE THE HEAVY METAL DOOR. LOCK IT\n" + "> PICK UP THE GREEN BOOT. SMELL IT. PUT IT ON.\n" + "> TAKE ALL\n" + "> TAKE ALL THE TOOLS\n" + "> DROP ALL THE TOOLS EXCEPT THE WRENCH AND MINIATURE HAMMER\n" + "> TAKE ALL FROM THE CARTON\n" + "> GIVE ALL BUT THE RUBY SLIPPERS TO THE WICKED WITCH\n" + "\n" + "The word \"ALL\" refers to every visible object except those inside\n" + "something else. If there were an apple on the ground and an orange " + "inside\n" + "a cabinet, \"TAKE ALL\" would take the apple but not the orange.\n" + "\n" + "There are three kinds of questions you can ask: \"WHERE IS " + "(something)\",\n" + "\"WHAT IS (something)\", and \"WHO IS (someone)\". For example:\n" + "\n" + "> WHO IS LORD DIMWIT?\n" + "> WHAT IS A GRUE?\n" + "> WHERE IS EVERYBODY?\n" + "\n" + "When you meet intelligent creatures, you can talk to them by typing " + "their\n" + "name, then a comma, then whatever you want to say to them. Here are " + "some\n" + "examples:\n" + "\n" + "> JESTER, HELLO\n" + "> GUSTAR WOOMAX, TELL ME ABOUT THE COCONUT\n" + "> UNCLE OTTO, GIVE ME YOUR WALLET\n" + "> HORSE, WHERE IS YOUR SADDLE?\n" + "> BOY, RUN HOME THEN CALL THE POLICE\n" + "> MIGHTY WIZARD, TAKE THIS POISONED APPLE. EAT IT\n" + "\n" + "Notice that in the last two examples, you are giving the characters more\n" + "than one command on the same input line. Keep in mind, however, that " + "many\n" + "creatures don't care for idle chatter; your actions will speak louder " + "than\n" + "your words. \n"; static void start_dfrotz(dfrotz &p, const std::string &game) { -// p.writepipe[0] = -1; + // p.writepipe[0] = -1; - if (pipe(p.readpipe) < 0 || pipe(p.writepipe) < 0) { - } + if (pipe(p.readpipe) < 0 || pipe(p.writepipe) < 0) { + } - std::cout << "dfrotz -p " << game << "\n"; + std::cout << "dfrotz -p " << game << "\n"; - if ((p.pid = fork()) < 0) { - /* FATAL: cannot fork child */ - } - else if (p.pid == 0) { - close(PARENT_WRITE); - close(PARENT_READ); + if ((p.pid = fork()) < 0) { + /* FATAL: cannot fork child */ + } else if (p.pid == 0) { + close(PARENT_WRITE); + close(PARENT_READ); - dup2(CHILD_READ, 0); close(CHILD_READ); - dup2(CHILD_WRITE, 1); close(CHILD_WRITE); + dup2(CHILD_READ, 0); + close(CHILD_READ); + dup2(CHILD_WRITE, 1); + close(CHILD_WRITE); - execlp("dfrotz", "-p", game.c_str(), NULL); + execlp("dfrotz", "-p", game.c_str(), NULL); - } - else { - close(CHILD_READ); - close(CHILD_WRITE); - } + } else { + close(CHILD_READ); + close(CHILD_WRITE); + } } -class FrotzNetworkPlugin : public NetworkPlugin { - public: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr m_conn; - - FrotzNetworkPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { - this->config = config; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&FrotzNetworkPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); -// m_conn->onConnectFinished.connect(boost::bind(&FrotzNetworkPlugin::_handleConnected, this, _1)); -// m_conn->onDisconnected.connect(boost::bind(&FrotzNetworkPlugin::handleDisconnected, this)); - } - - void sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); - } - - void _handleDataRead(std::shared_ptr data) { - std::string d(data->begin(), data->end()); - handleDataRead(d); - } - - void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings) { - np->handleConnected(user); - std::vector groups; - groups.push_back("ZCode"); - np->handleBuddyChanged(user, "zcode", "ZCode", groups, pbnetwork::STATUS_ONLINE); -// sleep(1); -// np->handleMessage(np->m_user, "zork", first_msg); - } - - void handleLogoutRequest(const std::string &user, const std::string &legacyName) { - if (games.find(user) != games.end()) { - kill(games[user].pid, SIGTERM); - games.erase(user); - } -// exit(0); - } - - void readMessage(const std::string &user) { - static char buf[15000]; - buf[0] = 0; - int repeated = 0; - while (strlen(buf) == 0) { - ssize_t len = read(games[user].readpipe[0], buf, 15000); - if (len > 0) { - buf[len] = 0; - } - usleep(1000); - repeated++; - if (repeated > 30) - return; - } - np->handleMessage(user, "zcode", buf); - - std::string msg = "save\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - - msg = user + "_" + games[user].game + ".save\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - ignoreMessage(user); - } - - void ignoreMessage(const std::string &user) { - usleep(1000000); - static char buf[15000]; - buf[0] = 0; - int repeated = 0; - while (strlen(buf) == 0) { - ssize_t len = read(games[user].readpipe[0], buf, 15000); - if (len > 0) { - buf[len] = 0; - } - usleep(1000); - repeated++; - if (repeated > 30) - return; - } - - std::cout << "ignoring: " << buf << "\n"; - } - - std::vector getGames() { - std::vector games; - path p("."); - directory_iterator end_itr; - for (directory_iterator itr(p); itr != end_itr; ++itr) { - if (extension(itr->path()) == ".z5") { +class FrotzNetworkPlugin : public BoostNetworkPlugin { +public: + FrotzNetworkPlugin(Config *config, const std::string &host, int port) + : BoostNetworkPlugin(config, host, port) { + } + + void handleLoginRequest(const std::string &user, + const std::string &legacyName, + const std::string &password, + const std::map &settings) { + np->handleConnected(user); + std::vector groups; + groups.push_back("ZCode"); + np->handleBuddyChanged(user, "zcode", "ZCode", groups, + pbnetwork::STATUS_ONLINE); + // sleep(1); + // np->handleMessage(np->m_user, "zork", first_msg); + } + + void handleLogoutRequest(const std::string &user, + const std::string &legacyName) { + if (games.find(user) != games.end()) { + kill(games[user].pid, SIGTERM); + games.erase(user); + } + // exit(0); + } + + void readMessage(const std::string &user) { + static char buf[15000]; + buf[0] = 0; + int repeated = 0; + while (strlen(buf) == 0) { + ssize_t len = read(games[user].readpipe[0], buf, 15000); + if (len > 0) { + buf[len] = 0; + } + usleep(1000); + repeated++; + if (repeated > 30) + return; + } + np->handleMessage(user, "zcode", buf); + + std::string msg = "save\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + + msg = user + "_" + games[user].game + ".save\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + ignoreMessage(user); + } + + void ignoreMessage(const std::string &user) { + usleep(1000000); + static char buf[15000]; + buf[0] = 0; + int repeated = 0; + while (strlen(buf) == 0) { + ssize_t len = read(games[user].readpipe[0], buf, 15000); + if (len > 0) { + buf[len] = 0; + } + usleep(1000); + repeated++; + if (repeated > 30) + return; + } + + std::cout << "ignoring: " << buf << "\n"; + } + + std::vector getGames() { + std::vector games; + path p("."); + directory_iterator end_itr; + for (directory_iterator itr(p); itr != end_itr; ++itr) { + if (extension(itr->path()) == ".z5") { #if BOOST_FILESYSTEM_VERSION == 3 - games.push_back(itr->path().filename().string()); + games.push_back(itr->path().filename().string()); #else - games.push_back(itr->path().leaf()); + games.push_back(itr->path().leaf()); #endif - } - } - return games; - } - - void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "") { - std::cout << "aaa\n"; - if (message.find("start") == 0) { - std::string game = message.substr(6); - std::vector lst = getGames(); - if (std::find(lst.begin(), lst.end(), game) == lst.end()) { - np->handleMessage(user, "zcode", "Unknown game"); - return; - } - np->handleMessage(user, "zcode", "Starting the game"); - - dfrotz d; - d.game = game; - start_dfrotz(d, game); - games[user] = d; - fcntl(games[user].readpipe[0], F_SETFL, O_NONBLOCK); - - if (boost::filesystem::exists(user + "_" + games[user].game + ".save")) { - - std::string msg = "restore\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - - msg = user + "_" + games[user].game + ".save\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - - ignoreMessage(user); - - msg = "l\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - } - - readMessage(user); - } - else if (message == "stop" && games.find(user) != games.end()) { - kill(games[user].pid, SIGTERM); - games.erase(user); - np->handleMessage(user, "zcode", "Game stopped"); - } - else if (message == "howtoplay") { - np->handleMessage(user, "zcode", howtoplay); - } - else if (games.find(user) != games.end()) { - std::string msg = message + "\n"; - write(games[user].writepipe[1], msg.c_str(), msg.size()); - readMessage(user); - } - else { - std::string games; - BOOST_FOREACH(const std::string &game, getGames()) { - games += game + "\n"; - } - np->handleMessage(user, "zcode", "Games are saved/loaded automatically. Use \"restart\" to restart existing game. Emulator commands are:\nstart \nstop\nhowtoplay\n\nList of games:\n" + games); - } - } - - void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) { - } - - void handleLeaveRoomRequest(const std::string &user, const std::string &room) { - } - - std::map games; - std::string first_msg; - private: - - Config *config; + } + } + return games; + } + + void handleMessageSendRequest(const std::string &user, + const std::string &legacyName, + const std::string &message, + const std::string &xhtml = "", + const std::string &id = "") { + std::cout << "aaa\n"; + if (message.find("start") == 0) { + std::string game = message.substr(6); + std::vector lst = getGames(); + if (std::find(lst.begin(), lst.end(), game) == lst.end()) { + np->handleMessage(user, "zcode", "Unknown game"); + return; + } + np->handleMessage(user, "zcode", "Starting the game"); + + dfrotz d; + d.game = game; + start_dfrotz(d, game); + games[user] = d; + fcntl(games[user].readpipe[0], F_SETFL, O_NONBLOCK); + + if (boost::filesystem::exists(user + "_" + games[user].game + ".save")) { + + std::string msg = "restore\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + + msg = user + "_" + games[user].game + ".save\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + + ignoreMessage(user); + + msg = "l\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + } + + readMessage(user); + } else if (message == "stop" && games.find(user) != games.end()) { + kill(games[user].pid, SIGTERM); + games.erase(user); + np->handleMessage(user, "zcode", "Game stopped"); + } else if (message == "howtoplay") { + np->handleMessage(user, "zcode", howtoplay); + } else if (games.find(user) != games.end()) { + std::string msg = message + "\n"; + write(games[user].writepipe[1], msg.c_str(), msg.size()); + readMessage(user); + } else { + std::string games; + BOOST_FOREACH (const std::string &game, getGames()) { + games += game + "\n"; + } + np->handleMessage( + user, "zcode", + "Games are saved/loaded automatically. Use \"restart\" to restart " + "existing game. Emulator commands are:\nstart " + "\nstop\nhowtoplay\n\nList of games:\n" + + games); + } + } + + void handleJoinRoomRequest(const std::string &user, const std::string &room, + const std::string &nickname, + const std::string &password) {} + + void handleLeaveRoomRequest(const std::string &user, + const std::string &room) {} + + std::map games; + std::string first_msg; }; -static void spectrum_sigchld_handler(int sig) -{ - int status; - pid_t pid; +static void spectrum_sigchld_handler(int sig) { + int status; + pid_t pid; - do { - pid = waitpid(-1, &status, WNOHANG); - } while (pid != 0 && pid != (pid_t)-1); + do { + pid = waitpid(-1, &status, WNOHANG); + } while (pid != 0 && pid != (pid_t)-1); - if ((pid == (pid_t) - 1) && (errno != ECHILD)) { - char errmsg[BUFSIZ]; - snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid); - perror(errmsg); - } + if ((pid == (pid_t)-1) && (errno != ECHILD)) { + char errmsg[BUFSIZ]; + snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid); + perror(errmsg); + } } +int main(int argc, char *argv[]) { + std::string host; + int port; -int main (int argc, char* argv[]) { - std::string host; - int port; - - if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) { - std::cout << "SIGCHLD handler can't be set\n"; - return -1; - } + if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) { + std::cout << "SIGCHLD handler can't be set\n"; + return -1; + } - std::string error; - Config *cfg = Config::createFromArgs(argc, argv, error, host, port); - if (cfg == NULL) { - std::cerr << error; - return 1; - } + std::string error; + Config *cfg = Config::createFromArgs(argc, argv, error, host, port); + if (cfg == NULL) { + std::cerr << error; + return 1; + } - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new FrotzNetworkPlugin(cfg, &eventLoop, host, port); - loop_->run(); + np = new FrotzNetworkPlugin(cfg, host, port); + np->run(); - delete cfg; + delete cfg; - return 0; + return 0; } diff --git a/backends/libcommuni/CMakeLists.txt b/backends/libcommuni/CMakeLists.txt index 0d3ee4ccc..57e3a79d0 100644 --- a/backends/libcommuni/CMakeLists.txt +++ b/backends/libcommuni/CMakeLists.txt @@ -13,15 +13,15 @@ add_executable(spectrum2_libcommuni_backend ${SRC}) if(NOT WIN32) if(ENABLE_QT4) - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport pthread) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport-plugin) else() - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport pthread) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport-plugin) endif() else() if(ENABLE_QT4) - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt4::QtNetwork Qt4::QtCore transport-plugin) else() - target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport) + target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} Qt5::Network Qt5::Core transport-plugin) endif() endif() diff --git a/backends/libcommuni/ircnetworkplugin.cpp b/backends/libcommuni/ircnetworkplugin.cpp index 33ed5e451..c7f68dad5 100644 --- a/backends/libcommuni/ircnetworkplugin.cpp +++ b/backends/libcommuni/ircnetworkplugin.cpp @@ -27,7 +27,7 @@ DEFINE_LOGGER(logger, "IRCNetworkPlugin"); #define FROM_UTF8(WHAT) QString::fromUtf8((WHAT).c_str(), (WHAT).size()) #define TO_UTF8(WHAT) std::string((WHAT).toUtf8().data(), (WHAT).toUtf8().size()) -IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) { +IRCNetworkPlugin::IRCNetworkPlugin(Config *config, const std::string &host, int port) : NetworkPlugin() { m_config = config; m_currentServer = 0; m_firstPing = true; diff --git a/backends/libcommuni/ircnetworkplugin.h b/backends/libcommuni/ircnetworkplugin.h index aafa05a61..27de306df 100644 --- a/backends/libcommuni/ircnetworkplugin.h +++ b/backends/libcommuni/ircnetworkplugin.h @@ -26,14 +26,13 @@ #include #include "transport/Config.h" #include "transport/NetworkPlugin.h" -#include "Swiften/EventLoop/Qt/QtEventLoop.h" #endif class IRCNetworkPlugin : public QObject, public NetworkPlugin { Q_OBJECT public: - IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port); + IRCNetworkPlugin(Config *config, const std::string &host, int port); void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings); diff --git a/backends/libcommuni/main.cpp b/backends/libcommuni/main.cpp index a5100e03c..c39863fcb 100644 --- a/backends/libcommuni/main.cpp +++ b/backends/libcommuni/main.cpp @@ -22,7 +22,6 @@ #include "transport/Config.h" #include "transport/NetworkPlugin.h" #include "transport/Logging.h" -#include "Swiften/EventLoop/Qt/QtEventLoop.h" #include "ircnetworkplugin.h" using namespace boost::program_options; @@ -45,9 +44,7 @@ int main (int argc, char* argv[]) { QCoreApplication app(argc, argv); - Swift::QtEventLoop eventLoop; - - np = new IRCNetworkPlugin(cfg, &eventLoop, host, port); + np = new IRCNetworkPlugin(cfg, host, port); return app.exec(); } diff --git a/backends/libcommuni/session.h b/backends/libcommuni/session.h index 55a1ee869..70c7b5602 100644 --- a/backends/libcommuni/session.h +++ b/backends/libcommuni/session.h @@ -27,7 +27,6 @@ #include #include #include -#include "Swiften/Swiften.h" #include #include #endif diff --git a/backends/smstools3/CMakeLists.txt b/backends/smstools3/CMakeLists.txt index f922c42d1..9922dbaa2 100644 --- a/backends/smstools3/CMakeLists.txt +++ b/backends/smstools3/CMakeLists.txt @@ -2,6 +2,6 @@ file(GLOB SRC *.c *.cpp) add_executable(spectrum2_smstools3_backend ${SRC}) -target_link_libraries(spectrum2_smstools3_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) +target_link_libraries(spectrum2_smstools3_backend transport ${Boost_LIBRARIES} ${LOG4CXX_LIBRARIES}) install(TARGETS spectrum2_smstools3_backend RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) diff --git a/backends/smstools3/main.cpp b/backends/smstools3/main.cpp index 52ac28235..6fe52bc96 100644 --- a/backends/smstools3/main.cpp +++ b/backends/smstools3/main.cpp @@ -10,12 +10,11 @@ #include "transport/Config.h" #include "transport/Logging.h" -#include "transport/NetworkPlugin.h" +#include "transport/BoostNetworkPlugin.h" #include "transport/SQLite3Backend.h" #include "transport/MySQLBackend.h" #include "transport/PQXXBackend.h" #include "transport/StorageBackend.h" -#include #include #include "unistd.h" #include "signal.h" @@ -24,14 +23,13 @@ #include #include -Swift::SimpleEventLoop *loop_; - #include #include +using namespace boost::asio::ip; using namespace boost::filesystem; - using namespace boost::program_options; + using namespace Transport; DEFINE_LOGGER(logger, "SMSNetworkPlugin"); @@ -41,30 +39,18 @@ DEFINE_LOGGER(logger, "SMSNetworkPlugin"); class SMSNetworkPlugin; SMSNetworkPlugin * np = NULL; -class SMSNetworkPlugin : public NetworkPlugin { +class SMSNetworkPlugin : public BoostNetworkPlugin { public: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr m_conn; - Swift::Timer::ref m_timer; int m_internalUser; + std::shared_ptr m_timer; StorageBackend *storageBackend; - SMSNetworkPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port) : NetworkPlugin() { - this->config = config; + SMSNetworkPlugin(Config *config, StorageBackend *storagebackend, const std::string &host, int port) + : BoostNetworkPlugin(config, host, port) { this->storageBackend = storagebackend; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&SMSNetworkPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); -// m_conn->onConnectFinished.connect(boost::bind(&FrotzNetworkPlugin::_handleConnected, this, _1)); -// m_conn->onDisconnected.connect(boost::bind(&FrotzNetworkPlugin::handleDisconnected, this)); - LOG4CXX_INFO(logger, "Starting the plugin."); - - m_timer = m_factories->getTimerFactory()->createTimer(5000); - m_timer->onTick.connect(boost::bind(&SMSNetworkPlugin::handleSMSDir, this)); - m_timer->start(); + m_timer = std::make_shared(io_context, boost::posix_time::seconds(5)); + m_timer->async_wait(boost::bind(&SMSNetworkPlugin::handleSMSDir, this)); // We're reusing our database model here. Buddies of user with JID INTERNAL_USER are there // to match received GSM messages from number N with the XMPP users who sent message to number N. @@ -144,7 +130,6 @@ class SMSNetworkPlugin : public NetworkPlugin { LOG4CXX_ERROR(logger, "Error when removing the SMS: " << ex.what() << "."); } } - m_timer->start(); } void sendSMS(const std::string &to, const std::string &msg) { @@ -165,15 +150,6 @@ class SMSNetworkPlugin : public NetworkPlugin { myfile.close(); } - void sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); - } - - void _handleDataRead(std::shared_ptr data) { - std::string d(data->begin(), data->end()); - handleDataRead(d); - } - void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings) { UserInfo info; if (!storageBackend->getUser(user, info)) { @@ -228,11 +204,6 @@ class SMSNetworkPlugin : public NetworkPlugin { void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups) { } - - - private: - - Config *config; }; static void spectrum_sigchld_handler(int sig) @@ -282,10 +253,8 @@ int main (int argc, char* argv[]) { return -1; } - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new SMSNetworkPlugin(cfg, &eventLoop, storageBackend, host, port); - loop_->run(); + np = new SMSNetworkPlugin(cfg, storageBackend, host, port); + np->run(); return 0; } diff --git a/backends/swiften/CMakeLists.txt b/backends/swiften/CMakeLists.txt index fa8db5d87..f50b2d7e7 100644 --- a/backends/swiften/CMakeLists.txt +++ b/backends/swiften/CMakeLists.txt @@ -2,10 +2,6 @@ file(GLOB SRC *.cpp) add_executable(spectrum2_swiften_backend ${SRC}) -if(NOT WIN32) - target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) -else() - target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) -endif() +target_link_libraries(spectrum2_swiften_backend transport-plugin ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) install(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) diff --git a/backends/template/CMakeLists.txt b/backends/template/CMakeLists.txt index 37828416d..9b5e8da7d 100644 --- a/backends/template/CMakeLists.txt +++ b/backends/template/CMakeLists.txt @@ -2,14 +2,6 @@ file(GLOB SRC *.c *.cpp) add_executable(spectrum2_template_backend ${SRC}) -if(CMAKE_COMPILER_IS_GNUCXX) - if(NOT WIN32) - target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) - else() - target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) - endif() -else() - target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) -endif() +target_link_libraries(spectrum2_template_backend transport-plugin ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LOG4CXX_LIBRARIES}) -#install(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin) +#install(TARGETS spectrum2_template_backend RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) diff --git a/backends/template/main.cpp b/backends/template/main.cpp index 5f9df1a81..b6fd2f914 100644 --- a/backends/template/main.cpp +++ b/backends/template/main.cpp @@ -5,9 +5,6 @@ #include "transport/NetworkPlugin.h" #include "transport/Logging.h" -// Swiften -#include "Swiften/Swiften.h" - #ifndef _WIN32 // for signal handler #include "unistd.h" @@ -17,7 +14,6 @@ #endif // Boost #include -using namespace boost::filesystem; using namespace boost::program_options; using namespace Transport; @@ -60,9 +56,8 @@ int main (int argc, char* argv[]) { Logging::initBackendLogging(cfg); - Swift::SimpleEventLoop eventLoop; - Plugin p(cfg, &eventLoop, host, port); - eventLoop.run(); + Plugin p(cfg, host, port); + p.run(); return 0; } diff --git a/backends/template/plugin.cpp b/backends/template/plugin.cpp index 57b828487..23e1279a7 100644 --- a/backends/template/plugin.cpp +++ b/backends/template/plugin.cpp @@ -1,62 +1,58 @@ #include "plugin.h" // Transport includes #include "transport/Config.h" -#include "transport/NetworkPlugin.h" #include "transport/Logging.h" - -// Swiften -#include "Swiften/Swiften.h" +#include "transport/BoostNetworkPlugin.h" // Boost #include -using namespace boost::filesystem; +#include +using namespace boost::asio::ip; using namespace boost::program_options; using namespace Transport; DEFINE_LOGGER(logger, "Backend Template"); -Plugin::Plugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() { - this->config = config; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&Plugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); - - LOG4CXX_INFO(logger, "Starting the plugin."); -} - -// NetworkPlugin uses this method to send the data to networkplugin server -void Plugin::sendData(const std::string &string) { - m_conn->write(Swift::createSafeByteArray(string)); +Plugin::Plugin(Config *config, + const std::string &host, int port) + : BoostNetworkPlugin(config, host, port) { } -// This method has to call handleDataRead with all received data from network plugin server -void Plugin::_handleDataRead(std::shared_ptr data) { - std::string d(data->begin(), data->end()); - handleDataRead(d); +void Plugin::handleLoginRequest( + const std::string &user, const std::string &legacyName, + const std::string &password, + const std::map &settings) { + handleConnected(user); + LOG4CXX_INFO(logger, user << ": Added buddy - Echo."); + handleBuddyChanged(user, "echo", "Echo", std::vector(), + pbnetwork::STATUS_ONLINE); } -void Plugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings) { - handleConnected(user); - LOG4CXX_INFO(logger, user << ": Added buddy - Echo."); - handleBuddyChanged(user, "echo", "Echo", std::vector(), pbnetwork::STATUS_ONLINE); -} - -void Plugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) { -} +void Plugin::handleLogoutRequest(const std::string &user, + const std::string &legacyName) {} -void Plugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml, const std::string &id) { - LOG4CXX_INFO(logger, "Sending message from " << user << " to " << legacyName << "."); - if (legacyName == "echo") { - handleMessage(user, legacyName, message); - } +void Plugin::handleMessageSendRequest(const std::string &user, + const std::string &legacyName, + const std::string &message, + const std::string &xhtml, + const std::string &id) { + LOG4CXX_INFO(logger, + "Sending message from " << user << " to " << legacyName << "."); + if (legacyName == "echo") { + handleMessage(user, legacyName, message); + } } -void Plugin::handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups) { - LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << "."); - handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE); +void Plugin::handleBuddyUpdatedRequest(const std::string &user, + const std::string &buddyName, + const std::string &alias, + const std::vector &groups) { + LOG4CXX_INFO(logger, user << ": Added buddy " << buddyName << "."); + handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE); } -void Plugin::handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups) { +void Plugin::handleBuddyRemovedRequest(const std::string &user, + const std::string &buddyName, + const std::vector &groups) { } diff --git a/backends/template/plugin.h b/backends/template/plugin.h index be2d876d8..fe15a79c4 100644 --- a/backends/template/plugin.h +++ b/backends/template/plugin.h @@ -1,16 +1,15 @@ #pragma once -#include "Swiften/Swiften.h" +#include + +#include #include "transport/Config.h" -#include "transport/NetworkPlugin.h" +#include "transport/BoostNetworkPlugin.h" -class Plugin : public Transport::NetworkPlugin { +class Plugin : public Transport::BoostNetworkPlugin { public: - Plugin(Transport::Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port); - - // NetworkPlugin uses this method to send the data to networkplugin server - void sendData(const std::string &string); + Plugin(Transport::Config *config, const std::string &host, int port); void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings); @@ -21,14 +20,4 @@ class Plugin : public Transport::NetworkPlugin { void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector &groups); void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector &groups); - - private: - // This method has to call handleDataRead with all received data from network plugin server - void _handleDataRead(std::shared_ptr data); - - private: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr m_conn; - Transport::Config *config; }; diff --git a/backends/twitter/CMakeLists.txt b/backends/twitter/CMakeLists.txt index 93a3af353..2c667db63 100644 --- a/backends/twitter/CMakeLists.txt +++ b/backends/twitter/CMakeLists.txt @@ -8,7 +8,7 @@ find_package(CURL) if(CURL_FOUND) message(STATUS "Using curl ${CURL_VERSION_STRING}: ${CURL_INCLUDE_DIRS} ${CURL_LIBRARIES}") - target_link_libraries(spectrum2_twitter_backend transport JsonCpp::JsonCpp ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES}) + target_link_libraries(spectrum2_twitter_backend transport-plugin ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${LOG4CXX_LIBRARIES}) else() message(FATAL_ERROR "curl not found") endif() diff --git a/backends/twitter/HTTPRequest.h b/backends/twitter/HTTPRequest.h deleted file mode 100644 index 40db66a1e..000000000 --- a/backends/twitter/HTTPRequest.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HTTPREQ_H -#define HTTPREQ_H - -#include "curl/curl.h" -#include "transport/Logging.h" -#include -#include -#include - -class HTTPRequest -{ - CURL *curlhandle; - char curl_errorbuffer[1024]; - std::string error; - std::string callbackdata; - - static int curlCallBack(char* data, size_t size, size_t nmemb, HTTPRequest *obj); - - public: - HTTPRequest() { - curlhandle = NULL; - } - - ~HTTPRequest() { - if(curlhandle) { - curl_easy_cleanup(curlhandle); - curlhandle = NULL; - } - } - - bool init(); - void setProxy(std::string, std::string, std::string, std::string); - bool GET(std::string, std::string &); - std::string getCurlError() {return std::string(curl_errorbuffer);} -}; - -#endif diff --git a/backends/twitter/Requests/CreateFriendRequest.cpp b/backends/twitter/Requests/CreateFriendRequest.cpp index 650651a0f..296e0137f 100644 --- a/backends/twitter/Requests/CreateFriendRequest.cpp +++ b/backends/twitter/Requests/CreateFriendRequest.cpp @@ -1,5 +1,5 @@ #include "CreateFriendRequest.h" -#include "../HTTPRequest.h" +#include "transport/HTTPRequest.h" DEFINE_LOGGER(createFriendRequestLogger, "CreateFriendRequest") void CreateFriendRequest::run() diff --git a/backends/twitter/Requests/FetchFriends.cpp b/backends/twitter/Requests/FetchFriends.cpp index 1705b9088..4bd2a1419 100644 --- a/backends/twitter/Requests/FetchFriends.cpp +++ b/backends/twitter/Requests/FetchFriends.cpp @@ -1,5 +1,5 @@ #include "FetchFriends.h" -#include "../HTTPRequest.h" +#include "transport/HTTPRequest.h" DEFINE_LOGGER(fetchFriendsRequestLogger, "FetchFriends") diff --git a/backends/twitter/Requests/ProfileImageRequest.cpp b/backends/twitter/Requests/ProfileImageRequest.cpp index 9a42a4527..722810484 100644 --- a/backends/twitter/Requests/ProfileImageRequest.cpp +++ b/backends/twitter/Requests/ProfileImageRequest.cpp @@ -1,5 +1,5 @@ #include "ProfileImageRequest.h" -#include "../HTTPRequest.h" +#include "transport/HTTPRequest.h" DEFINE_LOGGER(profileImageRequestLogger, "ProfileImageRequest") void ProfileImageRequest::run() { diff --git a/backends/twitter/Requests/ProfileImageRequest.h b/backends/twitter/Requests/ProfileImageRequest.h index 0112c79ca..4ac25a826 100644 --- a/backends/twitter/Requests/ProfileImageRequest.h +++ b/backends/twitter/Requests/ProfileImageRequest.h @@ -9,7 +9,6 @@ #include #include #include -#include using namespace Transport; using namespace boost::program_options; diff --git a/backends/twitter/TwitterPlugin.cpp b/backends/twitter/TwitterPlugin.cpp index 59d901872..3208d9403 100644 --- a/backends/twitter/TwitterPlugin.cpp +++ b/backends/twitter/TwitterPlugin.cpp @@ -10,12 +10,15 @@ #include "Requests/DestroyFriendRequest.h" #include "Requests/RetweetRequest.h" #include "Requests/ProfileImageRequest.h" -#include "Swiften/StringCodecs/Hexify.h" + +#include +#include + +#include DEFINE_LOGGER(logger, "Twitter Backend"); TwitterPlugin *np = NULL; -Swift::SimpleEventLoop *loop_; // Event Loop const std::string OLD_APP_KEY = "PCWAdQpyyR12ezp2fVwEhw"; const std::string OLD_APP_SECRET = "EveLmCXJIg2R7BTCpm6OWV8YyX49nI0pxnYXh7JMvDg"; @@ -34,12 +37,29 @@ static int cmp(std::string a, std::string b) return 1; } +std::string get_sha1(const std::string& p_arg) +{ + boost::uuids::detail::sha1 sha1; + sha1.process_bytes(p_arg.data(), p_arg.size()); + unsigned hash[5] = {0}; + sha1.get_digest(hash); + + // Back to string + char buf[41] = {0}; + + for (int i = 0; i < 5; i++) + { + std::sprintf(buf + (i << 3), "%08x", hash[i]); + } + + return std::string(buf); +} + -TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port) : NetworkPlugin() +TwitterPlugin::TwitterPlugin(Config *config, StorageBackend *storagebackend, const std::string &host, int port) + : BoostNetworkPlugin(config, host, port) { - this->config = config; this->storagebackend = storagebackend; - this->m_firstPing = true; if (CONFIG_HAS_KEY(config, "twitter.consumer_key") == false) { consumerKey = "5mFePMiJi0KpeURONkelg"; @@ -68,26 +88,11 @@ TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, Stora OAUTH_SECRET = "twitter_oauth_secret"; MODE = "mode"; - m_factories = new Swift::BoostNetworkFactories(loop); - m_conn = m_factories->getConnectionFactory()->createConnection(); - m_conn->onDataRead.connect(boost::bind(&TwitterPlugin::_handleDataRead, this, _1)); - m_conn->connect(Swift::HostAddressPort(*(Swift::HostAddress::fromString(host)), port)); - - tp = new ThreadPool(loop_, 10); - - LOG4CXX_INFO(logger, "Fetch timeout is set to " << CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); - tweet_timer = m_factories->getTimerFactory()->createTimer(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); - message_timer = m_factories->getTimerFactory()->createTimer(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000)); - - tweet_timer->onTick.connect(boost::bind(&TwitterPlugin::pollForTweets, this)); - //message_timer->onTick.connect(boost::bind(&TwitterPlugin::pollForDirectMessages, this)); - - tweet_timer->start(); - message_timer->start(); - cryptoProvider = std::shared_ptr(Swift::PlatformCryptoProvider::create()); + tp = new ThreadPool(io_context, 10); - - LOG4CXX_INFO(logger, "Starting the plugin."); + tweet_timer = std::make_shared(io_context); + (*tweet_timer).async_wait(boost::bind(&TwitterPlugin::pollForTweets, this)); + //message_timer->async_wait(boost::bind(&TwitterPlugin::pollForDirectMessages, this)); } TwitterPlugin::~TwitterPlugin() @@ -95,29 +100,6 @@ TwitterPlugin::~TwitterPlugin() delete storagebackend; std::set::iterator it; for (it = onlineUsers.begin() ; it != onlineUsers.end() ; it++) delete userdb[*it].sessions; - delete tp; -} - -// Send data to NetworkPlugin server -void TwitterPlugin::sendData(const std::string &string) -{ - m_conn->write(Swift::createSafeByteArray(string)); -} - -// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class) -void TwitterPlugin::_handleDataRead(std::shared_ptr data) -{ - if (m_firstPing) { - m_firstPing = false; - // Users can join the network without registering if we allow - // one user to connect multiple IRC networks. - NetworkPlugin::PluginConfig cfg; - cfg.setNeedPassword(false); - sendConfig(cfg); - } - - std::string d(data->begin(), data->end()); - handleDataRead(d); } // User trying to login into his twitter account @@ -347,7 +329,9 @@ void TwitterPlugin::pollForTweets() boost::bind(&TwitterPlugin::displayTweets, this, _1, _2, _3, _4))); it++; } - tweet_timer->start(); + (*tweet_timer).expires_from_now(boost::posix_time::milliseconds(CONFIG_INT_DEFAULTED(config, "twitter.fetch_timeout", 90000))); + LOG4CXX_INFO(logger, "Fetch is scheduled to " << (*tweet_timer).expires_at()); + (*tweet_timer).async_wait(boost::bind(&TwitterPlugin::pollForTweets, this)); } void TwitterPlugin::pollForDirectMessages() @@ -360,7 +344,6 @@ void TwitterPlugin::pollForDirectMessages() boost::bind(&TwitterPlugin::directMessageResponse, this, _1, _2, _3, _4))); it++; } - message_timer->start(); } @@ -655,9 +638,13 @@ void TwitterPlugin::populateRoster(std::string &user, std::vector &friends if(userdb[user].twitterMode == MULTIPLECONTACT) { std::string lastTweet = friends[i].getLastStatus().getTweet(); - //LOG4CXX_INFO(logger, user << " - " << SHA(friendAvatars[i])) + + auto friendAvatarHash = get_sha1(friendAvatars[i]); + + LOG4CXX_INFO(logger, user << " - " << friendAvatarHash); + handleBuddyChanged(user, friends[i].getScreenName(), friends[i].getUserName(), std::vector(), - pbnetwork::STATUS_ONLINE, lastTweet, Swift::Hexify::hexify(cryptoProvider->getSHA1Hash(Swift::createByteArray(friendAvatars[i])))); + pbnetwork::STATUS_ONLINE, lastTweet, friendAvatarHash); } else if(userdb[user].twitterMode == CHATROOM) handleParticipantChanged(user, friends[i].getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE); @@ -831,7 +818,7 @@ void TwitterPlugin::createFriendResponse(std::string &user, User &frnd, std::str LOG4CXX_INFO(logger, user << " - " << frnd.getScreenName() << ", " << frnd.getProfileImgURL()); if(userdb[user].twitterMode == MULTIPLECONTACT) { - handleBuddyChanged(user, frnd.getScreenName(), frnd.getUserName(), std::vector(), pbnetwork::STATUS_ONLINE, "", Swift::byteArrayToString(cryptoProvider->getSHA1Hash(Swift::createByteArray(img)))); + handleBuddyChanged(user, frnd.getScreenName(), frnd.getUserName(), std::vector(), pbnetwork::STATUS_ONLINE, "", get_sha1(img)); } else if(userdb[user].twitterMode == CHATROOM) { handleParticipantChanged(user, frnd.getScreenName(), adminChatRoom, 0, pbnetwork::STATUS_ONLINE); } diff --git a/backends/twitter/TwitterPlugin.h b/backends/twitter/TwitterPlugin.h index 967df7fc3..139caeea4 100644 --- a/backends/twitter/TwitterPlugin.h +++ b/backends/twitter/TwitterPlugin.h @@ -1,7 +1,7 @@ #pragma once #include "transport/Config.h" -#include "transport/NetworkPlugin.h" +#include "transport/BoostNetworkPlugin.h" #include "transport/Logging.h" #include "transport/SQLite3Backend.h" #include "transport/MySQLBackend.h" @@ -9,7 +9,6 @@ #include "transport/StorageBackend.h" #include "transport/ThreadPool.h" -#include #ifndef _WIN32 #include "unistd.h" #include "signal.h" @@ -17,6 +16,8 @@ #include "sys/signal.h" #endif #include +#include +#include #include #include @@ -24,14 +25,12 @@ #include "TwitterResponseParser.h" #include -#include #include #include #include #include #include -#include -#include + using namespace boost::filesystem; using namespace boost::program_options; using namespace Transport; @@ -40,27 +39,15 @@ using namespace Transport; class TwitterPlugin; extern TwitterPlugin *np; -extern Swift::SimpleEventLoop *loop_; // Event Loop -class TwitterPlugin : public NetworkPlugin { +class TwitterPlugin : public BoostNetworkPlugin { public: - Swift::BoostNetworkFactories *m_factories; - Swift::BoostIOServiceThread m_boostIOServiceThread; - std::shared_ptr m_conn; - std::shared_ptr cryptoProvider; - Swift::Timer::ref tweet_timer; - Swift::Timer::ref message_timer; + std::shared_ptr tweet_timer; StorageBackend *storagebackend; - TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port); + TwitterPlugin(Config *config, StorageBackend *storagebackend, const std::string &host, int port); ~TwitterPlugin(); - - // Send data to NetworkPlugin server - void sendData(const std::string &string); - - // Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class) - void _handleDataRead(std::shared_ptr data); // User trying to login into his twitter account void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password, const std::map &settings); @@ -139,7 +126,6 @@ class TwitterPlugin : public NetworkPlugin { enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED}; enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM}; - Config *config; std::string adminLegacyName; std::string adminChatRoom; std::string adminNickName; @@ -174,5 +160,4 @@ class TwitterPlugin : public NetworkPlugin { UserData() { sessions = NULL; } }; std::map userdb; - bool m_firstPing; }; diff --git a/backends/twitter/libtwitcurl/oauthlib.h b/backends/twitter/libtwitcurl/oauthlib.h index 5401490b5..d7fb53426 100644 --- a/backends/twitter/libtwitcurl/oauthlib.h +++ b/backends/twitter/libtwitcurl/oauthlib.h @@ -3,7 +3,6 @@ #include "time.h" #include -#include #include #include #include diff --git a/backends/twitter/main.cpp b/backends/twitter/main.cpp index 5d4d61dad..9f273365b 100644 --- a/backends/twitter/main.cpp +++ b/backends/twitter/main.cpp @@ -52,11 +52,8 @@ int main (int argc, char* argv[]) { LOG4CXX_ERROR(logger, "Can't connect to database!"); return -1; } - - Swift::SimpleEventLoop eventLoop; - loop_ = &eventLoop; - np = new TwitterPlugin(cfg, &eventLoop, storagebackend, host, port); - loop_->run(); + np = new TwitterPlugin(cfg, storagebackend, host, port); + np->run(); return 0; } diff --git a/include/transport/BoostNetworkPlugin.h b/include/transport/BoostNetworkPlugin.h new file mode 100644 index 000000000..45c50b84f --- /dev/null +++ b/include/transport/BoostNetworkPlugin.h @@ -0,0 +1,45 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011-2023, Jan Kaluza + * + * 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 +#include +#include + +#include + +#include + +namespace Transport { + class BoostNetworkPlugin: public NetworkPlugin { + public: + BoostNetworkPlugin(Config *config, const std::string &host, int port); + void sendData(const std::string &string); + void handleExitRequest(); + void run(); + protected: + Transport::Config *config; + boost::asio::io_context io_context; + private: + std::shared_ptr socket_; + bool is_connected; + }; +} diff --git a/include/transport/HTTPRequest.h b/include/transport/HTTPRequest.h index ea3fd6473..ca12b78d4 100644 --- a/include/transport/HTTPRequest.h +++ b/include/transport/HTTPRequest.h @@ -1,73 +1,36 @@ +#ifndef HTTPREQ_H +#define HTTPREQ_H -#pragma once - -#include -#include +#include "curl/curl.h" #include "transport/Logging.h" -#include "transport/ThreadPool.h" #include -#include #include -#include - -namespace Transport { - -class HTTPRequest : public Thread { - public: - typedef enum { Get } Type; - typedef boost::function< void (HTTPRequest *, bool, Json::Value &json, const std::string &data) > Callback; - - HTTPRequest(ThreadPool *tp, Type type, const std::string &url, Callback callback); - HTTPRequest(Type type, const std::string &url); - - virtual ~HTTPRequest(); - - void setProxy(std::string, std::string, std::string, std::string); - bool execute(); - bool execute(Json::Value &json); - std::string getError() {return std::string(curl_errorbuffer);} - const std::string &getRawData() { - return m_data; - } - - void run(); - void finalize(); - const std::string &getURL() { - return m_url; - } - - boost::signals2::signal onRequestFinished; +class HTTPRequest +{ + CURL *curlhandle; + char curl_errorbuffer[1024]; + std::string error; + std::string callbackdata; - static void globalInit() { - curl_global_init(CURL_GLOBAL_ALL); - } + static int curlCallBack(char* data, size_t size, size_t nmemb, HTTPRequest *obj); - static void globalCleanup() { - curl_global_cleanup(); + public: + HTTPRequest() { + curlhandle = NULL; + } + + ~HTTPRequest() { + if(curlhandle) { + curl_easy_cleanup(curlhandle); + curlhandle = NULL; } + } - private: - bool init(); - bool GET(std::string url, std::string &output); - bool GET(std::string url, Json::Value &json); - - - CURL *curlhandle; - char curl_errorbuffer[1024]; - std::string error; - std::string callbackdata; - ThreadPool *m_tp; - std::string m_url; - bool m_ok; - Json::Value m_json; - std::string m_data; - Callback m_callback; - Type m_type; - - static int curlCallBack(char* data, size_t size, size_t nmemb, HTTPRequest *obj); - + bool init(); + void setProxy(std::string, std::string, std::string, std::string); + bool GET(std::string, std::string &); + std::string getCurlError() {return std::string(curl_errorbuffer);} }; -} - +#endif diff --git a/include/transport/HTTPRequestQueue.h b/include/transport/HTTPRequestQueue.h deleted file mode 100644 index 32475cfa1..000000000 --- a/include/transport/HTTPRequestQueue.h +++ /dev/null @@ -1,40 +0,0 @@ - -#pragma once - -#include "curl/curl.h" -#include "transport/Logging.h" -#include "transport/ThreadPool.h" -#include -#include -#include - -#include "Swiften/Network/Timer.h" - -namespace Transport { - -class HTTPRequest; -class Component; - -class HTTPRequestQueue { - public: - HTTPRequestQueue(Component *component, const std::string &user, int delayBetweenRequests = 1); - - virtual ~HTTPRequestQueue(); - - void queueRequest(HTTPRequest *req); - - void sendNextRequest(); - - private: - void handleRequestFinished(); - - private: - int m_delay; - std::queue m_queue; - HTTPRequest *m_req; - Swift::Timer::ref m_queueTimer; - std::string m_user; -}; - -} - diff --git a/include/transport/NetworkPlugin.h b/include/transport/NetworkPlugin.h index eecf9497d..2df1120d6 100644 --- a/include/transport/NetworkPlugin.h +++ b/include/transport/NetworkPlugin.h @@ -50,7 +50,6 @@ class NetworkPlugin { void setExtraFields(const std::vector &fields) { m_extraFields = fields; } void setRawXML(bool rawXML = false) { m_rawXML = rawXML; } void disableJIDEscaping() { m_disableJIDEscaping = true; } - private: bool m_needPassword; bool m_needRegistration; @@ -63,9 +62,6 @@ 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. @@ -267,7 +263,7 @@ class NetworkPlugin { virtual void handleExitRequest() { exit(1); } void handleDataRead(std::string &data); - virtual void sendData(const std::string &string) {} + virtual void sendData(const std::string &string) {}; void checkPing(); @@ -292,7 +288,6 @@ class NetworkPlugin { std::string m_data; bool m_pingReceived; double m_init_res; - }; } diff --git a/include/transport/ThreadPool.h b/include/transport/ThreadPool.h index 87939c2b0..a45aeab47 100644 --- a/include/transport/ThreadPool.h +++ b/include/transport/ThreadPool.h @@ -1,12 +1,12 @@ #pragma once +#include #include #include #include #include #include #include -#include "Swiften/EventLoop/EventLoop.h" namespace Transport { @@ -55,12 +55,12 @@ class ThreadPool boost::mutex count_lock; boost::mutex pool_lock; boost::mutex criticalregion; - Swift::EventLoop *loop; + boost::asio::io_context *loop; boost::signals2::signal < void () > onWorkerAvailable; public: - ThreadPool(Swift::EventLoop *loop, int maxthreads); + ThreadPool(const boost::asio::io_context &loop, int maxthreads); ~ThreadPool(); void runAsThread(Thread *t); int getActiveThreadCount(); diff --git a/libtransport/CMakeLists.txt b/libtransport/CMakeLists.txt index df830c82b..873a724f8 100644 --- a/libtransport/CMakeLists.txt +++ b/libtransport/CMakeLists.txt @@ -46,10 +46,6 @@ find_package(CURL) target_link_libraries(transport transport-plugin ${CURL_LIBRARIES} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY} ${PROTOBUF_LIBRARY} JsonCpp::JsonCpp) -if(WIN32) - target_link_libraries(transport psapi.lib bcrypt.lib) -endif() - if(PQXX_FOUND) target_link_libraries(transport ${PQXX_LIBRARIES} ${PQ_LIBRARY}) endif() diff --git a/libtransport/HTTPRequest.cpp b/libtransport/HTTPRequest.cpp deleted file mode 100644 index a3bcdb819..000000000 --- a/libtransport/HTTPRequest.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "transport/HTTPRequest.h" - -namespace Transport { - -DEFINE_LOGGER(httpRequestLogger, "HTTPRequest") - -HTTPRequest::HTTPRequest(ThreadPool *tp, Type type, const std::string &url, Callback callback) { - m_type = type; - m_url = url; - m_tp = tp; - m_callback = callback; - curlhandle = NULL; -} - -HTTPRequest::HTTPRequest(Type type, const std::string &url) { - m_type = type; - m_url = url; - m_tp = NULL; - curlhandle = NULL; -} - -HTTPRequest::~HTTPRequest() { - if (curlhandle) { - LOG4CXX_INFO(httpRequestLogger, "Cleaning up CURL handle"); - curl_easy_cleanup(curlhandle); - curlhandle = NULL; - } -} - -bool HTTPRequest::init() { - if (curlhandle) { - return true; - } - - curlhandle = curl_easy_init(); - if (curlhandle) { - curl_easy_setopt(curlhandle, CURLOPT_PROXY, NULL); - curl_easy_setopt(curlhandle, CURLOPT_PROXYUSERPWD, NULL); - curl_easy_setopt(curlhandle, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); - return true; - } - - LOG4CXX_ERROR(httpRequestLogger, "Couldn't Initialize curl!"); - return false; -} - -void HTTPRequest::setProxy(std::string IP, std::string port, std::string username, std::string password) { - if (curlhandle) { - std::string proxyIpPort = IP + ":" + port; - curl_easy_setopt(curlhandle, CURLOPT_PROXY, proxyIpPort.c_str()); - if (username.length() && password.length()) { - std::string proxyUserPass = username + ":" + password; - curl_easy_setopt(curlhandle, CURLOPT_PROXYUSERPWD, proxyUserPass.c_str()); - } - } else { - LOG4CXX_ERROR(httpRequestLogger, "Trying to set proxy while CURL isn't initialized"); - } -} - -int HTTPRequest::curlCallBack(char* data, size_t size, size_t nmemb, HTTPRequest* obj) { - int writtenSize = 0; - if (obj && data) { - obj->callbackdata.append(data, size*nmemb); - writtenSize = (int)(size*nmemb); - } - - return writtenSize; -} - -bool HTTPRequest::GET(std::string url, std::string &data) { - if (curlhandle) { - curl_easy_setopt(curlhandle, CURLOPT_CUSTOMREQUEST, NULL); - curl_easy_setopt(curlhandle, CURLOPT_ENCODING, ""); - - data = ""; - callbackdata = ""; - memset(curl_errorbuffer, 0, 1024); - - curl_easy_setopt(curlhandle, CURLOPT_ERRORBUFFER, curl_errorbuffer); - curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, curlCallBack); - curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, this); - - /* Set http request and url */ - curl_easy_setopt(curlhandle, CURLOPT_HTTPGET, 1); - curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 0); - curl_easy_setopt(curlhandle, CURLOPT_URL, url.c_str()); - - /* Send http request and return status*/ - if (CURLE_OK == curl_easy_perform(curlhandle)) { - data = callbackdata; - return true; - } - } else { - LOG4CXX_ERROR(httpRequestLogger, "CURL not initialized!"); - strcpy(curl_errorbuffer, "CURL not initialized!"); - } - LOG4CXX_ERROR(httpRequestLogger, "Error fetching " << url); - return false; -} - -bool HTTPRequest::GET(std::string url, Json::Value &json) { - if (!GET(url, m_data)) { - return false; - } - - Json::CharReaderBuilder rbuilder; - std::shared_ptr const reader(rbuilder.newCharReader()); - if (!reader->parse(m_data.c_str(), m_data.c_str() + m_data.size(), &json, NULL)) { - LOG4CXX_ERROR(httpRequestLogger, "Error while parsing JSON"); - LOG4CXX_ERROR(httpRequestLogger, m_data); - strcpy(curl_errorbuffer, "Error while parsing JSON"); - return false; - } - - return true; -} - -void HTTPRequest::run() { - if (!init()) { - m_ok = false; - return; - } - - switch (m_type) { - case Get: - m_ok = GET(m_url, m_json); - break; - } - - curl_easy_cleanup(curlhandle); - curlhandle = NULL; -} - -void HTTPRequest::finalize() { - m_callback(this, m_ok, m_json, m_data); - onRequestFinished(); -} - -bool HTTPRequest::execute() { - if (!m_tp) { - return false; - } - - m_tp->runAsThread(this); - return true; -} - -bool HTTPRequest::execute(Json::Value &json) { - init(); - switch (m_type) { - case Get: - m_ok = GET(m_url, json); - break; - } - - return m_ok; -} - -} diff --git a/libtransport/HTTPRequestQueue.cpp b/libtransport/HTTPRequestQueue.cpp deleted file mode 100644 index de298806a..000000000 --- a/libtransport/HTTPRequestQueue.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "transport/HTTPRequestQueue.h" -#include "transport/HTTPRequest.h" -#include "transport/Transport.h" - -namespace Transport { - -DEFINE_LOGGER(httpRequestQueueLogger, "HTTPRequestQueue") - -HTTPRequestQueue::HTTPRequestQueue(Component *component, const std::string &user, int delay) { - m_delay = delay; - m_req = NULL; - m_user = user; - - m_queueTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(500); - m_queueTimer->onTick.connect(boost::bind(&HTTPRequestQueue::sendNextRequest, this)); -} - -HTTPRequestQueue::~HTTPRequestQueue() { - m_queueTimer->stop(); - - if (m_req) { - m_req->onRequestFinished.disconnect(boost::bind(&HTTPRequestQueue::handleRequestFinished, this)); - } -} - -void HTTPRequestQueue::handleRequestFinished() { - m_req = NULL; - m_queueTimer->start(); -} - -void HTTPRequestQueue::sendNextRequest() { - if (m_queue.empty()) { - LOG4CXX_INFO(httpRequestQueueLogger, m_user << ": Queue is empty."); - m_req = NULL; - m_queueTimer->stop(); - return; - } - - if (m_req) { - LOG4CXX_INFO(httpRequestQueueLogger, m_user << ": There is already a request being handled."); - return; - } - - m_req = m_queue.front(); - m_queue.pop(); - - LOG4CXX_INFO(httpRequestQueueLogger, m_user << ": Starting request '" << m_req->getURL() << "'."); - m_req->onRequestFinished.connect(boost::bind(&HTTPRequestQueue::handleRequestFinished, this)); - m_req->execute(); -} - -void HTTPRequestQueue::queueRequest(HTTPRequest *req) { - m_queue.push(req); - - if (!m_req) { - sendNextRequest(); - } - else { - LOG4CXX_INFO(httpRequestQueueLogger, m_user << ": Request '" << req->getURL() << "' queued."); - } -} - - -} diff --git a/libtransport/OAuth2.cpp b/libtransport/OAuth2.cpp index bf0f0a592..f6b8e0c3e 100644 --- a/libtransport/OAuth2.cpp +++ b/libtransport/OAuth2.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace Transport { @@ -81,20 +82,21 @@ std::string OAuth2::requestToken(const std::string &code, std::string &token, st url += "&redirect_uri=" + Util::urlencode(m_redirectURL); } - Json::Value resp; - HTTPRequest req(HTTPRequest::Get, url); - if (!req.execute(resp)) { + std::string responseData; + HTTPRequest req; + req.init(); + if (!req.GET(url, responseData)) { LOG4CXX_ERROR(oauth2Logger, url); - LOG4CXX_ERROR(oauth2Logger, req.getError()); - return req.getError(); + LOG4CXX_ERROR(oauth2Logger, req.getCurlError()); + return req.getCurlError(); } - LOG4CXX_ERROR(oauth2Logger, req.getRawData()); + LOG4CXX_ERROR(oauth2Logger, responseData); + Json::Value resp(responseData); Json::Value& access_token = resp["access_token"]; if (!access_token.isString()) { LOG4CXX_ERROR(oauth2Logger, "No 'access_token' object in the reply."); LOG4CXX_ERROR(oauth2Logger, url); - LOG4CXX_ERROR(oauth2Logger, req.getRawData()); return "No 'access_token' object in the reply."; } @@ -102,7 +104,6 @@ std::string OAuth2::requestToken(const std::string &code, std::string &token, st if (token.empty()) { LOG4CXX_ERROR(oauth2Logger, "Empty 'access_token' object in the reply."); LOG4CXX_ERROR(oauth2Logger, url); - LOG4CXX_ERROR(oauth2Logger, req.getRawData()); return "Empty 'access_token' object in the reply."; } diff --git a/libtransport/WebSocketClient.cpp b/libtransport/WebSocketClient.cpp index e643b1ce8..f64065451 100644 --- a/libtransport/WebSocketClient.cpp +++ b/libtransport/WebSocketClient.cpp @@ -32,7 +32,7 @@ namespace Transport { -DEFINE_LOGGER(logger, "WebSocketClient"); +DEFINE_LOGGER(wsLogger, "WebSocketClient"); WebSocketClient::WebSocketClient(Component *component, const std::string &user) { m_component = component; @@ -58,7 +58,7 @@ WebSocketClient::~WebSocketClient() { } void WebSocketClient::connectServer() { - LOG4CXX_INFO(logger, m_user << ": Starting DNS query for " << m_host << " " << m_path); + LOG4CXX_INFO(wsLogger, m_user << ": Starting DNS query for " << m_host << " " << m_path); m_upgraded = false; m_buffer.clear(); @@ -120,7 +120,7 @@ void WebSocketClient::write(const std::string &data) { + payload)); } - LOG4CXX_INFO(logger, m_user << ": > " << data); + LOG4CXX_INFO(wsLogger, m_user << ": > " << data); } void WebSocketClient::handleDataRead(std::shared_ptr data) { @@ -159,7 +159,7 @@ void WebSocketClient::handleDataRead(std::shared_ptr data) // This seems to be Slack bug... sometimes we receive 0x89 followed by 0x81 // For now, in that case we will just ignore the 0x89 and skip it... if (opcode == 9 && mask && size7 == 1) { - LOG4CXX_WARN(logger, m_user << ": Applying Slack workaround because of partial data received from server"); + LOG4CXX_WARN(wsLogger, m_user << ": Applying Slack workaround because of partial data received from server"); m_buffer.erase(0, 1); continue; } @@ -167,7 +167,7 @@ void WebSocketClient::handleDataRead(std::shared_ptr data) unsigned int size = (size16 == 0 ? size7 : size16); if (m_buffer.size() >= size + header_size) { std::string payload = m_buffer.substr(header_size, size); - LOG4CXX_INFO(logger, m_user << ": < " << payload); + LOG4CXX_INFO(wsLogger, m_user << ": < " << payload); onPayloadReceived(payload); m_buffer.erase(0, size + header_size); @@ -187,12 +187,12 @@ void WebSocketClient::handleDataRead(std::shared_ptr data) void WebSocketClient::handleConnected(bool error) { if (error) { - LOG4CXX_ERROR(logger, "Connection to " << m_host << " failed. Will reconnect in 1 second."); + LOG4CXX_ERROR(wsLogger, "Connection to " << m_host << " failed. Will reconnect in 1 second."); m_reconnectTimer->start(); return; } - LOG4CXX_INFO(logger, m_user << ": Connected to " << m_host); + LOG4CXX_INFO(wsLogger, m_user << ": Connected to " << m_host); std::string req = ""; req += "GET " + m_path + " HTTP/1.1\r\n"; @@ -211,20 +211,20 @@ void WebSocketClient::handleDisconnected(const boost::optionalstart(); } void WebSocketClient::handleDNSResult(const std::vector &addrs, boost::optional error) { if (error) { - LOG4CXX_ERROR(logger, m_user << ": DNS resolving error. Will try again in 1 second."); + LOG4CXX_ERROR(wsLogger, m_user << ": DNS resolving error. Will try again in 1 second."); m_reconnectTimer->start(); return; } if (addrs.empty()) { - LOG4CXX_ERROR(logger, m_user << ": DNS name cannot be resolved. Will try again in 1 second."); + LOG4CXX_ERROR(wsLogger, m_user << ": DNS name cannot be resolved. Will try again in 1 second."); m_reconnectTimer->start(); return; } diff --git a/plugin/cpp/BoostNetworkPlugin.cpp b/plugin/cpp/BoostNetworkPlugin.cpp new file mode 100644 index 000000000..ade7c6514 --- /dev/null +++ b/plugin/cpp/BoostNetworkPlugin.cpp @@ -0,0 +1,76 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011-2023, Jan Kaluza + * + * 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/BoostNetworkPlugin.h" +#include "transport/Logging.h" + +#include + +DEFINE_LOGGER(pluginLogger, "Backend"); + +namespace Transport { +BoostNetworkPlugin::BoostNetworkPlugin(Config *config, const std::string &host, + int port) + : NetworkPlugin(), io_context() { + this->config = config; + LOG4CXX_INFO(pluginLogger, "Starting the plugin."); + boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(host), port); + socket_ = std::make_shared(io_context); + socket_.get()->async_connect(ep, [&](boost::system::error_code ec) { + if (!ec) { + LOG4CXX_INFO(pluginLogger, "Connected " << ep.address().to_string()); + this->is_connected = true; + NetworkPlugin::PluginConfig cfg; + cfg.setRawXML(false); + cfg.setNeedRegistration(false); + sendConfig(cfg); + boost::asio::streambuf sb; + boost::system::error_code ec; + while (is_connected && + boost::asio::read(*socket_, sb, boost::asio::transfer_at_least(1), + ec)) { + if (ec) { + LOG4CXX_ERROR(pluginLogger, "Connection read error: " << ec.message()); + break; + } else { + std::string s((std::istreambuf_iterator(&sb)), + std::istreambuf_iterator()); + handleDataRead(s); + } + } + } else { + LOG4CXX_ERROR(pluginLogger, "Connection error: " << ec.message()); + } + }); +} +// NetworkPlugin uses this method to send the data to networkplugin server +void BoostNetworkPlugin::sendData(const std::string &string) { + boost::asio::write(*socket_, boost::asio::buffer(string)); +} +void BoostNetworkPlugin::handleExitRequest() { + this->is_connected = false; + this->io_context.stop(); +} + +void BoostNetworkPlugin::run() { + boost::thread thread([&]() { io_context.run(); }); + thread.join(); +} +} // namespace Transport diff --git a/plugin/cpp/CMakeLists.txt b/plugin/cpp/CMakeLists.txt index 370d02b5e..a1f28f7f8 100644 --- a/plugin/cpp/CMakeLists.txt +++ b/plugin/cpp/CMakeLists.txt @@ -18,12 +18,15 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif() endif() +target_link_libraries(transport-plugin JsonCpp::JsonCpp ${CMAKE_THREAD_LIBS_INIT}) + +find_package(CURL) + if(NOT WIN32) - target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES}) + target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES}) else() - target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib) + target_link_libraries(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ${PQXX_LIBRARIES} ${CURL_LIBRARIES} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} psapi.lib bcrypt.lib ws2_32.lib) endif() - set_target_properties(transport-plugin PROPERTIES VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION} ) diff --git a/backends/twitter/HTTPRequest.cpp b/plugin/cpp/HTTPRequest.cpp similarity index 98% rename from backends/twitter/HTTPRequest.cpp rename to plugin/cpp/HTTPRequest.cpp index 9e9dd09ee..33efef15f 100644 --- a/backends/twitter/HTTPRequest.cpp +++ b/plugin/cpp/HTTPRequest.cpp @@ -1,4 +1,4 @@ -#include "HTTPRequest.h" +#include "transport/HTTPRequest.h" DEFINE_LOGGER(httpRequestLogger, "HTTPRequest") bool HTTPRequest::init() diff --git a/plugin/cpp/MemoryUsage.cpp b/plugin/cpp/MemoryUsage.cpp index e5383f6ec..db92d9c9b 100644 --- a/plugin/cpp/MemoryUsage.cpp +++ b/plugin/cpp/MemoryUsage.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/libtransport/MySQLBackend.cpp b/plugin/cpp/MySQLBackend.cpp similarity index 100% rename from libtransport/MySQLBackend.cpp rename to plugin/cpp/MySQLBackend.cpp diff --git a/libtransport/PQXXBackend.cpp b/plugin/cpp/PQXXBackend.cpp similarity index 100% rename from libtransport/PQXXBackend.cpp rename to plugin/cpp/PQXXBackend.cpp diff --git a/libtransport/SQLite3Backend.cpp b/plugin/cpp/SQLite3Backend.cpp similarity index 100% rename from libtransport/SQLite3Backend.cpp rename to plugin/cpp/SQLite3Backend.cpp diff --git a/libtransport/StorageBackend.cpp b/plugin/cpp/StorageBackend.cpp similarity index 74% rename from libtransport/StorageBackend.cpp rename to plugin/cpp/StorageBackend.cpp index 2ee9171a3..a29afe51d 100644 --- a/libtransport/StorageBackend.cpp +++ b/plugin/cpp/StorageBackend.cpp @@ -4,9 +4,28 @@ #include "transport/SQLite3Backend.h" #include "transport/MySQLBackend.h" #include "transport/PQXXBackend.h" -#include "Swiften/StringCodecs/Base64.h" +#include +#include +#include +#include + +std::string decode64(const std::string &val) { + using namespace boost::archive::iterators; + using It = transform_width, 8, 6>; + return boost::algorithm::trim_right_copy_if(std::string(It(std::begin(val)), It(std::end(val))), [](char c) { + return c == '\0'; + }); +} + +std::string encode64(const std::string &val) { + using namespace boost::archive::iterators; + using It = base64_from_binary>; + auto tmp = std::string(It(std::begin(val)), It(std::end(val))); + return tmp.append((3 - val.size() % 3) % 3, '='); +} + namespace Transport { StorageBackend *StorageBackend::createBackend(Config *config, std::string &error) { @@ -59,12 +78,12 @@ std::string StorageBackend::encryptPassword(const std::string &password, const s encrypted[i] = c; } - encrypted = Swift::Base64::encode(Swift::createByteArray(encrypted)); + encrypted = encode64(encrypted); return encrypted; } std::string StorageBackend::decryptPassword(std::string &encrypted, const std::string &key) { - encrypted = Swift::byteArrayToString(Swift::Base64::decode(encrypted)); + encrypted = decode64(encrypted); std::string password; password.resize(encrypted.size()); for (unsigned i = 0; i < encrypted.size(); i++) { diff --git a/libtransport/ThreadPool.cpp b/plugin/cpp/ThreadPool.cpp similarity index 92% rename from libtransport/ThreadPool.cpp rename to plugin/cpp/ThreadPool.cpp index 24448442a..5b7ac595c 100644 --- a/libtransport/ThreadPool.cpp +++ b/plugin/cpp/ThreadPool.cpp @@ -1,13 +1,11 @@ #include "transport/ThreadPool.h" #include "transport/Logging.h" - namespace Transport { DEFINE_LOGGER(threadPoolLogger, "ThreadPool") -ThreadPool::ThreadPool(Swift::EventLoop *loop, int maxthreads) : MAX_THREADS(maxthreads) +ThreadPool::ThreadPool(const boost::asio::io_context &io_context, int maxthreads) : MAX_THREADS(maxthreads) { - this->loop = loop; activeThreads = 0; worker = (boost::thread **) malloc(sizeof(boost::thread *) * MAX_THREADS); for (int i=0 ; irun(); - loop->postEvent(boost::bind(&ThreadPool::cleandUp, this, t, wid), std::shared_ptr()); + cleandUp(t, wid); } } diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index cc1dba244..a4a22cb20 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -22,16 +22,9 @@ #include "transport/MemoryUsage.h" #include "transport/Logging.h" -#include +#include -#ifndef WIN32 -#include -#include -#include -#else -#include -#include -#include +#ifdef _WIN32 #define getpid _getpid #endif @@ -511,7 +504,6 @@ void NetworkPlugin::handleDataRead(std::string &data) { else { return; } - pbnetwork::WrapperMessage wrapper; if (wrapper.ParseFromArray(&m_data[4], expected_size) == false) { m_data.erase(m_data.begin(), m_data.begin() + 4 + expected_size); @@ -573,7 +565,7 @@ void NetworkPlugin::handleDataRead(std::string &data) { break; default: return; - } + } } } diff --git a/spectrum/src/CMakeLists.txt b/spectrum/src/CMakeLists.txt index 8779129c1..147529694 100644 --- a/spectrum/src/CMakeLists.txt +++ b/spectrum/src/CMakeLists.txt @@ -6,7 +6,6 @@ add_subdirectory(frontends) if(WIN32) file(GLOB WIN_SRC win32/*.cpp) include_directories(win32) - include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3") add_executable(spectrum2 ${SRC} ${WIN_SRC}) else() add_executable(spectrum2 ${SRC}) @@ -16,7 +15,11 @@ if (ENABLE_PURPLE AND PURPLE_FOUND) add_dependencies(spectrum2 spectrum2_libpurple_backend) endif() -target_link_libraries(spectrum2 transport spectrum2-xmpp-frontend spectrum2-slack-frontend ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY}) +target_link_libraries(spectrum2 transport spectrum2-xmpp-frontend ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY}) + +if(ENABLE_SLACK_FRONTEND) + target_link_libraries(spectrum2 spectrum2-slack-frontend) +endif() if(NOT MSVC AND NOT APPLE) # export all symbols (used for loading frontends) diff --git a/spectrum/src/frontends/CMakeLists.txt b/spectrum/src/frontends/CMakeLists.txt index eb6249560..44342804f 100644 --- a/spectrum/src/frontends/CMakeLists.txt +++ b/spectrum/src/frontends/CMakeLists.txt @@ -1,2 +1,4 @@ add_subdirectory(xmpp) +if(ENABLE_SLACK_FRONTEND) add_subdirectory(slack) +endif() diff --git a/spectrum/src/frontends/xmpp/XMPPFrontend.cpp b/spectrum/src/frontends/xmpp/XMPPFrontend.cpp index 399e01d5b..da327111b 100644 --- a/spectrum/src/frontends/xmpp/XMPPFrontend.cpp +++ b/spectrum/src/frontends/xmpp/XMPPFrontend.cpp @@ -145,7 +145,7 @@ void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Net } else { - LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled."); + LOG4CXX_INFO(logger, "No PKCS#12 certificate used. TLS is disabled."); } // m_server->start(); m_stanzaChannel = m_server->getStanzaChannel(); diff --git a/spectrum/src/frontends/xmpp/gatewayresponder.cpp b/spectrum/src/frontends/xmpp/gatewayresponder.cpp index 5698f8504..917aadcfe 100644 --- a/spectrum/src/frontends/xmpp/gatewayresponder.cpp +++ b/spectrum/src/frontends/xmpp/gatewayresponder.cpp @@ -63,7 +63,7 @@ bool GatewayResponder::handleSetRequest(const Swift::JID& from, const Swift::JID // This code is here to workaround Gajim (and probably other clients bug too) bug // https://trac.gajim.org/ticket/7277 if (prompt.find("\\40") != std::string::npos) { - LOG4CXX_WARN(gatewayResponderLogger, from.toString() << " Received already escaped JID " << prompt << ". Not escaping again."); + LOG4CXX_INFO(gatewayResponderLogger, from.toString() << " Received already escaped JID " << prompt << ". Not escaping again."); escaped = prompt; } diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index ba2e98c2e..8c4171089 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -14,7 +14,9 @@ #include "transport/Logging.h" #include "transport/Frontend.h" #include "frontends/xmpp/XMPPFrontendPlugin.h" +#ifdef ENABLE_SLACK_FRONTEND #include "frontends/slack/SlackFrontendPlugin.h" +#endif #include "Swiften/EventLoop/SimpleEventLoop.h" #include "Swiften/Network/BoostNetworkFactories.h" #include diff --git a/tests/libtransport/CMakeLists.txt b/tests/libtransport/CMakeLists.txt index 5b36e5b83..c0f8950e8 100644 --- a/tests/libtransport/CMakeLists.txt +++ b/tests/libtransport/CMakeLists.txt @@ -17,14 +17,20 @@ endif() file(GLOB HEADERS ../../include/transport/*.h) include_directories(../../spectrum/src/frontends/xmpp/) +if(ENABLE_SLACK_FRONTEND) +file(GLOB SRC slack/*.cpp slack/*.h) include_directories(../../spectrum/src/frontends/slack/) +endif() if(CPPUNIT_FOUND) file(GLOB SRC_TEST *.cpp) file(GLOB SRC_TEST_FRONTEND_XMPP ../../spectrum/src/frontends/xmpp/*.cpp) + add_executable(libtransport_test ${SRC_TEST} ${SRC_TEST_FRONTEND_XMPP}) + target_link_libraries(libtransport_test JsonCpp::JsonCpp) + if(ENABLE_SLACK_FRONTEND) file(GLOB SRC_TEST_FRONTEND_SLACK ../../spectrum/src/frontends/slack/*.cpp) - - add_executable(libtransport_test ${SRC_TEST} ${SRC_TEST_FRONTEND_XMPP} ${SRC_TEST_FRONTEND_SLACK}) + target_link_libraries(libtransport_test ${SRC_TEST_FRONTEND_SLACK}) + endif() set_target_properties(libtransport_test PROPERTIES COMPILE_DEFINITIONS LIBTRANSPORT_TEST=1) diff --git a/tests/libtransport/HTTPRequest.cpp b/tests/libtransport/HTTPRequest.cpp index 75b62a678..0fb8ec383 100644 --- a/tests/libtransport/HTTPRequest.cpp +++ b/tests/libtransport/HTTPRequest.cpp @@ -1,68 +1,35 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include "Swiften/Server/ServerStanzaChannel.h" -#include "Swiften/Server/ServerFromClientSession.h" -#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include #include "basictest.h" - -#include "transport/ThreadPool.h" #include "transport/HTTPRequest.h" using namespace Transport; class HTTPRequestTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(HTTPRequestTest); - CPPUNIT_TEST(GETThreadPool); + CPPUNIT_TEST(GET); CPPUNIT_TEST_SUITE_END(); public: - ThreadPool *tp; - bool result; void setUp (void) { setMeUp(); - tp = new ThreadPool(loop, 10); - result = false; } void tearDown (void) { tearMeDown(); - delete tp; } - void handleResult(HTTPRequest *req, bool ok, Json::Value &resp, const std::string &data) { - result = true; - } - void GET() { - Json::Value resp; - HTTPRequest *req = new HTTPRequest(tp, HTTPRequest::Get, "http://spectrum.im/params.json", boost::bind(&HTTPRequestTest::handleResult, this, _1, _2, _3, _4)); - req->execute(resp); - delete req; - } - - void GETThreadPool() { - HTTPRequest *req = new HTTPRequest(tp, HTTPRequest::Get, "http://spectrum.im/params.json", boost::bind(&HTTPRequestTest::handleResult, this, _1, _2, _3, _4)); - req->execute(); - - int i = 0; - while (result == false && i < 5) { - boost::system_time time = boost::get_system_time(); - time += boost::posix_time::seconds(1); - boost::thread::sleep(time); - loop->processEvents(); - i++; - } - CPPUNIT_ASSERT(result); + HTTPRequest req; + req.init(); + std::string responseData; + req.GET("http://spectrum.im/params.json", responseData); + Json::Value resp(responseData); + CPPUNIT_ASSERT(resp); } - }; CPPUNIT_TEST_SUITE_REGISTRATION (HTTPRequestTest); diff --git a/tests/libtransport/main.cpp b/tests/libtransport/main.cpp index 7f71c63f2..1f6e3a750 100644 --- a/tests/libtransport/main.cpp +++ b/tests/libtransport/main.cpp @@ -7,9 +7,8 @@ #include #ifdef WITH_LOG4CXX #include "log4cxx/logger.h" -#include "log4cxx/fileappender.h" +#include "log4cxx/consoleappender.h" #include "log4cxx/patternlayout.h" -#include "log4cxx/propertyconfigurator.h" using namespace log4cxx; #endif @@ -22,11 +21,12 @@ int main (int argc, char* argv[]) { #ifdef WITH_LOG4CXX LoggerPtr root = Logger::getRootLogger(); -#ifndef _MSC_VER - root->addAppender(new FileAppender(new PatternLayout("%d %-5p %c: %m%n"), "libtransport_test.log", false)); -#else - root->addAppender(new FileAppender(new PatternLayout(L"%d %-5p %c: %m%n"), L"libtransport_test.log", false)); -#endif + #ifdef _MSC_VER + root->addAppender(new ConsoleAppender(new PatternLayout(L"%d %-5p %c: %m%n"))); + #else + root->addAppender(new ConsoleAppender(new PatternLayout("%d %-5p %c: %m%n"))); + #endif + root->setLevel(log4cxx::Level::getWarn()); #endif std::vector testsToRun; @@ -39,8 +39,6 @@ int main (int argc, char* argv[]) testsToRun.push_back(""); } - Transport::HTTPRequest::globalInit(); - // informs test-listener about testresults CPPUNIT_NS :: TestResult testresult; @@ -61,7 +59,6 @@ int main (int argc, char* argv[]) } catch (const std::exception& e) { google::protobuf::ShutdownProtobufLibrary(); - Transport::HTTPRequest::globalCleanup(); std::cerr << "Error: " << e.what() << std::endl; return -1; } @@ -72,7 +69,6 @@ int main (int argc, char* argv[]) compileroutputter.write (); google::protobuf::ShutdownProtobufLibrary(); - Transport::HTTPRequest::globalCleanup(); // return 0 if tests were successful return collectedresults.wasSuccessful () ? 0 : 1; diff --git a/tests/libtransport/AdminInterface.cpp b/tests/libtransport/slack/AdminInterface.cpp similarity index 100% rename from tests/libtransport/AdminInterface.cpp rename to tests/libtransport/slack/AdminInterface.cpp diff --git a/tests/libtransport/BasicSlackTest.cpp b/tests/libtransport/slack/BasicSlackTest.cpp similarity index 100% rename from tests/libtransport/BasicSlackTest.cpp rename to tests/libtransport/slack/BasicSlackTest.cpp diff --git a/tests/libtransport/BasicSlackTest.h b/tests/libtransport/slack/BasicSlackTest.h similarity index 100% rename from tests/libtransport/BasicSlackTest.h rename to tests/libtransport/slack/BasicSlackTest.h diff --git a/tests/libtransport/SlackRTM.cpp b/tests/libtransport/slack/SlackRTM.cpp similarity index 100% rename from tests/libtransport/SlackRTM.cpp rename to tests/libtransport/slack/SlackRTM.cpp