Compare commits

...

9 Commits

23 changed files with 252 additions and 247 deletions

View File

@ -123,8 +123,8 @@ if (USE_TLS)
if (NOT USE_MBED_TLS AND NOT USE_OPEN_SSL) # unless we want something else
set(USE_SECURE_TRANSPORT ON)
endif()
# default to mbedtls on uwp (universal windows platform) if nothing is configured
elseif (${CMAKE_SYSTEM_NAME} MATCHES "WindowsStore")
# default to mbedtls on windows if nothing is configured
elseif (WIN32)
if (NOT USE_OPEN_SSL) # unless we want something else
set(USE_MBED_TLS ON)
endif()
@ -153,8 +153,6 @@ add_library( ixwebsocket STATIC
${IXWEBSOCKET_HEADERS}
)
add_library ( ixwebsocket::ixwebsocket ALIAS ixwebsocket )
if (USE_TLS)
target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_TLS)
if (USE_MBED_TLS)
@ -184,20 +182,22 @@ if (USE_TLS)
# This OPENSSL_FOUND check is to help find a cmake manually configured OpenSSL
if (NOT OPENSSL_FOUND)
include(FindOpenSSL)
find_package(OpenSSL REQUIRED)
endif()
message(STATUS "OpenSSL: " ${OPENSSL_VERSION})
target_link_libraries(ixwebsocket PUBLIC OpenSSL::SSL OpenSSL::Crypto)
add_definitions(${OPENSSL_DEFINITIONS})
target_include_directories(ixwebsocket PUBLIC ${OPENSSL_INCLUDE_DIR})
target_link_libraries(ixwebsocket ${OPENSSL_LIBRARIES})
elseif (USE_MBED_TLS)
message(STATUS "TLS configured to use mbedtls")
find_package(MbedTLS REQUIRED)
target_include_directories(ixwebsocket PUBLIC ${MBEDTLS_INCLUDE_DIRS})
target_link_libraries(ixwebsocket PUBLIC ${MBEDTLS_LIBRARIES})
target_link_libraries(ixwebsocket ${MBEDTLS_LIBRARIES})
elseif (USE_SECURE_TRANSPORT)
message(STATUS "TLS configured to use secure transport")
target_link_libraries(ixwebsocket PUBLIC "-framework foundation" "-framework security")
target_link_libraries(ixwebsocket "-framework foundation" "-framework security")
endif()
endif()
@ -207,25 +207,25 @@ if (NOT ZLIB_FOUND)
endif()
if (ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(ixwebsocket PUBLIC ${ZLIB_LIBRARIES})
target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES})
else()
include_directories(third_party/zlib ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib)
add_subdirectory(third_party/zlib EXCLUDE_FROM_ALL)
target_link_libraries(ixwebsocket PRIVATE $<LINK_ONLY:zlibstatic>)
add_subdirectory(third_party/zlib)
target_link_libraries(ixwebsocket zlibstatic)
endif()
if (WIN32)
target_link_libraries(ixwebsocket PUBLIC wsock32 ws2_32 shlwapi)
target_link_libraries(ixwebsocket wsock32 ws2_32 shlwapi)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if (USE_TLS)
target_link_libraries(ixwebsocket PUBLIC Crypt32)
target_link_libraries(ixwebsocket Crypt32)
endif()
endif()
if (UNIX)
find_package(Threads)
target_link_libraries(ixwebsocket PUBLIC ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(ixwebsocket ${CMAKE_THREAD_LIBS_INIT})
endif()
@ -238,18 +238,15 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(ixwebsocket PRIVATE /MP)
endif()
target_include_directories(ixwebsocket PUBLIC $<BUILD_INTERFACE:${IXWEBSOCKET_INCLUDE_DIRS}> $<INSTALL_INTERFACE:include/ixwebsocket>)
target_include_directories(ixwebsocket PUBLIC ${IXWEBSOCKET_INCLUDE_DIRS})
set_target_properties(ixwebsocket PROPERTIES PUBLIC_HEADER "${IXWEBSOCKET_HEADERS}")
install(TARGETS ixwebsocket EXPORT ixwebsocket
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ixwebsocket/
install(TARGETS ixwebsocket
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include/ixwebsocket/
)
install(EXPORT ixwebsocket NAMESPACE ixwebsocket:: DESTINATION lib/cmake/ixwebsocket)
export(EXPORT ixwebsocket NAMESPACE ixwebsocket:: FILE ixwebsocketConfig.cmake)
if (USE_WS OR USE_TEST)
add_subdirectory(ixcore)
add_subdirectory(ixcrypto)

View File

@ -45,6 +45,7 @@ IXWebSocket client code is autobahn compliant beginning with the 6.0.0 version.
If your company or project is using this library, feel free to open an issue or PR to amend this list.
- [Machine Zone](https://www.mz.com)
- [dis-light](https://gitlab.com/HCInk/dis-light), a discord library with a node frontend.
- [Tokio](https://gitlab.com/HCInk/tokio), a discord library focused on audio playback with node bindings.
- [libDiscordBot](https://github.com/tostc/libDiscordBot/tree/master), a work in progress discord library
- [gwebsocket](https://github.com/norrbotten/gwebsocket), a websocket (lua) module for Garry's Mod
- [DisCPP](https://github.com/DisCPP/DisCPP), a simple but feature rich Discord API wrapper

View File

@ -2,7 +2,7 @@ FROM alpine:3.11 as build
RUN apk add --no-cache \
gcc g++ musl-dev linux-headers \
cmake mbedtls-dev make zlib-dev
cmake mbedtls-dev make zlib-dev ninja
RUN addgroup -S app && \
adduser -S -G app app && \

View File

@ -1,6 +1,26 @@
# Changelog
All changes to this project will be documented in this file.
## [9.6.3] - 2020-05-18
(cmake) revert CMake changes to fix #203 and be able to use an external OpenSSL
## [9.6.2] - 2020-05-17
(cmake) make install cmake files optional to not conflict with vcpkg
## [9.6.1] - 2020-05-17
(windows + tls) mbedtls is the default windows tls backend + add ability to load system certificates with mbdetls on windows
## [9.6.0] - 2020-05-12
(ixbots) add options to limit how many messages per minute should be processed
## [9.5.9] - 2020-05-12
(ixbots) add new class to configure a bot to simplify passing options around
## [9.5.8] - 2020-05-08
(openssl tls) (openssl < 1.1) logic inversion - crypto locking callback are not registered properly

View File

@ -13,6 +13,7 @@ set (IXBOTS_SOURCES
set (IXBOTS_HEADERS
ixbots/IXCobraBot.h
ixbots/IXCobraBotConfig.h
ixbots/IXCobraToSentryBot.h
ixbots/IXCobraToStatsdBot.h
ixbots/IXCobraToStdoutBot.h

View File

@ -17,14 +17,18 @@
namespace ix
{
int64_t CobraBot::run(const CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime)
int64_t CobraBot::run(const CobraBotConfig& botConfig)
{
auto config = botConfig.cobraConfig;
auto channel = botConfig.channel;
auto filter = botConfig.filter;
auto position = botConfig.position;
auto enableHeartbeat = botConfig.enableHeartbeat;
auto heartBeatTimeout = botConfig.heartBeatTimeout;
auto runtime = botConfig.runtime;
auto maxEventsPerMinute = botConfig.maxEventsPerMinute;
auto limitReceivedEvents = botConfig.limitReceivedEvents;
ix::CobraConnection conn;
conn.configure(config);
conn.connect();
@ -35,9 +39,11 @@ namespace ix
uint64_t receivedCountTotal(0);
uint64_t sentCountPerSecs(0);
uint64_t receivedCountPerSecs(0);
std::atomic<int> receivedCountPerMinutes(0);
std::atomic<bool> stop(false);
std::atomic<bool> throttled(false);
std::atomic<bool> fatalCobraError(false);
int minuteCounter = 0;
auto timer = [&sentCount,
&receivedCount,
@ -45,6 +51,8 @@ namespace ix
&receivedCountTotal,
&sentCountPerSecs,
&receivedCountPerSecs,
&receivedCountPerMinutes,
&minuteCounter,
&stop] {
while (!stop)
{
@ -65,13 +73,19 @@ namespace ix
CoreLogger::info(ss.str());
receivedCountPerSecs = receivedCount - receivedCountTotal;
sentCountPerSecs = sentCount - receivedCountTotal;
sentCountPerSecs = sentCount - sentCountTotal;
receivedCountTotal += receivedCountPerSecs;
sentCountTotal += sentCountPerSecs;
auto duration = std::chrono::seconds(1);
std::this_thread::sleep_for(duration);
if (minuteCounter++ == 60)
{
receivedCountPerMinutes = 0;
minuteCounter = 0;
}
}
CoreLogger::info("timer thread done");
@ -118,6 +132,9 @@ namespace ix
&subscriptionPosition,
&throttled,
&receivedCount,
&receivedCountPerMinutes,
maxEventsPerMinute,
limitReceivedEvents,
&fatalCobraError,
&sentCount](const CobraEventPtr& event) {
if (event->type == ix::CobraEventType::Open)
@ -139,29 +156,34 @@ namespace ix
CoreLogger::info("Subscribing to " + channel);
CoreLogger::info("Subscribing at position " + subscriptionPosition);
CoreLogger::info("Subscribing with filter " + filter);
conn.subscribe(channel,
filter,
subscriptionPosition,
[this,
&throttled,
&receivedCount,
&subscriptionPosition,
&fatalCobraError,
&sentCount](const Json::Value& msg, const std::string& position) {
subscriptionPosition = position;
conn.subscribe(channel, filter, subscriptionPosition,
[&sentCount, &receivedCountPerMinutes,
maxEventsPerMinute, limitReceivedEvents,
&throttled, &receivedCount,
&subscriptionPosition, &fatalCobraError,
this](const Json::Value& msg, const std::string& position) {
subscriptionPosition = position;
++receivedCount;
// If we cannot send to sentry fast enough, drop the message
if (throttled)
{
return;
}
++receivedCountPerMinutes;
if (limitReceivedEvents)
{
if (receivedCountPerMinutes > maxEventsPerMinute)
{
return;
}
}
++receivedCount;
// If we cannot send to sentry fast enough, drop the message
if (throttled)
{
return;
}
_onBotMessageCallback(
msg, position, throttled,
fatalCobraError, sentCount);
});
_onBotMessageCallback(
msg, position, throttled,
fatalCobraError, sentCount);
});
}
else if (event->type == ix::CobraEventType::Subscribed)
{

View File

@ -8,7 +8,7 @@
#include <atomic>
#include <functional>
#include <ixcobra/IXCobraConfig.h>
#include "IXCobraBotConfig.h"
#include <json/json.h>
#include <stddef.h>
@ -25,14 +25,7 @@ namespace ix
public:
CobraBot() = default;
int64_t run(const CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime);
int64_t run(const CobraBotConfig& botConfig);
void setOnBotMessageCallback(const OnBotMessageCallback& callback);
private:

View File

@ -0,0 +1,31 @@
/*
* IXCobraBotConfig.h
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
*/
#pragma once
#include <string>
#include <limits>
#include <ixcobra/IXCobraConfig.h>
#ifdef max
#undef max
#endif
namespace ix
{
struct CobraBotConfig
{
CobraConfig cobraConfig;
std::string channel;
std::string filter;
std::string position = std::string("$");
bool enableHeartbeat = true;
int heartBeatTimeout = 60;
int runtime = -1;
int maxEventsPerMinute = std::numeric_limits<int>::max();
bool limitReceivedEvents = false;
};
} // namespace ix

View File

@ -16,15 +16,9 @@
namespace ix
{
int64_t cobra_to_sentry_bot(const CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_sentry_bot(const CobraBotConfig& config,
SentryClient& sentryClient,
bool verbose,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime)
bool verbose)
{
CobraBot bot;
bot.setOnBotMessageCallback([&sentryClient, &verbose](const Json::Value& msg,
@ -77,12 +71,6 @@ namespace ix
});
});
return bot.run(config,
channel,
filter,
position,
enableHeartbeat,
heartBeatTimeout,
runtime);
return bot.run(config);
}
} // namespace ix

View File

@ -6,19 +6,13 @@
#pragma once
#include <cstdint>
#include <ixcobra/IXCobraConfig.h>
#include "IXCobraBotConfig.h"
#include <ixsentry/IXSentryClient.h>
#include <string>
namespace ix
{
int64_t cobra_to_sentry_bot(const CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_sentry_bot(const CobraBotConfig& config,
SentryClient& sentryClient,
bool verbose,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime);
bool verbose);
} // namespace ix

View File

@ -53,23 +53,13 @@ namespace ix
return val;
}
int64_t cobra_to_statsd_bot(const ix::CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config,
StatsdClient& statsdClient,
const std::string& fields,
const std::string& gauge,
const std::string& timer,
bool verbose,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime)
bool verbose)
{
ix::CobraConnection conn;
conn.configure(config);
conn.connect();
auto tokens = parseFields(fields);
CobraBot bot;
@ -142,12 +132,6 @@ namespace ix
sentCount++;
});
return bot.run(config,
channel,
filter,
position,
enableHeartbeat,
heartBeatTimeout,
runtime);
return bot.run(config);
}
} // namespace ix

View File

@ -7,22 +7,16 @@
#include <cstdint>
#include <ixbots/IXStatsdClient.h>
#include <ixcobra/IXCobraConfig.h>
#include "IXCobraBotConfig.h"
#include <stddef.h>
#include <string>
namespace ix
{
int64_t cobra_to_statsd_bot(const ix::CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config,
StatsdClient& statsdClient,
const std::string& fields,
const std::string& gauge,
const std::string& timer,
bool verbose,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime);
bool verbose);
} // namespace ix

View File

@ -63,15 +63,9 @@ namespace ix
}
}
int64_t cobra_to_stdout_bot(const CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config,
bool fluentd,
bool quiet,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime)
bool quiet)
{
CobraBot bot;
auto jsonWriter = makeStreamWriter();
@ -89,12 +83,6 @@ namespace ix
sentCount++;
});
return bot.run(config,
channel,
filter,
position,
enableHeartbeat,
heartBeatTimeout,
runtime);
return bot.run(config);
}
} // namespace ix

