diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8403622b..8a52d0e7 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,10 @@ All changes to this project will be documented in this file. +## [11.0.7] - 2020-12-25 + +(ws) trim ws dependencies, only depends on ixcrypto and ixcore + ## [11.0.6] - 2020-12-22 (build) rename makefile to makefile.dev to ease cmake BuildExternal (fix #261) diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index 739fcced..1e3b4517 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "11.0.6" +#define IX_WEBSOCKET_VERSION "11.0.7" diff --git a/ws/CMakeLists.txt b/ws/CMakeLists.txt index 2967d529..0fa8760c 100644 --- a/ws/CMakeLists.txt +++ b/ws/CMakeLists.txt @@ -11,9 +11,6 @@ if (NOT WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") endif() -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") -# set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") - set (CMAKE_CXX_STANDARD 11) option(USE_TLS "Add TLS support" ON) @@ -21,48 +18,21 @@ option(USE_TLS "Add TLS support" ON) include_directories(ws .) include_directories(ws ..) include_directories(ws ../third_party/cpp-linenoise) +include_directories(ws ../third_party/cli11) +include_directories(ws ../third_party/msgpack11) -find_package(JsonCpp) -if (NOT JSONCPP_FOUND) - include_directories(../third_party/jsoncpp) - set(JSONCPP_SOURCES ../third_party/jsoncpp/jsoncpp.cpp) -endif() - -if (USE_PYTHON) - find_package(Python COMPONENTS Development) - if (NOT Python_FOUND) - message(FATAL_ERROR "Python3 not found") - endif() - message("Python_FOUND:${Python_FOUND}") - message("Python_VERSION:${Python_VERSION}") - message("Python_Development_FOUND:${Python_Development_FOUND}") - message("Python_LIBRARIES:${Python_LIBRARIES}") -endif() +include(FetchContent) add_executable(ws ../third_party/msgpack11/msgpack11.cpp ../third_party/cpp-linenoise/linenoise.cpp - ${JSONCPP_SOURCES} ws.cpp) # library with the most dependencies come first -target_link_libraries(ws ixbots) -target_link_libraries(ws ixsnake) -target_link_libraries(ws ixcobra) -target_link_libraries(ws ixsentry) -target_link_libraries(ws ixredis) target_link_libraries(ws ixwebsocket) target_link_libraries(ws ixcrypto) target_link_libraries(ws ixcore) target_link_libraries(ws spdlog) -if (USE_PYTHON) - target_link_libraries(ws ${Python_LIBRARIES}) -endif() - -if (JSONCPP_FOUND) - target_include_directories(ws PUBLIC ${JSONCPP_INCLUDE_DIRS}) - target_link_libraries(ws ${JSONCPP_LIBRARIES}) -endif() install(TARGETS ws RUNTIME DESTINATION bin) diff --git a/ws/ws.cpp b/ws/ws.cpp index 053c791a..357868a1 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -8,30 +8,18 @@ // Main driver for websocket utilities // -#include "IXBench.h" #include "linenoise.hpp" -#include "nlohmann/json.hpp" +#include #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include -#include -#include -#include -#include +#include #include #include #include @@ -45,9 +33,8 @@ #include #include #include -#include +#include #include -#include #include #include #include @@ -64,7 +51,6 @@ #endif // for convenience -using json = nlohmann::json; using msgpack11::MsgPack; namespace @@ -647,27 +633,30 @@ namespace ix std::pair WebSocketChat::decodeMessage(const std::string& str) { - auto j = json::parse(str); + std::string errMsg; + MsgPack msg = MsgPack::parse(str, errMsg); - std::string msg_user = j["user"]; - std::string msg_text = j["text"]; + std::string msg_user = msg["user"].string_value(); + std::string msg_text = msg["text"].string_value(); return std::pair(msg_user, msg_text); } std::string WebSocketChat::encodeMessage(const std::string& text) { - json j; - j["user"] = _user; - j["text"] = text; + std::map obj; + obj["user"] = _user; + obj["text"] = text; - std::string output = j.dump(); + MsgPack msg(obj); + + std::string output = msg.dump(); return output; } void WebSocketChat::sendMessage(const std::string& text) { - _webSocket.sendText(encodeMessage(text)); + _webSocket.sendBinary(encodeMessage(text)); } int ws_chat_main(const std::string& url, const std::string& user) @@ -697,156 +686,6 @@ namespace ix return 0; } - int ws_cobra_metrics_publish_main(const ix::CobraConfig& config, - const std::string& channel, - const std::string& path, - bool stress) - { - std::atomic sentMessages(0); - std::atomic ackedMessages(0); - CobraConnection::setPublishTrackerCallback( - [&sentMessages, &ackedMessages](bool sent, bool acked) { - if (sent) sentMessages++; - if (acked) ackedMessages++; - }); - - CobraMetricsPublisher cobraMetricsPublisher; - cobraMetricsPublisher.enable(true); - cobraMetricsPublisher.configure(config, channel); - - while (!cobraMetricsPublisher.isAuthenticated()) - ; - - std::ifstream f(path); - std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - - Json::Value data; - Json::Reader reader; - if (!reader.parse(str, data)) return 1; - - if (!stress) - { - auto msgId = cobraMetricsPublisher.push(channel, data); - spdlog::info("Sent message: {}", msgId); - } - else - { - // Stress mode to try to trigger server and client bugs - while (true) - { - for (int i = 0; i < 1000; ++i) - { - cobraMetricsPublisher.push(channel, data); - } - - cobraMetricsPublisher.suspend(); - cobraMetricsPublisher.resume(); - - // FIXME: investigate why without this check we trigger a lock - while (!cobraMetricsPublisher.isAuthenticated()) - ; - } - } - - // Wait a bit for the message to get a chance to be sent - // there isn't any ack on publish right now so it's the best we can do - // FIXME: this comment is a lie now - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - spdlog::info("Sent messages: {} Acked messages {}", sentMessages, ackedMessages); - - return 0; - } - - int ws_cobra_publish_main(const ix::CobraConfig& config, - const std::string& channel, - const std::string& path) - { - std::ifstream f(path); - std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - - Json::Value data; - Json::Reader reader; - if (!reader.parse(str, data)) - { - spdlog::info("Input file is not a JSON file"); - return 1; - } - - ix::CobraConnection conn; - conn.configure(config); - - // Display incoming messages - std::atomic authenticated(false); - std::atomic messageAcked(false); - - conn.setEventCallback( - [&conn, &channel, &data, &authenticated, &messageAcked](const CobraEventPtr& event) { - if (event->type == ix::CobraEventType::Open) - { - spdlog::info("Publisher connected"); - - for (auto&& it : event->headers) - { - spdlog::info("{}: {}", it.first, it.second); - } - } - else if (event->type == ix::CobraEventType::Closed) - { - spdlog::info("Subscriber closed: {}", event->errMsg); - } - else if (event->type == ix::CobraEventType::Authenticated) - { - spdlog::info("Publisher authenticated"); - authenticated = true; - - Json::Value channels; - channels[0] = channel; - auto msgId = conn.publish(channels, data); - - spdlog::info("Published msg {}", msgId); - } - else if (event->type == ix::CobraEventType::Subscribed) - { - spdlog::info("Publisher: subscribed to channel {}", event->subscriptionId); - } - else if (event->type == ix::CobraEventType::UnSubscribed) - { - spdlog::info("Publisher: unsubscribed from channel {}", event->subscriptionId); - } - else if (event->type == ix::CobraEventType::Error) - { - spdlog::error("Publisher: error {}", event->errMsg); - } - else if (event->type == ix::CobraEventType::Published) - { - spdlog::info("Published message id {} acked", event->msgId); - messageAcked = true; - } - else if (event->type == ix::CobraEventType::Pong) - { - spdlog::info("Received websocket pong"); - } - else if (event->type == ix::CobraEventType::HandshakeError) - { - spdlog::error("Subscriber: Handshake error: {}", event->errMsg); - } - else if (event->type == ix::CobraEventType::AuthenticationError) - { - spdlog::error("Subscriber: Authentication error: {}", event->errMsg); - } - }); - - conn.connect(); - - while (!authenticated) - ; - while (!messageAcked) - ; - - return 0; - } - class WebSocketConnect { public: @@ -2229,199 +2068,6 @@ namespace ix return 0; } - int ws_redis_cli_main(const std::string& hostname, int port, const std::string& password) - { - RedisClient redisClient; - if (!redisClient.connect(hostname, port)) - { - spdlog::info("Cannot connect to redis host"); - return 1; - } - - if (!password.empty()) - { - std::string authResponse; - if (!redisClient.auth(password, authResponse)) - { - std::stringstream ss; - spdlog::info("Cannot authenticated to redis"); - return 1; - } - spdlog::info("Auth response: {}", authResponse); - } - - while (true) - { - // Read line - std::string line; - std::string prompt; - prompt += hostname; - prompt += ":"; - prompt += std::to_string(port); - prompt += "> "; - auto quit = linenoise::Readline(prompt.c_str(), line); - - if (quit) - { - break; - } - - std::stringstream ss(line); - std::vector args; - std::string arg; - - while (ss.good()) - { - ss >> arg; - args.push_back(arg); - } - - std::string errMsg; - auto response = redisClient.send(args, errMsg); - if (!errMsg.empty()) - { - spdlog::error("(error) {}", errMsg); - } - else - { - if (response.first != RespType::String) - { - std::cout << "(" << redisClient.getRespTypeDescription(response.first) << ")" - << " "; - } - - std::cout << response.second << std::endl; - } - - linenoise::AddHistory(line.c_str()); - } - - return 0; - } - - int ws_redis_publish_main(const std::string& hostname, - int port, - const std::string& password, - const std::string& channel, - const std::string& message, - int count) - { - RedisClient redisClient; - if (!redisClient.connect(hostname, port)) - { - spdlog::info("Cannot connect to redis host"); - return 1; - } - - if (!password.empty()) - { - std::string authResponse; - if (!redisClient.auth(password, authResponse)) - { - std::stringstream ss; - spdlog::info("Cannot authenticated to redis"); - return 1; - } - spdlog::info("Auth response: {}", authResponse); - } - - std::string errMsg; - for (int i = 0; i < count; i++) - { - if (!redisClient.publish(channel, message, errMsg)) - { - spdlog::error("Error publishing to channel {} error {}", channel, errMsg); - return 1; - } - } - - return 0; - } - - int ws_redis_server_main(int port, const std::string& hostname) - { - spdlog::info("Listening on {}:{}", hostname, port); - - ix::RedisServer server(port, hostname); - - auto res = server.listen(); - if (!res.first) - { - spdlog::info(res.second); - return 1; - } - - server.start(); - server.wait(); - - return 0; - } - - int ws_redis_subscribe_main(const std::string& hostname, - int port, - const std::string& password, - const std::string& channel, - bool verbose) - { - RedisClient redisClient; - if (!redisClient.connect(hostname, port)) - { - spdlog::info("Cannot connect to redis host"); - return 1; - } - - if (!password.empty()) - { - std::string authResponse; - if (!redisClient.auth(password, authResponse)) - { - std::stringstream ss; - spdlog::info("Cannot authenticated to redis"); - return 1; - } - spdlog::info("Auth response: {}", authResponse); - } - - std::atomic msgPerSeconds(0); - std::atomic msgCount(0); - - auto callback = [&msgPerSeconds, &msgCount, verbose](const std::string& message) { - if (verbose) - { - spdlog::info("recived: {}", message); - } - - msgPerSeconds++; - msgCount++; - }; - - auto responseCallback = [](const std::string& redisResponse) { - spdlog::info("Redis subscribe response: {}", redisResponse); - }; - - auto timer = [&msgPerSeconds, &msgCount] { - while (true) - { - spdlog::info("#messages {} msg/s {}", msgCount, msgPerSeconds); - - msgPerSeconds = 0; - auto duration = std::chrono::seconds(1); - std::this_thread::sleep_for(duration); - } - }; - - std::thread t(timer); - - spdlog::info("Subscribing to {} ...", channel); - if (!redisClient.subscribe(channel, responseCallback, callback)) - { - spdlog::info("Error subscribing to channel {}", channel); - return 1; - } - - return 0; - } - class WebSocketSender { public: @@ -2707,132 +2353,6 @@ namespace ix return 0; } - int ws_sentry_minidump_upload(const std::string& metadataPath, - const std::string& minidump, - const std::string& project, - const std::string& key, - bool verbose) - { - SentryClient sentryClient((std::string())); - - // Read minidump file from disk - std::string minidumpBytes = readBytes(minidump); - - // Read json data - std::string sentryMetadata = readBytes(metadataPath); - - std::atomic done(false); - - sentryClient.uploadMinidump( - sentryMetadata, - minidumpBytes, - project, - key, - verbose, - [verbose, &done](const HttpResponsePtr& response) { - if (verbose) - { - for (auto it : response->headers) - { - spdlog::info("{}: {}", it.first, it.second); - } - - spdlog::info("Upload size: {}", response->uploadSize); - spdlog::info("Download size: {}", response->downloadSize); - - spdlog::info("Status: {}", response->statusCode); - if (response->errorCode != HttpErrorCode::Ok) - { - spdlog::info("error message: {}", response->errorMsg); - } - - if (response->headers["Content-Type"] != "application/octet-stream") - { - spdlog::info("body: {}", response->body); - } - } - - if (response->statusCode != 200) - { - spdlog::error("Error sending data to sentry: {}", response->statusCode); - spdlog::error("Status: {}", response->statusCode); - spdlog::error("Response: {}", response->body); - } - else - { - spdlog::info("Event sent to sentry"); - } - - done = true; - }); - - int i = 0; - - while (!done) - { - std::chrono::duration duration(10); - std::this_thread::sleep_for(duration); - - if (i++ > 5000) break; // wait 5 seconds max - } - - if (!done) - { - spdlog::error("Error: timing out trying to sent a crash to sentry"); - } - - return 0; - } - - int ws_snake_main(int port, - const std::string& hostname, - const std::string& redisHosts, - int redisPort, - const std::string& redisPassword, - bool verbose, - const std::string& appsConfigPath, - const SocketTLSOptions& socketTLSOptions, - bool disablePong, - const std::string& republishChannel) - { - snake::AppConfig appConfig; - appConfig.port = port; - appConfig.hostname = hostname; - appConfig.verbose = verbose; - appConfig.redisPort = redisPort; - appConfig.redisPassword = redisPassword; - appConfig.socketTLSOptions = socketTLSOptions; - appConfig.disablePong = disablePong; - appConfig.republishChannel = republishChannel; - - // Parse config file - auto res = readAsString(appsConfigPath); - bool found = res.first; - if (!found) - { - spdlog::error("Cannot read content of {}", appsConfigPath); - return 1; - } - - auto apps = nlohmann::json::parse(res.second); - appConfig.apps = apps["apps"]; - - std::string token; - std::stringstream tokenStream(redisHosts); - while (std::getline(tokenStream, token, ';')) - { - appConfig.redisHosts.push_back(token); - } - - // Display config on the terminal for debugging - dumpConfig(appConfig); - - snake::SnakeServer snakeServer(appConfig); - snakeServer.runForever(); - - return 0; // should never reach this - } - int ws_transfer_main(int port, const std::string& hostname, const ix::SocketTLSOptions& tlsOptions) @@ -3030,22 +2550,10 @@ int main(int argc, char** argv) std::string filter; std::string position; std::string message; - std::string password; - std::string prefix("ws.test.v0"); - std::string fields; - std::string gauge; std::string timer; - std::string dsn; - std::string redisHosts("127.0.0.1"); - std::string redisPassword; - std::string appsConfigPath("appsConfig.json"); std::string configPath; std::string subprotocol; std::string remoteHost; - std::string minidump; - std::string metadata; - std::string project; - std::string key; std::string logfile; std::string moduleName; std::string republishChannel; @@ -3055,8 +2563,6 @@ int main(int argc, char** argv) std::string filename; std::string httpHeaderAuthorization; ix::SocketTLSOptions tlsOptions; - ix::CobraConfig cobraConfig; - ix::CobraBotConfig cobraBotConfig; std::string ciphers; std::string redirectUrl; bool headersOnly = false; @@ -3079,8 +2585,6 @@ int main(int argc, char** argv) bool disablePong = false; bool debug = false; int port = 8008; - int redisPort = 6379; - int statsdPort = 8125; int connectTimeOut = 60; int transferTimeout = 1800; int maxRedirects = 5; @@ -3110,32 +2614,6 @@ int main(int argc, char** argv) app->add_flag("--verify_none", verifyNone, "Disable peer cert verification"); }; - auto addCobraConfig = [&cobraConfig](CLI::App* app) { - app->add_option("--appkey", cobraConfig.appkey, "Appkey")->required(); - app->add_option("--endpoint", cobraConfig.endpoint, "Endpoint")->required(); - app->add_option("--rolename", cobraConfig.rolename, "Role name")->required(); - app->add_option("--rolesecret", cobraConfig.rolesecret, "Role secret")->required(); - }; - - auto addCobraBotConfig = [&cobraBotConfig](CLI::App* app) { - app->add_option("--appkey", cobraBotConfig.cobraConfig.appkey, "Appkey")->required(); - app->add_option("--endpoint", cobraBotConfig.cobraConfig.endpoint, "Endpoint")->required(); - app->add_option("--rolename", cobraBotConfig.cobraConfig.rolename, "Role name")->required(); - app->add_option("--rolesecret", cobraBotConfig.cobraConfig.rolesecret, "Role secret") - ->required(); - app->add_option("--channel", cobraBotConfig.channel, "Channel")->required(); - app->add_option("--filter", cobraBotConfig.filter, "Filter"); - app->add_option("--position", cobraBotConfig.position, "Position"); - app->add_option("--runtime", cobraBotConfig.runtime, "Runtime"); - app->add_option("--heartbeat", cobraBotConfig.enableHeartbeat, "Runtime"); - app->add_option("--heartbeat_timeout", cobraBotConfig.heartBeatTimeout, "Runtime"); - app->add_flag( - "--limit_received_events", cobraBotConfig.limitReceivedEvents, "Max events per minute"); - app->add_option( - "--max_events_per_minute", cobraBotConfig.maxEventsPerMinute, "Max events per minute"); - app->add_option("--batch_size", cobraBotConfig.batchSize, "Subscription batch size"); - }; - app.add_flag("--version", version, "Print ws version"); app.add_option("--logfile", logfile, "path where all logs will be redirected"); @@ -3250,129 +2728,6 @@ int main(int argc, char** argv) httpClientApp->add_option("--transfer-timeout", transferTimeout, "Transfer timeout"); addTLSOptions(httpClientApp); - CLI::App* redisCliApp = app.add_subcommand("redis_cli", "Redis cli"); - redisCliApp->fallthrough(); - redisCliApp->add_option("--port", redisPort, "Port"); - redisCliApp->add_option("--host", hostname, "Hostname"); - redisCliApp->add_option("--password", password, "Password"); - - CLI::App* redisPublishApp = app.add_subcommand("redis_publish", "Redis publisher"); - redisPublishApp->fallthrough(); - redisPublishApp->add_option("--port", redisPort, "Port"); - redisPublishApp->add_option("--host", hostname, "Hostname"); - redisPublishApp->add_option("--password", password, "Password"); - redisPublishApp->add_option("channel", channel, "Channel")->required(); - redisPublishApp->add_option("message", message, "Message")->required(); - redisPublishApp->add_option("-c", count, "Count"); - - CLI::App* redisSubscribeApp = app.add_subcommand("redis_subscribe", "Redis subscriber"); - redisSubscribeApp->fallthrough(); - redisSubscribeApp->add_option("--port", redisPort, "Port"); - redisSubscribeApp->add_option("--host", hostname, "Hostname"); - redisSubscribeApp->add_option("--password", password, "Password"); - redisSubscribeApp->add_option("channel", channel, "Channel")->required(); - redisSubscribeApp->add_flag("-v", verbose, "Verbose"); - redisSubscribeApp->add_option("--pidfile", pidfile, "Pid file"); - - CLI::App* cobraSubscribeApp = app.add_subcommand("cobra_subscribe", "Cobra subscriber"); - cobraSubscribeApp->fallthrough(); - cobraSubscribeApp->add_option("--pidfile", pidfile, "Pid file"); - cobraSubscribeApp->add_flag("-q", quiet, "Quiet / only display stats"); - cobraSubscribeApp->add_flag("--fluentd", fluentd, "Write fluentd prefix"); - addTLSOptions(cobraSubscribeApp); - addCobraBotConfig(cobraSubscribeApp); - - CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher"); - cobraPublish->fallthrough(); - cobraPublish->add_option("--channel", channel, "Channel")->required(); - cobraPublish->add_option("--pidfile", pidfile, "Pid file"); - cobraPublish->add_option("path", path, "Path to the file to send") - ->required() - ->check(CLI::ExistingPath); - addTLSOptions(cobraPublish); - addCobraConfig(cobraPublish); - - CLI::App* cobraMetricsPublish = - app.add_subcommand("cobra_metrics_publish", "Cobra metrics publisher"); - cobraMetricsPublish->fallthrough(); - cobraMetricsPublish->add_option("--channel", channel, "Channel")->required(); - cobraMetricsPublish->add_option("--pidfile", pidfile, "Pid file"); - cobraMetricsPublish->add_option("path", path, "Path to the file to send") - ->required() - ->check(CLI::ExistingPath); - cobraMetricsPublish->add_flag("--stress", stress, "Stress mode"); - addTLSOptions(cobraMetricsPublish); - addCobraConfig(cobraMetricsPublish); - - CLI::App* cobra2statsd = app.add_subcommand("cobra_to_statsd", "Cobra to statsd"); - cobra2statsd->fallthrough(); - cobra2statsd->add_option("--host", hostname, "Statsd host"); - cobra2statsd->add_option("--port", statsdPort, "Statsd port"); - cobra2statsd->add_option("--prefix", prefix, "Statsd prefix"); - cobra2statsd->add_option("--fields", fields, "Extract fields for naming the event")->join(); - cobra2statsd->add_option("--gauge", gauge, "Value to extract, and use as a statsd gauge") - ->join(); - cobra2statsd->add_option("--timer", timer, "Value to extract, and use as a statsd timer") - ->join(); - cobra2statsd->add_flag("-v", verbose, "Verbose"); - cobra2statsd->add_option("--pidfile", pidfile, "Pid file"); - addTLSOptions(cobra2statsd); - addCobraBotConfig(cobra2statsd); - - CLI::App* cobra2cobra = app.add_subcommand("cobra_to_cobra", "Cobra to Cobra"); - cobra2cobra->fallthrough(); - cobra2cobra->add_option("--republish", republishChannel, "Republish channel"); - cobra2cobra->add_option("--publisher_rolename", publisherRolename, "Publisher Role name") - ->required(); - cobra2cobra->add_option("--publisher_rolesecret", publisherRolesecret, "Publisher Role secret") - ->required(); - cobra2cobra->add_flag("-q", quiet, "Quiet"); - addTLSOptions(cobra2cobra); - addCobraBotConfig(cobra2cobra); - - CLI::App* cobra2python = app.add_subcommand("cobra_to_python", "Cobra to python"); - cobra2python->fallthrough(); - cobra2python->add_option("--host", hostname, "Statsd host"); - cobra2python->add_option("--port", statsdPort, "Statsd port"); - cobra2python->add_option("--prefix", prefix, "Statsd prefix"); - cobra2python->add_option("--module", moduleName, "Python module"); - cobra2python->add_option("--pidfile", pidfile, "Pid file"); - addTLSOptions(cobra2python); - addCobraBotConfig(cobra2python); - - CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra to sentry"); - cobra2sentry->fallthrough(); - cobra2sentry->add_option("--dsn", dsn, "Sentry DSN"); - cobra2sentry->add_flag("-v", verbose, "Verbose"); - cobra2sentry->add_option("--pidfile", pidfile, "Pid file"); - addTLSOptions(cobra2sentry); - addCobraBotConfig(cobra2sentry); - - CLI::App* cobra2redisApp = - app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis"); - cobra2redisApp->fallthrough(); - cobra2redisApp->add_option("--pidfile", pidfile, "Pid file"); - cobra2redisApp->add_option("--hostname", hostname, "Redis hostname"); - cobra2redisApp->add_option("--port", redisPort, "Redis port"); - cobra2redisApp->add_flag("-v", verbose, "Verbose"); - addTLSOptions(cobra2redisApp); - addCobraBotConfig(cobra2redisApp); - - CLI::App* snakeApp = app.add_subcommand("snake", "Snake server"); - snakeApp->fallthrough(); - snakeApp->add_option("--port", port, "Connection url"); - snakeApp->add_option("--host", hostname, "Hostname"); - snakeApp->add_option("--pidfile", pidfile, "Pid file"); - snakeApp->add_option("--redis_hosts", redisHosts, "Redis hosts"); - snakeApp->add_option("--redis_port", redisPort, "Redis hosts"); - snakeApp->add_option("--redis_password", redisPassword, "Redis password"); - snakeApp->add_option("--apps_config_path", appsConfigPath, "Path to auth data") - ->check(CLI::ExistingPath); - snakeApp->add_option("--republish_channel", republishChannel, "Republish channel"); - snakeApp->add_flag("-v", verbose, "Verbose"); - snakeApp->add_flag("-d", disablePong, "Disable Pongs"); - addTLSOptions(snakeApp); - CLI::App* httpServerApp = app.add_subcommand("httpd", "HTTP server"); httpServerApp->fallthrough(); httpServerApp->add_option("--port", port, "Port"); @@ -3387,11 +2742,6 @@ int main(int argc, char** argv) autobahnApp->add_option("--url", url, "url"); autobahnApp->add_flag("-q", quiet, "Quiet"); - CLI::App* redisServerApp = app.add_subcommand("redis_server", "Redis server"); - redisServerApp->fallthrough(); - redisServerApp->add_option("--port", port, "Port"); - redisServerApp->add_option("--host", hostname, "Hostname"); - CLI::App* proxyServerApp = app.add_subcommand("proxy_server", "Proxy server"); proxyServerApp->fallthrough(); proxyServerApp->add_option("--port", port, "Port"); @@ -3403,18 +2753,6 @@ int main(int argc, char** argv) addGenericOptions(proxyServerApp); addTLSOptions(proxyServerApp); - CLI::App* minidumpApp = app.add_subcommand("upload_minidump", "Upload a minidump to sentry"); - minidumpApp->fallthrough(); - minidumpApp->add_option("--minidump", minidump, "Minidump path") - ->required() - ->check(CLI::ExistingPath); - minidumpApp->add_option("--metadata", metadata, "Metadata path") - ->required() - ->check(CLI::ExistingPath); - minidumpApp->add_option("--project", project, "Sentry Project")->required(); - minidumpApp->add_option("--key", key, "Sentry Key")->required(); - minidumpApp->add_flag("-v", verbose, "Verbose"); - CLI::App* dnsLookupApp = app.add_subcommand("dnslookup", "DNS lookup"); dnsLookupApp->fallthrough(); dnsLookupApp->add_option("host", hostname, "Hostname")->required(); @@ -3495,14 +2833,6 @@ int main(int argc, char** argv) spdlog::set_level(spdlog::level::info); } - // Cobra config - cobraConfig.webSocketPerMessageDeflateOptions = ix::WebSocketPerMessageDeflateOptions(true); - cobraConfig.socketTLSOptions = tlsOptions; - - cobraBotConfig.cobraConfig.webSocketPerMessageDeflateOptions = - ix::WebSocketPerMessageDeflateOptions(true); - cobraBotConfig.cobraConfig.socketTLSOptions = tlsOptions; - int ret = 1; if (app.got_subcommand("connect")) { @@ -3581,111 +2911,6 @@ int main(int argc, char** argv) compressRequest, tlsOptions); } - else if (app.got_subcommand("redis_cli")) - { - ret = ix::ws_redis_cli_main(hostname, redisPort, password); - } - else if (app.got_subcommand("redis_publish")) - { - ret = ix::ws_redis_publish_main(hostname, redisPort, password, channel, message, count); - } - else if (app.got_subcommand("redis_subscribe")) - { - ret = ix::ws_redis_subscribe_main(hostname, redisPort, password, channel, verbose); - } - else if (app.got_subcommand("cobra_subscribe")) - { - int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, quiet); - ret = (int) sentCount; - } - else if (app.got_subcommand("cobra_publish")) - { - ret = ix::ws_cobra_publish_main(cobraConfig, channel, path); - } - else if (app.got_subcommand("cobra_metrics_publish")) - { - ret = ix::ws_cobra_metrics_publish_main(cobraConfig, channel, path, stress); - } - else if (app.got_subcommand("cobra_to_statsd")) - { - if (!timer.empty() && !gauge.empty()) - { - spdlog::error("--gauge and --timer options are exclusive. " - "you can only supply one"); - ret = 1; - } - else - { - ix::StatsdClient statsdClient(hostname, statsdPort, prefix, verbose); - - std::string errMsg; - bool initialized = statsdClient.init(errMsg); - if (!initialized) - { - spdlog::error(errMsg); - ret = 1; - } - else - { - ret = (int) ix::cobra_to_statsd_bot( - cobraBotConfig, statsdClient, fields, gauge, timer, verbose); - } - } - } - else if (app.got_subcommand("cobra_to_python")) - { - ix::StatsdClient statsdClient(hostname, statsdPort, prefix, verbose); - - std::string errMsg; - bool initialized = statsdClient.init(errMsg); - if (!initialized) - { - spdlog::error(errMsg); - ret = 1; - } - else - { - ret = (int) ix::cobra_to_python_bot(cobraBotConfig, statsdClient, moduleName); - } - } - else if (app.got_subcommand("cobra_to_sentry")) - { - ix::SentryClient sentryClient(dsn); - sentryClient.setTLSOptions(tlsOptions); - - ret = (int) ix::cobra_to_sentry_bot(cobraBotConfig, sentryClient, verbose); - } - else if (app.got_subcommand("cobra_metrics_to_redis")) - { - ix::RedisClient redisClient; - if (!redisClient.connect(hostname, redisPort)) - { - spdlog::error("Cannot connect to redis host {}:{}", redisHosts, redisPort); - return 1; - } - else - { - ret = (int) ix::cobra_metrics_to_redis_bot(cobraBotConfig, redisClient, verbose); - } - } - else if (app.got_subcommand("cobra_to_cobra")) - { - ret = (int) ix::cobra_to_cobra_bot( - cobraBotConfig, republishChannel, publisherRolename, publisherRolesecret); - } - else if (app.got_subcommand("snake")) - { - ret = ix::ws_snake_main(port, - hostname, - redisHosts, - redisPort, - redisPassword, - verbose, - appsConfigPath, - tlsOptions, - disablePong, - republishChannel); - } else if (app.got_subcommand("httpd")) { ret = ix::ws_httpd_main(port, hostname, redirect, redirectUrl, debug, tlsOptions); @@ -3694,10 +2919,6 @@ int main(int argc, char** argv) { ret = ix::ws_autobahn_main(url, quiet); } - else if (app.got_subcommand("redis_server")) - { - ret = ix::ws_redis_server_main(port, hostname); - } else if (app.got_subcommand("proxy_server")) { ix::RemoteUrlsMapping remoteUrlsMapping; @@ -3712,12 +2933,23 @@ int main(int argc, char** argv) } else { - auto jsonData = nlohmann::json::parse(res.second); - auto remoteUrls = jsonData["remote_urls"]; + // Split by \n + std::string token; + std::stringstream tokenStream(res.second); - for (auto& el : remoteUrls.items()) + while (std::getline(tokenStream, token)) { - remoteUrlsMapping[el.key()] = el.value(); + std::size_t pos = token.rfind(':'); + + // Bail out if last '.' is found + if (pos == std::string::npos) continue; + + auto key = token.substr(0, pos); + auto val = token.substr(pos + 1); + + spdlog::info("{}: {}", key, val); + + remoteUrlsMapping[key] = val; } } } @@ -3725,10 +2957,6 @@ int main(int argc, char** argv) ret = ix::websocket_proxy_server_main( port, hostname, tlsOptions, remoteHost, remoteUrlsMapping, verbose); } - else if (app.got_subcommand("upload_minidump")) - { - ret = ix::ws_sentry_minidump_upload(metadata, minidump, project, key, verbose); - } else if (app.got_subcommand("dnslookup")) { ret = ix::ws_dns_lookup(hostname);