View File

@ -6,19 +6,13 @@
#pragma once
#include <cstdint>
#include <ixcobra/IXCobraConfig.h>
#include "IXCobraBotConfig.h"
#include <stddef.h>
#include <string>
namespace ix
{
int64_t cobra_to_stdout_bot(const ix::CobraConfig& config,
const std::string& channel,
const std::string& filter,
const std::string& position,
int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config,
bool fluentd,
bool quiet,
bool enableHeartbeat,
int heartBeatTimeout,
int runtime);
bool quiet);
} // namespace ix

View File

@ -43,6 +43,55 @@ namespace ix
mbedtls_pk_init(&_pkey);
}
bool SocketMbedTLS::loadSystemCertificates(std::string& errorMsg)
{
#ifdef _WIN32
DWORD flags = CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG |
CERT_SYSTEM_STORE_CURRENT_USER;
HCERTSTORE systemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, flags, L"Root");
if (!systemStore)
{
errorMsg = "CertOpenStore failed with ";
errorMsg += std::to_string(GetLastError());
return false;
}
PCCERT_CONTEXT certificateIterator = NULL;
int certificateCount = 0;
while (certificateIterator = CertEnumCertificatesInStore(systemStore, certificateIterator))
{
if (certificateIterator->dwCertEncodingType & X509_ASN_ENCODING)
{
int ret = mbedtls_x509_crt_parse(&_cacert,
certificateIterator->pbCertEncoded,
certificateIterator->cbCertEncoded);
if (ret == 0)
{
++certificateCount;
}
}
}
CertFreeCertificateContext(certificateIterator);
CertCloseStore(systemStore, 0);
if (certificateCount == 0)
{
errorMsg = "No certificates found";
return false;
}
return true;
#else
// On macOS we can query the system cert location from the keychain
// On Linux we could try to fetch some local files based on the distribution
// On Android we could use JNI to get to the system certs
return false;
#endif
}
bool SocketMbedTLS::init(const std::string& host, bool isClient, std::string& errMsg)
{
initMBedTLS();
@ -96,13 +145,15 @@ namespace ix
}
else
{
mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
// FIXME: should we call mbedtls_ssl_conf_verify ?
mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
if (_tlsOptions.isUsingSystemDefaults())
{
; // FIXME
if (!loadSystemCertificates(errMsg))
{
return false;
}
}
else
{

View File

@ -52,6 +52,7 @@ namespace ix
bool init(const std::string& host, bool isClient, std::string& errMsg);
void initMBedTLS();
bool loadSystemCertificates(std::string& errMsg);
};
} // namespace ix

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "9.5.8"
#define IX_WEBSOCKET_VERSION "9.6.3"

View File

@ -26,7 +26,7 @@ brew:
# server side ?) and I can't work-around it easily, so we're using mbedtls on
# Linux for the SSL backend, which works great.
ws_mbedtls_install:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; make -j 4 install)
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
ws:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4)

View File

@ -138,11 +138,12 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
std::thread publisherThread(runPublisher, config, channel);
std::string filter;
std::string position("$");
ix::CobraBotConfig cobraBotConfig;
cobraBotConfig.cobraConfig = config;
cobraBotConfig.channel = channel;
cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
cobraBotConfig.enableHeartbeat = false;
bool verbose = true;
bool enableHeartbeat = false;
int heartBeatTimeout = 60;
// FIXME: try to get this working with https instead of http
// to regress the TLS 1.3 OpenSSL bug
@ -157,18 +158,7 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
SentryClient sentryClient(dsn);
sentryClient.setTLSOptions(tlsOptionsClient);
// Only run the bot for 3 seconds
int runtime = 3;
int64_t sentCount = cobra_to_sentry_bot(config,
channel,
filter,
position,
sentryClient,
verbose,
enableHeartbeat,
heartBeatTimeout,
runtime);
int64_t sentCount = cobra_to_sentry_bot(cobraBotConfig, sentryClient, verbose);
//
// We want at least 2 messages to be sent
//

View File

@ -87,14 +87,11 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
std::thread publisherThread(runPublisher, config, channel);
std::string filter;
std::string position("$");
bool verbose = true;
bool enableHeartbeat = false;
int heartBeatTimeout = 60;
// Only run the bot for 3 seconds
int runtime = 3;
ix::CobraBotConfig cobraBotConfig;
cobraBotConfig.cobraConfig = config;
cobraBotConfig.channel = channel;
cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
cobraBotConfig.enableHeartbeat = false;
std::string hostname("127.0.0.1");
// std::string hostname("www.google.com");
@ -113,19 +110,10 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
std::string fields("device.game\ndevice.os_name");
std::string gauge;
std::string timer;
bool verbose = true;
int64_t sentCount = ix::cobra_to_statsd_bot(config,
channel,
filter,
position,
statsdClient,
fields,
gauge,
timer,
verbose,
enableHeartbeat,
heartBeatTimeout,
runtime);
int64_t sentCount =
ix::cobra_to_statsd_bot(cobraBotConfig, statsdClient, fields, gauge, timer, verbose);
//
// We want at least 2 messages to be sent
//

View File

@ -85,27 +85,17 @@ TEST_CASE("Cobra_to_stdout_bot", "[cobra_bots]")
std::thread publisherThread(runPublisher, config, channel);
std::string filter;
std::string position("$");
ix::CobraBotConfig cobraBotConfig;
cobraBotConfig.cobraConfig = config;
cobraBotConfig.channel = channel;
cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
cobraBotConfig.enableHeartbeat = false;
bool quiet = false;
bool enableHeartbeat = false;
int heartBeatTimeout = 60;
// Only run the bot for 3 seconds
int runtime = 3;
// We could try to capture the output ... not sure how.
bool fluentd = true;
int64_t sentCount = ix::cobra_to_stdout_bot(config,
channel,
filter,
position,
fluentd,
quiet,
enableHeartbeat,
heartBeatTimeout,
runtime);
int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, quiet);
//
// We want at least 2 messages to be sent
//

View File

@ -93,10 +93,11 @@ TEST_CASE("subprotocol", "[websocket_subprotocol]")
webSocket.setUrl(url);
webSocket.start();
// Give us 3 seconds to connect
int attempts = 0;
while (!connected)
{
REQUIRE(attempts++ < 100);
REQUIRE(attempts++ < 300);
ix::msleep(10);
}

View File

@ -120,6 +120,7 @@ int main(int argc, char** argv)
std::string logfile;
ix::SocketTLSOptions tlsOptions;
ix::CobraConfig cobraConfig;
ix::CobraBotConfig cobraBotConfig;
std::string ciphers;
std::string redirectUrl;
bool headersOnly = false;
@ -149,8 +150,6 @@ int main(int argc, char** argv)
int count = 1;
uint32_t maxWaitBetweenReconnectionRetries;
int pingIntervalSecs = 30;
int runtime = -1; // run indefinitely
int heartBeatTimeout = 60;
auto addTLSOptions = [&tlsOptions, &verifyNone](CLI::App* app) {
app->add_option(
@ -174,6 +173,24 @@ int main(int argc, char** argv)
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_flag("--version", version, "Print ws version");
app.add_option("--logfile", logfile, "path where all logs will be redirected");
@ -281,16 +298,11 @@ int main(int argc, char** argv)
CLI::App* cobraSubscribeApp = app.add_subcommand("cobra_subscribe", "Cobra subscriber");
cobraSubscribeApp->fallthrough();
cobraSubscribeApp->add_option("--channel", channel, "Channel")->required();
cobraSubscribeApp->add_option("--pidfile", pidfile, "Pid file");
cobraSubscribeApp->add_option("--filter", filter, "Stream SQL Filter");
cobraSubscribeApp->add_option("--position", position, "Stream position");
cobraSubscribeApp->add_flag("-q", quiet, "Quiet / only display stats");
cobraSubscribeApp->add_flag("--fluentd", fluentd, "Write fluentd prefix");
cobraSubscribeApp->add_option("--runtime", runtime, "Runtime in seconds");
cobraSubscribeApp->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout");
addTLSOptions(cobraSubscribeApp);
addCobraConfig(cobraSubscribeApp);
addCobraBotConfig(cobraSubscribeApp);
CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher");
cobraPublish->fallthrough();
@ -324,28 +336,18 @@ int main(int argc, char** argv)
->join();
cobra2statsd->add_option("--timer", timer, "Value to extract, and use as a statsd timer")
->join();
cobra2statsd->add_option("channel", channel, "Channel")->required();
cobra2statsd->add_flag("-v", verbose, "Verbose");
cobra2statsd->add_option("--pidfile", pidfile, "Pid file");
cobra2statsd->add_option("--filter", filter, "Stream SQL Filter");
cobra2statsd->add_option("--position", position, "Stream position");
cobra2statsd->add_option("--runtime", runtime, "Runtime in seconds");
cobra2statsd->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout");
addTLSOptions(cobra2statsd);
addCobraConfig(cobra2statsd);
addCobraBotConfig(cobra2statsd);
CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra metrics to sentry");
cobra2sentry->fallthrough();
cobra2sentry->add_option("--dsn", dsn, "Sentry DSN");
cobra2sentry->add_option("channel", channel, "Channel")->required();
cobra2sentry->add_flag("-v", verbose, "Verbose");
cobra2sentry->add_option("--pidfile", pidfile, "Pid file");
cobra2sentry->add_option("--filter", filter, "Stream SQL Filter");
cobra2sentry->add_option("--position", position, "Stream position");
cobra2sentry->add_option("--runtime", runtime, "Runtime in seconds");
cobra2sentry->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout");
addTLSOptions(cobra2sentry);
addCobraConfig(cobra2sentry);
addCobraBotConfig(cobra2sentry);
CLI::App* cobra2redisApp =
app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis");
@ -456,6 +458,10 @@ int main(int argc, char** argv)
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("transfer"))
{
@ -525,16 +531,7 @@ int main(int argc, char** argv)
}
else if (app.got_subcommand("cobra_subscribe"))
{
bool enableHeartbeat = true;
int64_t sentCount = ix::cobra_to_stdout_bot(cobraConfig,
channel,
filter,
position,
fluentd,
quiet,
enableHeartbeat,
heartBeatTimeout,
runtime);
int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, quiet);
ret = (int) sentCount;
}
else if (app.got_subcommand("cobra_publish"))
@ -555,7 +552,6 @@ int main(int argc, char** argv)
}
else
{
bool enableHeartbeat = true;
ix::StatsdClient statsdClient(hostname, statsdPort, prefix);
std::string errMsg;
@ -567,36 +563,17 @@ int main(int argc, char** argv)
}
else
{
ret = (int) ix::cobra_to_statsd_bot(cobraConfig,
channel,
filter,
position,
statsdClient,
fields,
gauge,
timer,
verbose,
enableHeartbeat,
heartBeatTimeout,
runtime);
ret = (int) ix::cobra_to_statsd_bot(
cobraBotConfig, statsdClient, fields, gauge, timer, verbose);
}
}
}
else if (app.got_subcommand("cobra_to_sentry"))
{
bool enableHeartbeat = true;
ix::SentryClient sentryClient(dsn);
sentryClient.setTLSOptions(tlsOptions);
ret = (int) ix::cobra_to_sentry_bot(cobraConfig,
channel,
filter,
position,
sentryClient,
verbose,
enableHeartbeat,
heartBeatTimeout,
runtime);
ret = (int) ix::cobra_to_sentry_bot(cobraBotConfig, sentryClient, verbose);
}
else if (app.got_subcommand("cobra_metrics_to_redis"))
{