Compare commits
	
		
			2 Commits
		
	
	
		
			v9.6.4
			...
			feature/wi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bf2145eb8a | ||
| 
						 | 
					a35f8f2250 | 
							
								
								
									
										47
									
								
								.github/workflows/ccpp.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								.github/workflows/ccpp.yml
									
									
									
									
										vendored
									
									
								
							@@ -5,39 +5,7 @@ on:
 | 
				
			|||||||
    - 'docs/**'
 | 
					    - 'docs/**'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  linux:
 | 
					  windows_openssl:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - name: make test_make
 | 
					 | 
				
			||||||
      run: make test_make
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mac_tsan_sectransport:
 | 
					 | 
				
			||||||
    runs-on: macOS-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - name: make test_tsan
 | 
					 | 
				
			||||||
      run: make test_tsan
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mac_tsan_openssl:
 | 
					 | 
				
			||||||
    runs-on: macOS-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - name: install openssl
 | 
					 | 
				
			||||||
      run: brew install openssl@1.1
 | 
					 | 
				
			||||||
    - name: make test
 | 
					 | 
				
			||||||
      run: make test_tsan_openssl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mac_tsan_mbedtls:
 | 
					 | 
				
			||||||
    runs-on: macOS-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - name: install mbedtls
 | 
					 | 
				
			||||||
      run: brew install mbedtls
 | 
					 | 
				
			||||||
    - name: make test
 | 
					 | 
				
			||||||
      run: make test_tsan_mbedtls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  windows:
 | 
					 | 
				
			||||||
    runs-on: windows-latest
 | 
					    runs-on: windows-latest
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					    - uses: actions/checkout@v1
 | 
				
			||||||
@@ -45,24 +13,13 @@ jobs:
 | 
				
			|||||||
    - run: |
 | 
					    - run: |
 | 
				
			||||||
        mkdir build
 | 
					        mkdir build
 | 
				
			||||||
        cd build
 | 
					        cd build
 | 
				
			||||||
        cmake -DCMAKE_CXX_COMPILER=cl.exe -DUSE_WS=1 -DUSE_TEST=1 ..
 | 
					        cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DCMAKE_CXX_COMPILER=cl.exe -DUSE_WS=1 -DUSE_TEST=1 ..
 | 
				
			||||||
    - run: cmake --build build
 | 
					    - run: cmake --build build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Running the unittest does not work, the binary cannot be found
 | 
					    # Running the unittest does not work, the binary cannot be found
 | 
				
			||||||
    #- run: ../build/test/ixwebsocket_unittest.exe
 | 
					    #- run: ../build/test/ixwebsocket_unittest.exe
 | 
				
			||||||
    # working-directory: test
 | 
					    # working-directory: test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uwp:
 | 
					 | 
				
			||||||
    runs-on: windows-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - uses: seanmiddleditch/gha-setup-vsdevenv@master
 | 
					 | 
				
			||||||
    - run: |
 | 
					 | 
				
			||||||
        mkdir build
 | 
					 | 
				
			||||||
        cd build
 | 
					 | 
				
			||||||
        cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DCMAKE_CXX_COMPILER=cl.exe -DUSE_TEST=1 ..
 | 
					 | 
				
			||||||
    - run: cmake --build build
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#   Windows with OpenSSL is working but disabled as it takes 13 minutes (10 for openssl) to build with vcpkg
 | 
					#   Windows with OpenSSL is working but disabled as it takes 13 minutes (10 for openssl) to build with vcpkg
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,10 +12,6 @@ set (CMAKE_CXX_STANDARD 14)
 | 
				
			|||||||
set (CXX_STANDARD_REQUIRED ON)
 | 
					set (CXX_STANDARD_REQUIRED ON)
 | 
				
			||||||
set (CMAKE_CXX_EXTENSIONS OFF)
 | 
					set (CMAKE_CXX_EXTENSIONS OFF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 | 
					 | 
				
			||||||
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (UNIX)
 | 
					if (UNIX)
 | 
				
			||||||
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
 | 
					  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
@@ -123,11 +119,6 @@ if (USE_TLS)
 | 
				
			|||||||
      if (NOT USE_MBED_TLS AND NOT USE_OPEN_SSL) # unless we want something else
 | 
					      if (NOT USE_MBED_TLS AND NOT USE_OPEN_SSL) # unless we want something else
 | 
				
			||||||
        set(USE_SECURE_TRANSPORT ON)
 | 
					        set(USE_SECURE_TRANSPORT ON)
 | 
				
			||||||
      endif()
 | 
					      endif()
 | 
				
			||||||
    # 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()
 | 
					 | 
				
			||||||
    else() # default to OpenSSL on all other platforms
 | 
					    else() # default to OpenSSL on all other platforms
 | 
				
			||||||
      if (NOT USE_MBED_TLS) # Unless mbedtls is requested
 | 
					      if (NOT USE_MBED_TLS) # Unless mbedtls is requested
 | 
				
			||||||
        set(USE_OPEN_SSL ON)
 | 
					        set(USE_OPEN_SSL ON)
 | 
				
			||||||
@@ -174,10 +165,6 @@ if (USE_TLS)
 | 
				
			|||||||
    if (APPLE)
 | 
					    if (APPLE)
 | 
				
			||||||
      set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/opt/openssl/lib)
 | 
					      set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/opt/openssl/lib)
 | 
				
			||||||
      set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/opt/openssl/include)
 | 
					      set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/opt/openssl/include)
 | 
				
			||||||
 | 
					 | 
				
			||||||
      # This is for MacPort OpenSSL 1.0
 | 
					 | 
				
			||||||
      # set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /opt/local/lib/openssl-1.0)
 | 
					 | 
				
			||||||
      # set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /opt/local/include/openssl-1.0)
 | 
					 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # This OPENSSL_FOUND check is to help find a cmake manually configured OpenSSL
 | 
					    # This OPENSSL_FOUND check is to help find a cmake manually configured OpenSSL
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,3 @@ 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.
 | 
					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)
 | 
					- [Machine Zone](https://www.mz.com)
 | 
				
			||||||
- [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
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ FROM alpine:3.11 as build
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
RUN apk add --no-cache \
 | 
					RUN apk add --no-cache \
 | 
				
			||||||
    gcc g++ musl-dev linux-headers \
 | 
					    gcc g++ musl-dev linux-headers \
 | 
				
			||||||
    cmake mbedtls-dev make zlib-dev ninja
 | 
					    cmake mbedtls-dev make zlib-dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN addgroup -S app && \
 | 
					RUN addgroup -S app && \
 | 
				
			||||||
    adduser -S -G app app && \
 | 
					    adduser -S -G app app && \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,54 +1,6 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
All changes to this project will be documented in this file.
 | 
					All changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [9.6.4] - 2020-05-20
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(compiler fix) support clang 5 and earlier (contributed by @LunarWatcher)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.7] - 2020-05-08
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(cmake) default TLS back to mbedtls on Windows Universal Platform
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.6] - 2020-05-06
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(cobra bots) add a --heartbeat_timeout option to specify when the bot should terminate because no events are received
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.5] - 2020-05-06
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(openssl tls) when OpenSSL is older than 1.1, register the crypto locking callback to be thread safe. Should fix lots of CI failures
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.4] - 2020-05-04
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(cobra bots) do not use a queue to store messages pending processing, let the bot handle queuing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.3] - 2020-04-29
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(http client) better current request cancellation support when the HttpClient destructor is invoked (see #189)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [9.5.2] - 2020-04-27
 | 
					## [9.5.2] - 2020-04-27
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(cmake) fix cmake broken tls option parsing
 | 
					(cmake) fix cmake broken tls option parsing
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,19 +42,6 @@ It is possible to get IXWebSocket through Microsoft [vcpkg](https://github.com/m
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
vcpkg install ixwebsocket
 | 
					vcpkg install ixwebsocket
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
To use the installed package within a cmake project, use the following:
 | 
					 | 
				
			||||||
```cmake
 | 
					 | 
				
			||||||
 set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") # this is super important in order for cmake to include the vcpkg search/lib paths!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 # find library and its headers
 | 
					 | 
				
			||||||
 find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket/IXWebSocket.h)
 | 
					 | 
				
			||||||
 find_library(IXWEBSOCKET_LIBRARY ixwebsocket)
 | 
					 | 
				
			||||||
 # include headers
 | 
					 | 
				
			||||||
 include_directories(${IXWEBSOCKET_INCLUDE_DIR})
 | 
					 | 
				
			||||||
 # ...
 | 
					 | 
				
			||||||
 target_link_libraries(${PROJECT_NAME} ... ${IXWEBSOCKET_LIBRARY}) # Cmake will automatically fail the generation if the lib was not found, i.e is set to NOTFOUNS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Conan
 | 
					### Conan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,15 +8,16 @@ set (IXBOTS_SOURCES
 | 
				
			|||||||
    ixbots/IXCobraToSentryBot.cpp
 | 
					    ixbots/IXCobraToSentryBot.cpp
 | 
				
			||||||
    ixbots/IXCobraToStatsdBot.cpp
 | 
					    ixbots/IXCobraToStatsdBot.cpp
 | 
				
			||||||
    ixbots/IXCobraToStdoutBot.cpp
 | 
					    ixbots/IXCobraToStdoutBot.cpp
 | 
				
			||||||
 | 
					    ixbots/IXQueueManager.cpp
 | 
				
			||||||
    ixbots/IXStatsdClient.cpp
 | 
					    ixbots/IXStatsdClient.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set (IXBOTS_HEADERS
 | 
					set (IXBOTS_HEADERS
 | 
				
			||||||
    ixbots/IXCobraBot.h
 | 
					    ixbots/IXCobraBot.h
 | 
				
			||||||
    ixbots/IXCobraBotConfig.h
 | 
					 | 
				
			||||||
    ixbots/IXCobraToSentryBot.h
 | 
					    ixbots/IXCobraToSentryBot.h
 | 
				
			||||||
    ixbots/IXCobraToStatsdBot.h
 | 
					    ixbots/IXCobraToStatsdBot.h
 | 
				
			||||||
    ixbots/IXCobraToStdoutBot.h
 | 
					    ixbots/IXCobraToStdoutBot.h
 | 
				
			||||||
 | 
					    ixbots/IXQueueManager.h
 | 
				
			||||||
    ixbots/IXStatsdClient.h
 | 
					    ixbots/IXStatsdClient.h
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "IXCobraBot.h"
 | 
					#include "IXCobraBot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "IXQueueManager.h"
 | 
				
			||||||
#include <ixcobra/IXCobraConnection.h>
 | 
					#include <ixcobra/IXCobraConnection.h>
 | 
				
			||||||
#include <ixcore/utils/IXCoreLogger.h>
 | 
					#include <ixcore/utils/IXCoreLogger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,33 +18,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t CobraBot::run(const CobraBotConfig& botConfig)
 | 
					    int64_t CobraBot::run(const CobraConfig& config,
 | 
				
			||||||
 | 
					                          const std::string& channel,
 | 
				
			||||||
 | 
					                          const std::string& filter,
 | 
				
			||||||
 | 
					                          const std::string& position,
 | 
				
			||||||
 | 
					                          bool verbose,
 | 
				
			||||||
 | 
					                          size_t maxQueueSize,
 | 
				
			||||||
 | 
					                          bool useQueue,
 | 
				
			||||||
 | 
					                          bool enableHeartbeat,
 | 
				
			||||||
 | 
					                          int runtime)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        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;
 | 
					        ix::CobraConnection conn;
 | 
				
			||||||
        conn.configure(config);
 | 
					        conn.configure(config);
 | 
				
			||||||
        conn.connect();
 | 
					        conn.connect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Json::FastWriter jsonWriter;
 | 
				
			||||||
        std::atomic<uint64_t> sentCount(0);
 | 
					        std::atomic<uint64_t> sentCount(0);
 | 
				
			||||||
        std::atomic<uint64_t> receivedCount(0);
 | 
					        std::atomic<uint64_t> receivedCount(0);
 | 
				
			||||||
        uint64_t sentCountTotal(0);
 | 
					        uint64_t sentCountTotal(0);
 | 
				
			||||||
        uint64_t receivedCountTotal(0);
 | 
					        uint64_t receivedCountTotal(0);
 | 
				
			||||||
        uint64_t sentCountPerSecs(0);
 | 
					        uint64_t sentCountPerSecs(0);
 | 
				
			||||||
        uint64_t receivedCountPerSecs(0);
 | 
					        uint64_t receivedCountPerSecs(0);
 | 
				
			||||||
        std::atomic<int> receivedCountPerMinutes(0);
 | 
					 | 
				
			||||||
        std::atomic<bool> stop(false);
 | 
					        std::atomic<bool> stop(false);
 | 
				
			||||||
        std::atomic<bool> throttled(false);
 | 
					        std::atomic<bool> throttled(false);
 | 
				
			||||||
        std::atomic<bool> fatalCobraError(false);
 | 
					        std::atomic<bool> fatalCobraError(false);
 | 
				
			||||||
        int minuteCounter = 0;
 | 
					
 | 
				
			||||||
 | 
					        QueueManager queueManager(maxQueueSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto timer = [&sentCount,
 | 
					        auto timer = [&sentCount,
 | 
				
			||||||
                      &receivedCount,
 | 
					                      &receivedCount,
 | 
				
			||||||
@@ -51,8 +51,6 @@ namespace ix
 | 
				
			|||||||
                      &receivedCountTotal,
 | 
					                      &receivedCountTotal,
 | 
				
			||||||
                      &sentCountPerSecs,
 | 
					                      &sentCountPerSecs,
 | 
				
			||||||
                      &receivedCountPerSecs,
 | 
					                      &receivedCountPerSecs,
 | 
				
			||||||
                      &receivedCountPerMinutes,
 | 
					 | 
				
			||||||
                      &minuteCounter,
 | 
					 | 
				
			||||||
                      &stop] {
 | 
					                      &stop] {
 | 
				
			||||||
            while (!stop)
 | 
					            while (!stop)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -73,19 +71,13 @@ namespace ix
 | 
				
			|||||||
                CoreLogger::info(ss.str());
 | 
					                CoreLogger::info(ss.str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                receivedCountPerSecs = receivedCount - receivedCountTotal;
 | 
					                receivedCountPerSecs = receivedCount - receivedCountTotal;
 | 
				
			||||||
                sentCountPerSecs = sentCount - sentCountTotal;
 | 
					                sentCountPerSecs = sentCount - receivedCountTotal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                receivedCountTotal += receivedCountPerSecs;
 | 
					                receivedCountTotal += receivedCountPerSecs;
 | 
				
			||||||
                sentCountTotal += sentCountPerSecs;
 | 
					                sentCountTotal += sentCountPerSecs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto duration = std::chrono::seconds(1);
 | 
					                auto duration = std::chrono::seconds(1);
 | 
				
			||||||
                std::this_thread::sleep_for(duration);
 | 
					                std::this_thread::sleep_for(duration);
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (minuteCounter++ == 60)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    receivedCountPerMinutes = 0;
 | 
					 | 
				
			||||||
                    minuteCounter = 0;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            CoreLogger::info("timer thread done");
 | 
					            CoreLogger::info("timer thread done");
 | 
				
			||||||
@@ -93,7 +85,7 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread t1(timer);
 | 
					        std::thread t1(timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto heartbeat = [&sentCount, &receivedCount, &stop, &enableHeartbeat, &heartBeatTimeout, &fatalCobraError] {
 | 
					        auto heartbeat = [&sentCount, &receivedCount, &stop, &enableHeartbeat] {
 | 
				
			||||||
            std::string state("na");
 | 
					            std::string state("na");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!enableHeartbeat) return;
 | 
					            if (!enableHeartbeat) return;
 | 
				
			||||||
@@ -109,12 +101,11 @@ namespace ix
 | 
				
			|||||||
                if (currentState == state)
 | 
					                if (currentState == state)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    CoreLogger::error("no messages received or sent for 1 minute, exiting");
 | 
					                    CoreLogger::error("no messages received or sent for 1 minute, exiting");
 | 
				
			||||||
                    fatalCobraError = true;
 | 
					                    exit(1);
 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                state = currentState;
 | 
					                state = currentState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto duration = std::chrono::seconds(heartBeatTimeout);
 | 
					                auto duration = std::chrono::minutes(1);
 | 
				
			||||||
                std::this_thread::sleep_for(duration);
 | 
					                std::this_thread::sleep_for(duration);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -123,6 +114,40 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread t2(heartbeat);
 | 
					        std::thread t2(heartbeat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto sender =
 | 
				
			||||||
 | 
					            [this, &queueManager, verbose, &sentCount, &stop, &throttled, &fatalCobraError] {
 | 
				
			||||||
 | 
					                while (true)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    auto data = queueManager.pop();
 | 
				
			||||||
 | 
					                    Json::Value msg = data.first;
 | 
				
			||||||
 | 
					                    std::string position = data.second;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (stop) break;
 | 
				
			||||||
 | 
					                    if (msg.isNull()) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (_onBotMessageCallback &&
 | 
				
			||||||
 | 
					                        _onBotMessageCallback(msg, position, verbose, throttled, fatalCobraError))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // That might be too noisy
 | 
				
			||||||
 | 
					                        if (verbose)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            CoreLogger::info("cobra bot: sending succesfull");
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        ++sentCount;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        CoreLogger::error("cobra bot: error sending");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (stop) break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CoreLogger::info("sender thread done");
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::thread t3(sender);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string subscriptionPosition(position);
 | 
					        std::string subscriptionPosition(position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.setEventCallback([this,
 | 
					        conn.setEventCallback([this,
 | 
				
			||||||
@@ -130,12 +155,13 @@ namespace ix
 | 
				
			|||||||
                               &channel,
 | 
					                               &channel,
 | 
				
			||||||
                               &filter,
 | 
					                               &filter,
 | 
				
			||||||
                               &subscriptionPosition,
 | 
					                               &subscriptionPosition,
 | 
				
			||||||
 | 
					                               &jsonWriter,
 | 
				
			||||||
 | 
					                               verbose,
 | 
				
			||||||
                               &throttled,
 | 
					                               &throttled,
 | 
				
			||||||
                               &receivedCount,
 | 
					                               &receivedCount,
 | 
				
			||||||
                               &receivedCountPerMinutes,
 | 
					 | 
				
			||||||
                               maxEventsPerMinute,
 | 
					 | 
				
			||||||
                               limitReceivedEvents,
 | 
					 | 
				
			||||||
                               &fatalCobraError,
 | 
					                               &fatalCobraError,
 | 
				
			||||||
 | 
					                               &useQueue,
 | 
				
			||||||
 | 
					                               &queueManager,
 | 
				
			||||||
                               &sentCount](const CobraEventPtr& event) {
 | 
					                               &sentCount](const CobraEventPtr& event) {
 | 
				
			||||||
            if (event->type == ix::CobraEventType::Open)
 | 
					            if (event->type == ix::CobraEventType::Open)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -156,23 +182,26 @@ namespace ix
 | 
				
			|||||||
                CoreLogger::info("Subscribing to " + channel);
 | 
					                CoreLogger::info("Subscribing to " + channel);
 | 
				
			||||||
                CoreLogger::info("Subscribing at position " + subscriptionPosition);
 | 
					                CoreLogger::info("Subscribing at position " + subscriptionPosition);
 | 
				
			||||||
                CoreLogger::info("Subscribing with filter " + filter);
 | 
					                CoreLogger::info("Subscribing with filter " + filter);
 | 
				
			||||||
                conn.subscribe(channel, filter, subscriptionPosition,
 | 
					                conn.subscribe(channel,
 | 
				
			||||||
                    [&sentCount, &receivedCountPerMinutes,
 | 
					                               filter,
 | 
				
			||||||
                     maxEventsPerMinute, limitReceivedEvents,
 | 
					                               subscriptionPosition,
 | 
				
			||||||
                     &throttled, &receivedCount,
 | 
					                               [this,
 | 
				
			||||||
                     &subscriptionPosition, &fatalCobraError,
 | 
					                                &jsonWriter,
 | 
				
			||||||
                     this](const Json::Value& msg, const std::string& position) {
 | 
					                                verbose,
 | 
				
			||||||
                        subscriptionPosition = position;
 | 
					                                &throttled,
 | 
				
			||||||
                        ++receivedCount;
 | 
					                                &receivedCount,
 | 
				
			||||||
 | 
					                                &queueManager,
 | 
				
			||||||
 | 
					                                &useQueue,
 | 
				
			||||||
 | 
					                                &subscriptionPosition,
 | 
				
			||||||
 | 
					                                &fatalCobraError,
 | 
				
			||||||
 | 
					                                &sentCount](const Json::Value& msg, const std::string& position) {
 | 
				
			||||||
 | 
					                                   if (verbose)
 | 
				
			||||||
 | 
					                                   {
 | 
				
			||||||
 | 
					                                       CoreLogger::info("Subscriber received message "
 | 
				
			||||||
 | 
					                                                        + position + " -> " + jsonWriter.write(msg));
 | 
				
			||||||
 | 
					                                   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        ++receivedCountPerMinutes;
 | 
					                                   subscriptionPosition = position;
 | 
				
			||||||
                        if (limitReceivedEvents)
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            if (receivedCountPerMinutes > maxEventsPerMinute)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                return;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                   // If we cannot send to sentry fast enough, drop the message
 | 
					                                   // If we cannot send to sentry fast enough, drop the message
 | 
				
			||||||
                                   if (throttled)
 | 
					                                   if (throttled)
 | 
				
			||||||
@@ -180,9 +209,30 @@ namespace ix
 | 
				
			|||||||
                                       return;
 | 
					                                       return;
 | 
				
			||||||
                                   }
 | 
					                                   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                   ++receivedCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                   if (useQueue)
 | 
				
			||||||
 | 
					                                   {
 | 
				
			||||||
 | 
					                                       queueManager.add(msg, position);
 | 
				
			||||||
 | 
					                                   }
 | 
				
			||||||
 | 
					                                   else
 | 
				
			||||||
 | 
					                                   {
 | 
				
			||||||
 | 
					                                       if (_onBotMessageCallback &&
 | 
				
			||||||
                                           _onBotMessageCallback(
 | 
					                                           _onBotMessageCallback(
 | 
				
			||||||
                            msg, position, throttled,
 | 
					                                               msg, position, verbose, throttled, fatalCobraError))
 | 
				
			||||||
                            fatalCobraError, sentCount);
 | 
					                                       {
 | 
				
			||||||
 | 
					                                           // That might be too noisy
 | 
				
			||||||
 | 
					                                           if (verbose)
 | 
				
			||||||
 | 
					                                           {
 | 
				
			||||||
 | 
					                                               CoreLogger::info("cobra bot: sending succesfull");
 | 
				
			||||||
 | 
					                                           }
 | 
				
			||||||
 | 
					                                           ++sentCount;
 | 
				
			||||||
 | 
					                                       }
 | 
				
			||||||
 | 
					                                       else
 | 
				
			||||||
 | 
					                                       {
 | 
				
			||||||
 | 
					                                           CoreLogger::error("cobra bot: error sending");
 | 
				
			||||||
 | 
					                                       }
 | 
				
			||||||
 | 
					                                   }
 | 
				
			||||||
                               });
 | 
					                               });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (event->type == ix::CobraEventType::Subscribed)
 | 
					            else if (event->type == ix::CobraEventType::Subscribed)
 | 
				
			||||||
@@ -258,6 +308,9 @@ namespace ix
 | 
				
			|||||||
        // heartbeat thread
 | 
					        // heartbeat thread
 | 
				
			||||||
        if (t2.joinable()) t2.join();
 | 
					        if (t2.joinable()) t2.join();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // sentry sender thread
 | 
				
			||||||
 | 
					        t3.join();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return fatalCobraError ? -1 : (int64_t) sentCount;
 | 
					        return fatalCobraError ? -1 : (int64_t) sentCount;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,24 +8,33 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
#include "IXCobraBotConfig.h"
 | 
					#include <ixcobra/IXCobraConfig.h>
 | 
				
			||||||
#include <json/json.h>
 | 
					#include <json/json.h>
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using OnBotMessageCallback = std::function<void(const Json::Value&,
 | 
					    using OnBotMessageCallback = std::function<bool(const Json::Value&,
 | 
				
			||||||
                                                    const std::string&,
 | 
					                                                    const std::string&,
 | 
				
			||||||
 | 
					                                                    const bool verbose,
 | 
				
			||||||
                                                    std::atomic<bool>&,
 | 
					                                                    std::atomic<bool>&,
 | 
				
			||||||
                                                    std::atomic<bool>&,
 | 
					                                                    std::atomic<bool>&)>;
 | 
				
			||||||
                                                    std::atomic<uint64_t>&)>;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class CobraBot
 | 
					    class CobraBot
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        CobraBot() = default;
 | 
					        CobraBot() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int64_t run(const CobraBotConfig& botConfig);
 | 
					        int64_t run(const CobraConfig& config,
 | 
				
			||||||
 | 
					                    const std::string& channel,
 | 
				
			||||||
 | 
					                    const std::string& filter,
 | 
				
			||||||
 | 
					                    const std::string& position,
 | 
				
			||||||
 | 
					                    bool verbose,
 | 
				
			||||||
 | 
					                    size_t maxQueueSize,
 | 
				
			||||||
 | 
					                    bool useQueue,
 | 
				
			||||||
 | 
					                    bool enableHeartbeat,
 | 
				
			||||||
 | 
					                    int runtime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setOnBotMessageCallback(const OnBotMessageCallback& callback);
 | 
					        void setOnBotMessageCallback(const OnBotMessageCallback& callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *  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
 | 
					 | 
				
			||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "IXCobraToSentryBot.h"
 | 
					#include "IXCobraToSentryBot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "IXCobraBot.h"
 | 
					#include "IXCobraBot.h"
 | 
				
			||||||
 | 
					#include "IXQueueManager.h"
 | 
				
			||||||
#include <ixcobra/IXCobraConnection.h>
 | 
					#include <ixcobra/IXCobraConnection.h>
 | 
				
			||||||
#include <ixcore/utils/IXCoreLogger.h>
 | 
					#include <ixcore/utils/IXCoreLogger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,31 +17,60 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t cobra_to_sentry_bot(const CobraBotConfig& config,
 | 
					    int64_t cobra_to_sentry_bot(const CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                SentryClient& sentryClient,
 | 
					                                SentryClient& sentryClient,
 | 
				
			||||||
                                bool verbose)
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        CobraBot bot;
 | 
					        CobraBot bot;
 | 
				
			||||||
        bot.setOnBotMessageCallback([&sentryClient, &verbose](const Json::Value& msg,
 | 
					        bot.setOnBotMessageCallback([&sentryClient](const Json::Value& msg,
 | 
				
			||||||
                                                    const std::string& /*position*/,
 | 
					                                                    const std::string& /*position*/,
 | 
				
			||||||
 | 
					                                                    const bool verbose,
 | 
				
			||||||
                                                    std::atomic<bool>& throttled,
 | 
					                                                    std::atomic<bool>& throttled,
 | 
				
			||||||
                                                    std::atomic<bool>& /*fatalCobraError*/,
 | 
					                                                    std::atomic<bool> &
 | 
				
			||||||
                                                    std::atomic<uint64_t>& sentCount) -> void {
 | 
					                                                    /*fatalCobraError*/) -> bool {
 | 
				
			||||||
            sentryClient.send(msg, verbose,
 | 
					            auto ret = sentryClient.send(msg, verbose);
 | 
				
			||||||
                [&sentCount, &throttled](const HttpResponsePtr& response) {
 | 
					            HttpResponsePtr response = ret.first;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!response)
 | 
					            if (!response)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                CoreLogger::warn("Null HTTP Response");
 | 
					                CoreLogger::warn("Null HTTP Response");
 | 
				
			||||||
                    return;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (response->statusCode == 200)
 | 
					            if (verbose)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                    sentCount++;
 | 
					                for (auto it : response->headers)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CoreLogger::info(it.first + ": " + it.second);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					
 | 
				
			||||||
 | 
					                CoreLogger::info("Upload size: " + std::to_string(response->uploadSize));
 | 
				
			||||||
 | 
					                CoreLogger::info("Download size: " + std::to_string(response->downloadSize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CoreLogger::info("Status: " + std::to_string(response->statusCode));
 | 
				
			||||||
 | 
					                if (response->errorCode != HttpErrorCode::Ok)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CoreLogger::info("error message: " + response->errorMsg);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (response->headers["Content-Type"] != "application/octet-stream")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CoreLogger::info("payload: " + response->payload);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool success = response->statusCode == 200;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!success)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                CoreLogger::error("Error sending data to sentry: " + std::to_string(response->statusCode));
 | 
					                CoreLogger::error("Error sending data to sentry: " + std::to_string(response->statusCode));
 | 
				
			||||||
 | 
					                CoreLogger::error("Body: " + ret.second);
 | 
				
			||||||
                CoreLogger::error("Response: " + response->payload);
 | 
					                CoreLogger::error("Response: " + response->payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Error 429 Too Many Requests
 | 
					                // Error 429 Too Many Requests
 | 
				
			||||||
@@ -68,9 +98,20 @@ namespace ix
 | 
				
			|||||||
                    throttled = false;
 | 
					                    throttled = false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            });
 | 
					
 | 
				
			||||||
 | 
					            return success;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return bot.run(config);
 | 
					        bool useQueue = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return bot.run(config,
 | 
				
			||||||
 | 
					                       channel,
 | 
				
			||||||
 | 
					                       filter,
 | 
				
			||||||
 | 
					                       position,
 | 
				
			||||||
 | 
					                       verbose,
 | 
				
			||||||
 | 
					                       maxQueueSize,
 | 
				
			||||||
 | 
					                       useQueue,
 | 
				
			||||||
 | 
					                       enableHeartbeat,
 | 
				
			||||||
 | 
					                       runtime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,13 +6,19 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include "IXCobraBotConfig.h"
 | 
					#include <ixcobra/IXCobraConfig.h>
 | 
				
			||||||
#include <ixsentry/IXSentryClient.h>
 | 
					#include <ixsentry/IXSentryClient.h>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t cobra_to_sentry_bot(const CobraBotConfig& config,
 | 
					    int64_t cobra_to_sentry_bot(const CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                SentryClient& sentryClient,
 | 
					                                SentryClient& sentryClient,
 | 
				
			||||||
                                bool verbose);
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime);
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "IXCobraToStatsdBot.h"
 | 
					#include "IXCobraToStatsdBot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "IXCobraBot.h"
 | 
					#include "IXCobraBot.h"
 | 
				
			||||||
 | 
					#include "IXQueueManager.h"
 | 
				
			||||||
#include "IXStatsdClient.h"
 | 
					#include "IXStatsdClient.h"
 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
#include <ixcobra/IXCobraConnection.h>
 | 
					#include <ixcobra/IXCobraConnection.h>
 | 
				
			||||||
@@ -53,22 +54,32 @@ namespace ix
 | 
				
			|||||||
        return val;
 | 
					        return val;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config,
 | 
					    int64_t cobra_to_statsd_bot(const ix::CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                StatsdClient& statsdClient,
 | 
					                                StatsdClient& statsdClient,
 | 
				
			||||||
                                const std::string& fields,
 | 
					                                const std::string& fields,
 | 
				
			||||||
                                const std::string& gauge,
 | 
					                                const std::string& gauge,
 | 
				
			||||||
                                const std::string& timer,
 | 
					                                const std::string& timer,
 | 
				
			||||||
                                bool verbose)
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        ix::CobraConnection conn;
 | 
				
			||||||
 | 
					        conn.configure(config);
 | 
				
			||||||
 | 
					        conn.connect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto tokens = parseFields(fields);
 | 
					        auto tokens = parseFields(fields);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CobraBot bot;
 | 
					        CobraBot bot;
 | 
				
			||||||
        bot.setOnBotMessageCallback(
 | 
					        bot.setOnBotMessageCallback(
 | 
				
			||||||
            [&statsdClient, &tokens, &gauge, &timer, &verbose](const Json::Value& msg,
 | 
					            [&statsdClient, &tokens, &gauge, &timer](const Json::Value& msg,
 | 
				
			||||||
                                                     const std::string& /*position*/,
 | 
					                                                     const std::string& /*position*/,
 | 
				
			||||||
 | 
					                                                     const bool verbose,
 | 
				
			||||||
                                                     std::atomic<bool>& /*throttled*/,
 | 
					                                                     std::atomic<bool>& /*throttled*/,
 | 
				
			||||||
                                                     std::atomic<bool>& fatalCobraError,
 | 
					                                                     std::atomic<bool>& fatalCobraError) -> bool {
 | 
				
			||||||
                                                     std::atomic<uint64_t>& sentCount) -> void {
 | 
					 | 
				
			||||||
                std::string id;
 | 
					                std::string id;
 | 
				
			||||||
                for (auto&& attr : tokens)
 | 
					                for (auto&& attr : tokens)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -111,7 +122,7 @@ namespace ix
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        CoreLogger::error("Gauge " + gauge + " is not a numeric type");
 | 
					                        CoreLogger::error("Gauge " + gauge + " is not a numeric type");
 | 
				
			||||||
                        fatalCobraError = true;
 | 
					                        fatalCobraError = true;
 | 
				
			||||||
                        return;
 | 
					                        return false;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (verbose)
 | 
					                    if (verbose)
 | 
				
			||||||
@@ -129,9 +140,19 @@ namespace ix
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                sentCount++;
 | 
					                return true;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return bot.run(config);
 | 
					        bool useQueue = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return bot.run(config,
 | 
				
			||||||
 | 
					                       channel,
 | 
				
			||||||
 | 
					                       filter,
 | 
				
			||||||
 | 
					                       position,
 | 
				
			||||||
 | 
					                       verbose,
 | 
				
			||||||
 | 
					                       maxQueueSize,
 | 
				
			||||||
 | 
					                       useQueue,
 | 
				
			||||||
 | 
					                       enableHeartbeat,
 | 
				
			||||||
 | 
					                       runtime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,16 +7,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include <ixbots/IXStatsdClient.h>
 | 
					#include <ixbots/IXStatsdClient.h>
 | 
				
			||||||
#include "IXCobraBotConfig.h"
 | 
					#include <ixcobra/IXCobraConfig.h>
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config,
 | 
					    int64_t cobra_to_statsd_bot(const ix::CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                StatsdClient& statsdClient,
 | 
					                                StatsdClient& statsdClient,
 | 
				
			||||||
                                const std::string& fields,
 | 
					                                const std::string& fields,
 | 
				
			||||||
                                const std::string& gauge,
 | 
					                                const std::string& gauge,
 | 
				
			||||||
                                const std::string& timer,
 | 
					                                const std::string& timer,
 | 
				
			||||||
                                bool verbose);
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime);
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "IXCobraToStdoutBot.h"
 | 
					#include "IXCobraToStdoutBot.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "IXCobraBot.h"
 | 
					#include "IXCobraBot.h"
 | 
				
			||||||
 | 
					#include "IXQueueManager.h"
 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
@@ -63,9 +64,16 @@ namespace ix
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config,
 | 
					    int64_t cobra_to_stdout_bot(const CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                bool fluentd,
 | 
					                                bool fluentd,
 | 
				
			||||||
                                bool quiet)
 | 
					                                bool quiet,
 | 
				
			||||||
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        CobraBot bot;
 | 
					        CobraBot bot;
 | 
				
			||||||
        auto jsonWriter = makeStreamWriter();
 | 
					        auto jsonWriter = makeStreamWriter();
 | 
				
			||||||
@@ -73,16 +81,27 @@ namespace ix
 | 
				
			|||||||
        bot.setOnBotMessageCallback(
 | 
					        bot.setOnBotMessageCallback(
 | 
				
			||||||
            [&fluentd, &quiet, &jsonWriter](const Json::Value& msg,
 | 
					            [&fluentd, &quiet, &jsonWriter](const Json::Value& msg,
 | 
				
			||||||
                                            const std::string& position,
 | 
					                                            const std::string& position,
 | 
				
			||||||
 | 
					                                            const bool /*verbose*/,
 | 
				
			||||||
                                            std::atomic<bool>& /*throttled*/,
 | 
					                                            std::atomic<bool>& /*throttled*/,
 | 
				
			||||||
                                            std::atomic<bool>& /*fatalCobraError*/,
 | 
					                                            std::atomic<bool> &
 | 
				
			||||||
                                            std::atomic<uint64_t>& sentCount) -> void {
 | 
					                                            /*fatalCobraError*/) -> bool {
 | 
				
			||||||
                if (!quiet)
 | 
					                if (!quiet)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    writeToStdout(fluentd, jsonWriter, msg, position);
 | 
					                    writeToStdout(fluentd, jsonWriter, msg, position);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                sentCount++;
 | 
					                return true;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return bot.run(config);
 | 
					        bool useQueue = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return bot.run(config,
 | 
				
			||||||
 | 
					                       channel,
 | 
				
			||||||
 | 
					                       filter,
 | 
				
			||||||
 | 
					                       position,
 | 
				
			||||||
 | 
					                       verbose,
 | 
				
			||||||
 | 
					                       maxQueueSize,
 | 
				
			||||||
 | 
					                       useQueue,
 | 
				
			||||||
 | 
					                       enableHeartbeat,
 | 
				
			||||||
 | 
					                       runtime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,13 +6,20 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include "IXCobraBotConfig.h"
 | 
					#include <ixcobra/IXCobraConfig.h>
 | 
				
			||||||
#include <stddef.h>
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config,
 | 
					    int64_t cobra_to_stdout_bot(const ix::CobraConfig& config,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const std::string& filter,
 | 
				
			||||||
 | 
					                                const std::string& position,
 | 
				
			||||||
                                bool fluentd,
 | 
					                                bool fluentd,
 | 
				
			||||||
                                bool quiet);
 | 
					                                bool quiet,
 | 
				
			||||||
 | 
					                                bool verbose,
 | 
				
			||||||
 | 
					                                size_t maxQueueSize,
 | 
				
			||||||
 | 
					                                bool enableHeartbeat,
 | 
				
			||||||
 | 
					                                int runtime);
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										67
									
								
								ixbots/ixbots/IXQueueManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								ixbots/ixbots/IXQueueManager.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  IXQueueManager.cpp
 | 
				
			||||||
 | 
					 *  Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					 *  Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "IXQueueManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    std::pair<Json::Value, std::string> QueueManager::pop()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::unique_lock<std::mutex> lock(_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_queues.empty())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Json::Value val;
 | 
				
			||||||
 | 
					            return std::make_pair(val, std::string());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::vector<std::string> games;
 | 
				
			||||||
 | 
					        for (auto it : _queues)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            games.push_back(it.first);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::random_shuffle(games.begin(), games.end());
 | 
				
			||||||
 | 
					        std::string game = games[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto duration = std::chrono::seconds(1);
 | 
				
			||||||
 | 
					        _condition.wait_for(lock, duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_queues[game].empty())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Json::Value val;
 | 
				
			||||||
 | 
					            return std::make_pair(val, std::string());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto msg = _queues[game].front();
 | 
				
			||||||
 | 
					        _queues[game].pop();
 | 
				
			||||||
 | 
					        return msg;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void QueueManager::add(const Json::Value& msg, const std::string& position)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::unique_lock<std::mutex> lock(_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string game;
 | 
				
			||||||
 | 
					        if (msg.isMember("device") && msg["device"].isMember("game"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            game = msg["device"]["game"].asString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (game.empty()) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // if the sending is not fast enough there is no point
 | 
				
			||||||
 | 
					        // in queuing too many events.
 | 
				
			||||||
 | 
					        if (_queues[game].size() < _maxQueueSize)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _queues[game].push(std::make_pair(msg, position));
 | 
				
			||||||
 | 
					            _condition.notify_one();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} // namespace ix
 | 
				
			||||||
							
								
								
									
										35
									
								
								ixbots/ixbots/IXQueueManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ixbots/ixbots/IXQueueManager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  IXQueueManager.h
 | 
				
			||||||
 | 
					 *  Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					 *  Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <condition_variable>
 | 
				
			||||||
 | 
					#include <json/json.h>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class QueueManager
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        QueueManager(size_t maxQueueSize)
 | 
				
			||||||
 | 
					            : _maxQueueSize(maxQueueSize)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::pair<Json::Value, std::string> pop();
 | 
				
			||||||
 | 
					        void add(const Json::Value& msg, const std::string& position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        std::map<std::string, std::queue<std::pair<Json::Value, std::string>>> _queues;
 | 
				
			||||||
 | 
					        std::mutex _mutex;
 | 
				
			||||||
 | 
					        std::condition_variable _condition;
 | 
				
			||||||
 | 
					        size_t _maxQueueSize;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					} // namespace ix
 | 
				
			||||||
@@ -226,23 +226,20 @@ namespace ix
 | 
				
			|||||||
        return _jsonWriter.write(payload);
 | 
					        return _jsonWriter.write(payload);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SentryClient::send(
 | 
					    std::pair<HttpResponsePtr, std::string> SentryClient::send(const Json::Value& msg, bool verbose)
 | 
				
			||||||
        const Json::Value& msg,
 | 
					 | 
				
			||||||
        bool verbose,
 | 
					 | 
				
			||||||
        const OnResponseCallback& onResponseCallback)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto args = _httpClient->createRequest();
 | 
					        auto args = _httpClient->createRequest();
 | 
				
			||||||
        args->url = _url;
 | 
					 | 
				
			||||||
        args->verb = HttpClient::kPost;
 | 
					 | 
				
			||||||
        args->extraHeaders["X-Sentry-Auth"] = SentryClient::computeAuthHeader();
 | 
					        args->extraHeaders["X-Sentry-Auth"] = SentryClient::computeAuthHeader();
 | 
				
			||||||
        args->connectTimeout = 60;
 | 
					        args->connectTimeout = 60;
 | 
				
			||||||
        args->transferTimeout = 5 * 60;
 | 
					        args->transferTimeout = 5 * 60;
 | 
				
			||||||
        args->followRedirects = true;
 | 
					        args->followRedirects = true;
 | 
				
			||||||
        args->verbose = verbose;
 | 
					        args->verbose = verbose;
 | 
				
			||||||
        args->logger = [](const std::string& msg) { CoreLogger::log(msg.c_str()); };
 | 
					        args->logger = [](const std::string& msg) { CoreLogger::log(msg.c_str()); };
 | 
				
			||||||
        args->body = computePayload(msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _httpClient->performRequest(args, onResponseCallback);
 | 
					        std::string body = computePayload(msg);
 | 
				
			||||||
 | 
					        HttpResponsePtr response = _httpClient->post(_url, body, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return std::make_pair(response, body);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // https://sentry.io/api/12345/minidump?sentry_key=abcdefgh");
 | 
					    // https://sentry.io/api/12345/minidump?sentry_key=abcdefgh");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,9 +21,12 @@ namespace ix
 | 
				
			|||||||
        SentryClient(const std::string& dsn);
 | 
					        SentryClient(const std::string& dsn);
 | 
				
			||||||
        ~SentryClient() = default;
 | 
					        ~SentryClient() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void send(const Json::Value& msg,
 | 
					        std::pair<HttpResponsePtr, std::string> send(const Json::Value& msg, bool verbose);
 | 
				
			||||||
                  bool verbose,
 | 
					
 | 
				
			||||||
                  const OnResponseCallback& onResponseCallback);
 | 
					        Json::Value parseLuaStackTrace(const std::string& stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Mostly for testing
 | 
				
			||||||
 | 
					        void setTLSOptions(const SocketTLSOptions& tlsOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void uploadMinidump(const std::string& sentryMetadata,
 | 
					        void uploadMinidump(const std::string& sentryMetadata,
 | 
				
			||||||
                            const std::string& minidumpBytes,
 | 
					                            const std::string& minidumpBytes,
 | 
				
			||||||
@@ -36,12 +39,6 @@ namespace ix
 | 
				
			|||||||
                           bool verbose,
 | 
					                           bool verbose,
 | 
				
			||||||
                           const OnResponseCallback& onResponseCallback);
 | 
					                           const OnResponseCallback& onResponseCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Json::Value parseLuaStackTrace(const std::string& stack);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Mostly for testing
 | 
					 | 
				
			||||||
        void setTLSOptions(const SocketTLSOptions& tlsOptions);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        int64_t getTimestamp();
 | 
					        int64_t getTimestamp();
 | 
				
			||||||
        std::string computeAuthHeader();
 | 
					        std::string computeAuthHeader();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "IXCancellationRequest.h"
 | 
					#include "IXCancellationRequest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cassert>
 | 
					 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
@@ -14,8 +13,6 @@ namespace ix
 | 
				
			|||||||
    CancellationRequest makeCancellationRequestWithTimeout(
 | 
					    CancellationRequest makeCancellationRequestWithTimeout(
 | 
				
			||||||
        int secs, std::atomic<bool>& requestInitCancellation)
 | 
					        int secs, std::atomic<bool>& requestInitCancellation)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        assert(secs > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto start = std::chrono::system_clock::now();
 | 
					        auto start = std::chrono::system_clock::now();
 | 
				
			||||||
        auto timeout = std::chrono::seconds(secs);
 | 
					        auto timeout = std::chrono::seconds(secs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,19 +4,6 @@
 | 
				
			|||||||
 *  Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
 | 
					 *  Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// On Windows Universal Platform (uwp), gai_strerror defaults behavior is to returns wchar_t
 | 
					 | 
				
			||||||
// which is different from all other platforms. We want the non unicode version.
 | 
					 | 
				
			||||||
// See https://github.com/microsoft/vcpkg/pull/11030
 | 
					 | 
				
			||||||
// We could do this in IXNetSystem.cpp but so far we are only using gai_strerror in here.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
#ifdef _UNICODE
 | 
					 | 
				
			||||||
#undef _UNICODE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef UNICODE
 | 
					 | 
				
			||||||
#undef UNICODE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "IXDNSLookup.h"
 | 
					#include "IXDNSLookup.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "IXNetSystem.h"
 | 
					#include "IXNetSystem.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,12 +25,10 @@ namespace ix
 | 
				
			|||||||
    const std::string HttpClient::kHead = "HEAD";
 | 
					    const std::string HttpClient::kHead = "HEAD";
 | 
				
			||||||
    const std::string HttpClient::kDel = "DEL";
 | 
					    const std::string HttpClient::kDel = "DEL";
 | 
				
			||||||
    const std::string HttpClient::kPut = "PUT";
 | 
					    const std::string HttpClient::kPut = "PUT";
 | 
				
			||||||
    const std::string HttpClient::kPatch = "PATCH";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpClient::HttpClient(bool async)
 | 
					    HttpClient::HttpClient(bool async)
 | 
				
			||||||
        : _async(async)
 | 
					        : _async(async)
 | 
				
			||||||
        , _stop(false)
 | 
					        , _stop(false)
 | 
				
			||||||
        , _forceBody(false)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!_async) return;
 | 
					        if (!_async) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,11 +49,6 @@ namespace ix
 | 
				
			|||||||
        _tlsOptions = tlsOptions;
 | 
					        _tlsOptions = tlsOptions;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void HttpClient::setForceBody(bool value)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        _forceBody = value;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HttpRequestArgsPtr HttpClient::createRequest(const std::string& url, const std::string& verb)
 | 
					    HttpRequestArgsPtr HttpClient::createRequest(const std::string& url, const std::string& verb)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        auto request = std::make_shared<HttpRequestArgs>();
 | 
					        auto request = std::make_shared<HttpRequestArgs>();
 | 
				
			||||||
@@ -199,7 +192,7 @@ namespace ix
 | 
				
			|||||||
            ss << "User-Agent: " << userAgent() << "\r\n";
 | 
					            ss << "User-Agent: " << userAgent() << "\r\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (verb == kPost || verb == kPut || verb == kPatch || _forceBody)
 | 
					        if (verb == kPost || verb == kPut)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ss << "Content-Length: " << body.size() << "\r\n";
 | 
					            ss << "Content-Length: " << body.size() << "\r\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -227,10 +220,11 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::string req(ss.str());
 | 
					        std::string req(ss.str());
 | 
				
			||||||
        std::string errMsg;
 | 
					        std::string errMsg;
 | 
				
			||||||
 | 
					        std::atomic<bool> requestInitCancellation(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Make a cancellation object dealing with connection timeout
 | 
					        // Make a cancellation object dealing with connection timeout
 | 
				
			||||||
        auto isCancellationRequested =
 | 
					        auto isCancellationRequested =
 | 
				
			||||||
            makeCancellationRequestWithTimeout(args->connectTimeout, _stop);
 | 
					            makeCancellationRequestWithTimeout(args->connectTimeout, requestInitCancellation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool success = _socket->connect(host, port, errMsg, isCancellationRequested);
 | 
					        bool success = _socket->connect(host, port, errMsg, isCancellationRequested);
 | 
				
			||||||
        if (!success)
 | 
					        if (!success)
 | 
				
			||||||
@@ -248,7 +242,8 @@ namespace ix
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Make a new cancellation object dealing with transfer timeout
 | 
					        // Make a new cancellation object dealing with transfer timeout
 | 
				
			||||||
        isCancellationRequested = makeCancellationRequestWithTimeout(args->transferTimeout, _stop);
 | 
					        isCancellationRequested =
 | 
				
			||||||
 | 
					            makeCancellationRequestWithTimeout(args->transferTimeout, requestInitCancellation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (args->verbose)
 | 
					        if (args->verbose)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -567,20 +562,6 @@ namespace ix
 | 
				
			|||||||
        return request(url, kPut, body, args);
 | 
					        return request(url, kPut, body, args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponsePtr HttpClient::patch(const std::string& url,
 | 
					 | 
				
			||||||
                                      const HttpParameters& httpParameters,
 | 
					 | 
				
			||||||
                                      HttpRequestArgsPtr args)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return request(url, kPatch, serializeHttpParameters(httpParameters), args);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HttpResponsePtr HttpClient::patch(const std::string& url,
 | 
					 | 
				
			||||||
                                      const std::string& body,
 | 
					 | 
				
			||||||
                                      const HttpRequestArgsPtr args)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return request(url, kPatch, body, args);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string HttpClient::urlEncode(const std::string& value)
 | 
					    std::string HttpClient::urlEncode(const std::string& value)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::ostringstream escaped;
 | 
					        std::ostringstream escaped;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,19 +46,12 @@ namespace ix
 | 
				
			|||||||
                            const std::string& body,
 | 
					                            const std::string& body,
 | 
				
			||||||
                            HttpRequestArgsPtr args);
 | 
					                            HttpRequestArgsPtr args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        HttpResponsePtr patch(const std::string& url,
 | 
					 | 
				
			||||||
                              const HttpParameters& httpParameters,
 | 
					 | 
				
			||||||
                              HttpRequestArgsPtr args);
 | 
					 | 
				
			||||||
        HttpResponsePtr patch(const std::string& url,
 | 
					 | 
				
			||||||
                              const std::string& body,
 | 
					 | 
				
			||||||
                              HttpRequestArgsPtr args);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        HttpResponsePtr request(const std::string& url,
 | 
					        HttpResponsePtr request(const std::string& url,
 | 
				
			||||||
                                const std::string& verb,
 | 
					                                const std::string& verb,
 | 
				
			||||||
                                const std::string& body,
 | 
					                                const std::string& body,
 | 
				
			||||||
                                HttpRequestArgsPtr args,
 | 
					                                HttpRequestArgsPtr args,
 | 
				
			||||||
                                int redirects = 0);
 | 
					                                int redirects = 0);
 | 
				
			||||||
        void setForceBody(bool value);
 | 
					
 | 
				
			||||||
        // Async API
 | 
					        // Async API
 | 
				
			||||||
        HttpRequestArgsPtr createRequest(const std::string& url = std::string(),
 | 
					        HttpRequestArgsPtr createRequest(const std::string& url = std::string(),
 | 
				
			||||||
                                         const std::string& verb = HttpClient::kGet);
 | 
					                                         const std::string& verb = HttpClient::kGet);
 | 
				
			||||||
@@ -85,7 +78,6 @@ namespace ix
 | 
				
			|||||||
        const static std::string kHead;
 | 
					        const static std::string kHead;
 | 
				
			||||||
        const static std::string kDel;
 | 
					        const static std::string kDel;
 | 
				
			||||||
        const static std::string kPut;
 | 
					        const static std::string kPut;
 | 
				
			||||||
        const static std::string kPatch;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        void log(const std::string& msg, HttpRequestArgsPtr args);
 | 
					        void log(const std::string& msg, HttpRequestArgsPtr args);
 | 
				
			||||||
@@ -94,6 +86,7 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Async API background thread runner
 | 
					        // Async API background thread runner
 | 
				
			||||||
        void run();
 | 
					        void run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Async API
 | 
					        // Async API
 | 
				
			||||||
        bool _async;
 | 
					        bool _async;
 | 
				
			||||||
        std::queue<std::pair<HttpRequestArgsPtr, OnResponseCallback>> _queue;
 | 
					        std::queue<std::pair<HttpRequestArgsPtr, OnResponseCallback>> _queue;
 | 
				
			||||||
@@ -106,7 +99,5 @@ namespace ix
 | 
				
			|||||||
        std::mutex _mutex; // to protect accessing the _socket (only one socket per client)
 | 
					        std::mutex _mutex; // to protect accessing the _socket (only one socket per client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SocketTLSOptions _tlsOptions;
 | 
					        SocketTLSOptions _tlsOptions;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        bool _forceBody;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@ typedef unsigned long int nfds_t;
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <netdb.h>
 | 
					#include <netdb.h>
 | 
				
			||||||
#include <netinet/in.h>
 | 
					#include <netinet/in.h>
 | 
				
			||||||
#include <netinet/ip.h>
 | 
					#include <netinet/ip.h>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,55 +43,6 @@ namespace ix
 | 
				
			|||||||
        mbedtls_pk_init(&_pkey);
 | 
					        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)
 | 
					    bool SocketMbedTLS::init(const std::string& host, bool isClient, std::string& errMsg)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        initMBedTLS();
 | 
					        initMBedTLS();
 | 
				
			||||||
@@ -145,15 +96,13 @@ namespace ix
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // FIXME: should we call mbedtls_ssl_conf_verify ?
 | 
					 | 
				
			||||||
            mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
 | 
					            mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // FIXME: should we call mbedtls_ssl_conf_verify ?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (_tlsOptions.isUsingSystemDefaults())
 | 
					            if (_tlsOptions.isUsingSystemDefaults())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!loadSystemCertificates(errMsg))
 | 
					                ; // FIXME
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,6 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        bool init(const std::string& host, bool isClient, std::string& errMsg);
 | 
					        bool init(const std::string& host, bool isClient, std::string& errMsg);
 | 
				
			||||||
        void initMBedTLS();
 | 
					        void initMBedTLS();
 | 
				
			||||||
        bool loadSystemCertificates(std::string& errMsg);
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,8 +85,6 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::atomic<bool> SocketOpenSSL::_openSSLInitializationSuccessful(false);
 | 
					    std::atomic<bool> SocketOpenSSL::_openSSLInitializationSuccessful(false);
 | 
				
			||||||
    std::once_flag SocketOpenSSL::_openSSLInitFlag;
 | 
					    std::once_flag SocketOpenSSL::_openSSLInitFlag;
 | 
				
			||||||
    std::unique_ptr<std::mutex[]> SocketOpenSSL::_openSSLMutexes =
 | 
					 | 
				
			||||||
        std::make_unique<std::mutex[]>(CRYPTO_num_locks());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SocketOpenSSL::SocketOpenSSL(const SocketTLSOptions& tlsOptions, int fd)
 | 
					    SocketOpenSSL::SocketOpenSSL(const SocketTLSOptions& tlsOptions, int fd)
 | 
				
			||||||
        : Socket(fd)
 | 
					        : Socket(fd)
 | 
				
			||||||
@@ -108,11 +106,6 @@ namespace ix
 | 
				
			|||||||
        if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr)) return;
 | 
					        if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr)) return;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
        (void) OPENSSL_config(nullptr);
 | 
					        (void) OPENSSL_config(nullptr);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (CRYPTO_get_locking_callback() == nullptr)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            CRYPTO_set_locking_callback(SocketOpenSSL::openSSLLockingCallback);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (void) OpenSSL_add_ssl_algorithms();
 | 
					        (void) OpenSSL_add_ssl_algorithms();
 | 
				
			||||||
@@ -121,21 +114,6 @@ namespace ix
 | 
				
			|||||||
        _openSSLInitializationSuccessful = true;
 | 
					        _openSSLInitializationSuccessful = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SocketOpenSSL::openSSLLockingCallback(int mode,
 | 
					 | 
				
			||||||
                                               int type,
 | 
					 | 
				
			||||||
                                               const char* /*file*/,
 | 
					 | 
				
			||||||
                                               int /*line*/)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (mode & CRYPTO_LOCK)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _openSSLMutexes[type].lock();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _openSSLMutexes[type].unlock();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string SocketOpenSSL::getSSLError(int ret)
 | 
					    std::string SocketOpenSSL::getSSLError(int ret)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        unsigned long e;
 | 
					        unsigned long e;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,9 +49,6 @@ namespace ix
 | 
				
			|||||||
        bool handleTLSOptions(std::string& errMsg);
 | 
					        bool handleTLSOptions(std::string& errMsg);
 | 
				
			||||||
        bool openSSLServerHandshake(std::string& errMsg);
 | 
					        bool openSSLServerHandshake(std::string& errMsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Required for OpenSSL < 1.1
 | 
					 | 
				
			||||||
        static void openSSLLockingCallback(int mode, int type, const char* /*file*/, int /*line*/);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SSL* _ssl_connection;
 | 
					        SSL* _ssl_connection;
 | 
				
			||||||
        SSL_CTX* _ssl_context;
 | 
					        SSL_CTX* _ssl_context;
 | 
				
			||||||
        const SSL_METHOD* _ssl_method;
 | 
					        const SSL_METHOD* _ssl_method;
 | 
				
			||||||
@@ -61,7 +58,6 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        static std::once_flag _openSSLInitFlag;
 | 
					        static std::once_flag _openSSLInitFlag;
 | 
				
			||||||
        static std::atomic<bool> _openSSLInitializationSuccessful;
 | 
					        static std::atomic<bool> _openSSLInitializationSuccessful;
 | 
				
			||||||
        static std::unique_ptr<std::mutex[]> _openSSLMutexes;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,18 +44,6 @@ namespace ix
 | 
				
			|||||||
        return err;
 | 
					        return err;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool UdpSocket::isWaitNeeded()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        int err = getErrno();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (err == EWOULDBLOCK || err == EAGAIN || err == EINPROGRESS)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void UdpSocket::closeSocket(int fd)
 | 
					    void UdpSocket::closeSocket(int fd)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
@@ -74,13 +62,6 @@ namespace ix
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					 | 
				
			||||||
        unsigned long nonblocking = 1;
 | 
					 | 
				
			||||||
        ioctlsocket(_sockfd, FIONBIO, &nonblocking);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        fcntl(_sockfd, F_SETFL, O_NONBLOCK); // make socket non blocking
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        memset(&_server, 0, sizeof(_server));
 | 
					        memset(&_server, 0, sizeof(_server));
 | 
				
			||||||
        _server.sin_family = AF_INET;
 | 
					        _server.sin_family = AF_INET;
 | 
				
			||||||
        _server.sin_port = htons(port);
 | 
					        _server.sin_port = htons(port);
 | 
				
			||||||
@@ -112,15 +93,4 @@ namespace ix
 | 
				
			|||||||
        return (ssize_t)::sendto(
 | 
					        return (ssize_t)::sendto(
 | 
				
			||||||
            _sockfd, buffer.data(), buffer.size(), 0, (struct sockaddr*) &_server, sizeof(_server));
 | 
					            _sockfd, buffer.data(), buffer.size(), 0, (struct sockaddr*) &_server, sizeof(_server));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ssize_t UdpSocket::recvfrom(char* buffer, size_t length)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
#ifdef _WIN32
 | 
					 | 
				
			||||||
        int addressLen = (int) sizeof(_server);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        socklen_t addressLen = (socklen_t) sizeof(_server);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        return (ssize_t)::recvfrom(
 | 
					 | 
				
			||||||
            _sockfd, buffer, length, 0, (struct sockaddr*) &_server, &addressLen);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,12 +28,9 @@ namespace ix
 | 
				
			|||||||
        // Virtual methods
 | 
					        // Virtual methods
 | 
				
			||||||
        bool init(const std::string& host, int port, std::string& errMsg);
 | 
					        bool init(const std::string& host, int port, std::string& errMsg);
 | 
				
			||||||
        ssize_t sendto(const std::string& buffer);
 | 
					        ssize_t sendto(const std::string& buffer);
 | 
				
			||||||
        ssize_t recvfrom(char* buffer, size_t length);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void close();
 | 
					        void close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static int getErrno();
 | 
					        static int getErrno();
 | 
				
			||||||
        static bool isWaitNeeded();
 | 
					 | 
				
			||||||
        static void closeSocket(int fd);
 | 
					        static void closeSocket(int fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <algorithm>
 | 
					#include <algorithm>
 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
#include <cstdlib>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IX_WEBSOCKET_VERSION "9.6.4"
 | 
					#define IX_WEBSOCKET_VERSION "9.5.2"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								makefile
									
									
									
									
									
								
							@@ -20,13 +20,13 @@ install: brew
 | 
				
			|||||||
# Release, Debug, MinSizeRel, RelWithDebInfo are the build types
 | 
					# Release, Debug, MinSizeRel, RelWithDebInfo are the build types
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
brew:
 | 
					brew:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; ninja install)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; make -j 4 install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Docker default target. We've add problem with OpenSSL and TLS 1.3 (on the
 | 
					# Docker default target. We've add problem with OpenSSL and TLS 1.3 (on the
 | 
				
			||||||
# server side ?) and I can't work-around it easily, so we're using mbedtls on
 | 
					# server side ?) and I can't work-around it easily, so we're using mbedtls on
 | 
				
			||||||
# Linux for the SSL backend, which works great.
 | 
					# Linux for the SSL backend, which works great.
 | 
				
			||||||
ws_mbedtls_install:
 | 
					ws_mbedtls_install:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ws:
 | 
					ws:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4)
 | 
				
			||||||
@@ -103,10 +103,6 @@ test_server:
 | 
				
			|||||||
# env TEST=Websocket_chat make test
 | 
					# env TEST=Websocket_chat make test
 | 
				
			||||||
# env TEST=heartbeat make test
 | 
					# env TEST=heartbeat make test
 | 
				
			||||||
test:
 | 
					test:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; ninja install)
 | 
					 | 
				
			||||||
	(cd test ; python2.7 run.py -r)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test_make:
 | 
					 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; make -j 4)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; make -j 4)
 | 
				
			||||||
	(cd test ; python2.7 run.py -r)
 | 
						(cd test ; python2.7 run.py -r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,7 +144,7 @@ test_tsan_mbedtls:
 | 
				
			|||||||
	(cd test ; python2.7 run.py -r)
 | 
						(cd test ; python2.7 run.py -r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build_test_openssl:
 | 
					build_test_openssl:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_OPEN_SSL=1 -DUSE_TEST=1 .. ; ninja install)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_OPEN_SSL=1 -DUSE_TEST=1 .. ; make -j 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_openssl: build_test_openssl
 | 
					test_openssl: build_test_openssl
 | 
				
			||||||
	(cd test ; python2.7 run.py -r)
 | 
						(cd test ; python2.7 run.py -r)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,12 +138,11 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread publisherThread(runPublisher, config, channel);
 | 
					        std::thread publisherThread(runPublisher, config, channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ix::CobraBotConfig cobraBotConfig;
 | 
					        std::string filter;
 | 
				
			||||||
        cobraBotConfig.cobraConfig = config;
 | 
					        std::string position("$");
 | 
				
			||||||
        cobraBotConfig.channel = channel;
 | 
					 | 
				
			||||||
        cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
 | 
					 | 
				
			||||||
        cobraBotConfig.enableHeartbeat = false;
 | 
					 | 
				
			||||||
        bool verbose = true;
 | 
					        bool verbose = true;
 | 
				
			||||||
 | 
					        size_t maxQueueSize = 10;
 | 
				
			||||||
 | 
					        bool enableHeartbeat = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // FIXME: try to get this working with https instead of http
 | 
					        // FIXME: try to get this working with https instead of http
 | 
				
			||||||
        //        to regress the TLS 1.3 OpenSSL bug
 | 
					        //        to regress the TLS 1.3 OpenSSL bug
 | 
				
			||||||
@@ -158,7 +157,18 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]")
 | 
				
			|||||||
        SentryClient sentryClient(dsn);
 | 
					        SentryClient sentryClient(dsn);
 | 
				
			||||||
        sentryClient.setTLSOptions(tlsOptionsClient);
 | 
					        sentryClient.setTLSOptions(tlsOptionsClient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int64_t sentCount = cobra_to_sentry_bot(cobraBotConfig, sentryClient, verbose);
 | 
					        // Only run the bot for 3 seconds
 | 
				
			||||||
 | 
					        int runtime = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int64_t sentCount = cobra_to_sentry_bot(config,
 | 
				
			||||||
 | 
					                                                channel,
 | 
				
			||||||
 | 
					                                                filter,
 | 
				
			||||||
 | 
					                                                position,
 | 
				
			||||||
 | 
					                                                sentryClient,
 | 
				
			||||||
 | 
					                                                verbose,
 | 
				
			||||||
 | 
					                                                maxQueueSize,
 | 
				
			||||||
 | 
					                                                enableHeartbeat,
 | 
				
			||||||
 | 
					                                                runtime);
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // We want at least 2 messages to be sent
 | 
					        // We want at least 2 messages to be sent
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,11 +87,14 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread publisherThread(runPublisher, config, channel);
 | 
					        std::thread publisherThread(runPublisher, config, channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ix::CobraBotConfig cobraBotConfig;
 | 
					        std::string filter;
 | 
				
			||||||
        cobraBotConfig.cobraConfig = config;
 | 
					        std::string position("$");
 | 
				
			||||||
        cobraBotConfig.channel = channel;
 | 
					        bool verbose = true;
 | 
				
			||||||
        cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
 | 
					        size_t maxQueueSize = 10;
 | 
				
			||||||
        cobraBotConfig.enableHeartbeat = false;
 | 
					        bool enableHeartbeat = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Only run the bot for 3 seconds
 | 
				
			||||||
 | 
					        int runtime = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string hostname("127.0.0.1");
 | 
					        std::string hostname("127.0.0.1");
 | 
				
			||||||
        // std::string hostname("www.google.com");
 | 
					        // std::string hostname("www.google.com");
 | 
				
			||||||
@@ -110,10 +113,19 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]")
 | 
				
			|||||||
        std::string fields("device.game\ndevice.os_name");
 | 
					        std::string fields("device.game\ndevice.os_name");
 | 
				
			||||||
        std::string gauge;
 | 
					        std::string gauge;
 | 
				
			||||||
        std::string timer;
 | 
					        std::string timer;
 | 
				
			||||||
        bool verbose = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int64_t sentCount =
 | 
					        int64_t sentCount = ix::cobra_to_statsd_bot(config,
 | 
				
			||||||
            ix::cobra_to_statsd_bot(cobraBotConfig, statsdClient, fields, gauge, timer, verbose);
 | 
					                                                    channel,
 | 
				
			||||||
 | 
					                                                    filter,
 | 
				
			||||||
 | 
					                                                    position,
 | 
				
			||||||
 | 
					                                                    statsdClient,
 | 
				
			||||||
 | 
					                                                    fields,
 | 
				
			||||||
 | 
					                                                    gauge,
 | 
				
			||||||
 | 
					                                                    timer,
 | 
				
			||||||
 | 
					                                                    verbose,
 | 
				
			||||||
 | 
					                                                    maxQueueSize,
 | 
				
			||||||
 | 
					                                                    enableHeartbeat,
 | 
				
			||||||
 | 
					                                                    runtime);
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // We want at least 2 messages to be sent
 | 
					        // We want at least 2 messages to be sent
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,17 +85,29 @@ TEST_CASE("Cobra_to_stdout_bot", "[cobra_bots]")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread publisherThread(runPublisher, config, channel);
 | 
					        std::thread publisherThread(runPublisher, config, channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ix::CobraBotConfig cobraBotConfig;
 | 
					        std::string filter;
 | 
				
			||||||
        cobraBotConfig.cobraConfig = config;
 | 
					        std::string position("$");
 | 
				
			||||||
        cobraBotConfig.channel = channel;
 | 
					        bool verbose = true;
 | 
				
			||||||
        cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds
 | 
					 | 
				
			||||||
        cobraBotConfig.enableHeartbeat = false;
 | 
					 | 
				
			||||||
        bool quiet = false;
 | 
					        bool quiet = false;
 | 
				
			||||||
 | 
					        size_t maxQueueSize = 10;
 | 
				
			||||||
 | 
					        bool enableHeartbeat = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Only run the bot for 3 seconds
 | 
				
			||||||
 | 
					        int runtime = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // We could try to capture the output ... not sure how.
 | 
					        // We could try to capture the output ... not sure how.
 | 
				
			||||||
        bool fluentd = true;
 | 
					        bool fluentd = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, quiet);
 | 
					        int64_t sentCount = ix::cobra_to_stdout_bot(config,
 | 
				
			||||||
 | 
					                                                    channel,
 | 
				
			||||||
 | 
					                                                    filter,
 | 
				
			||||||
 | 
					                                                    position,
 | 
				
			||||||
 | 
					                                                    fluentd,
 | 
				
			||||||
 | 
					                                                    quiet,
 | 
				
			||||||
 | 
					                                                    verbose,
 | 
				
			||||||
 | 
					                                                    maxQueueSize,
 | 
				
			||||||
 | 
					                                                    enableHeartbeat,
 | 
				
			||||||
 | 
					                                                    runtime);
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // We want at least 2 messages to be sent
 | 
					        // We want at least 2 messages to be sent
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,6 @@
 | 
				
			|||||||
 *  Copyright (c) 2019 Machine Zone. All rights reserved.
 | 
					 *  Copyright (c) 2019 Machine Zone. All rights reserved.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Using inet_addr will trigger an error on uwp without this
 | 
					 | 
				
			||||||
// FIXME: use a different api
 | 
					 | 
				
			||||||
#ifdef _WIN32
 | 
					 | 
				
			||||||
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
 | 
					 | 
				
			||||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "IXGetFreePort.h"
 | 
					#include "IXGetFreePort.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ixwebsocket/IXNetSystem.h>
 | 
					#include <ixwebsocket/IXNetSystem.h>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,11 +93,10 @@ TEST_CASE("subprotocol", "[websocket_subprotocol]")
 | 
				
			|||||||
        webSocket.setUrl(url);
 | 
					        webSocket.setUrl(url);
 | 
				
			||||||
        webSocket.start();
 | 
					        webSocket.start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Give us 3 seconds to connect
 | 
					 | 
				
			||||||
        int attempts = 0;
 | 
					        int attempts = 0;
 | 
				
			||||||
        while (!connected)
 | 
					        while (!connected)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            REQUIRE(attempts++ < 300);
 | 
					            REQUIRE(attempts++ < 10);
 | 
				
			||||||
            ix::msleep(10);
 | 
					            ix::msleep(10);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										89
									
								
								ws/ws.cpp
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								ws/ws.cpp
									
									
									
									
									
								
							@@ -19,8 +19,8 @@
 | 
				
			|||||||
#include <ixwebsocket/IXNetSystem.h>
 | 
					#include <ixwebsocket/IXNetSystem.h>
 | 
				
			||||||
#include <ixwebsocket/IXSocket.h>
 | 
					#include <ixwebsocket/IXSocket.h>
 | 
				
			||||||
#include <ixwebsocket/IXUserAgent.h>
 | 
					#include <ixwebsocket/IXUserAgent.h>
 | 
				
			||||||
#include <spdlog/sinks/basic_file_sink.h>
 | 
					 | 
				
			||||||
#include <spdlog/spdlog.h>
 | 
					#include <spdlog/spdlog.h>
 | 
				
			||||||
 | 
					#include <spdlog/sinks/basic_file_sink.h>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,7 +120,6 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    std::string logfile;
 | 
					    std::string logfile;
 | 
				
			||||||
    ix::SocketTLSOptions tlsOptions;
 | 
					    ix::SocketTLSOptions tlsOptions;
 | 
				
			||||||
    ix::CobraConfig cobraConfig;
 | 
					    ix::CobraConfig cobraConfig;
 | 
				
			||||||
    ix::CobraBotConfig cobraBotConfig;
 | 
					 | 
				
			||||||
    std::string ciphers;
 | 
					    std::string ciphers;
 | 
				
			||||||
    std::string redirectUrl;
 | 
					    std::string redirectUrl;
 | 
				
			||||||
    bool headersOnly = false;
 | 
					    bool headersOnly = false;
 | 
				
			||||||
@@ -149,7 +148,9 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    int delayMs = -1;
 | 
					    int delayMs = -1;
 | 
				
			||||||
    int count = 1;
 | 
					    int count = 1;
 | 
				
			||||||
    uint32_t maxWaitBetweenReconnectionRetries;
 | 
					    uint32_t maxWaitBetweenReconnectionRetries;
 | 
				
			||||||
 | 
					    size_t maxQueueSize = 100;
 | 
				
			||||||
    int pingIntervalSecs = 30;
 | 
					    int pingIntervalSecs = 30;
 | 
				
			||||||
 | 
					    int runtime = -1; // run indefinitely
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto addTLSOptions = [&tlsOptions, &verifyNone](CLI::App* app) {
 | 
					    auto addTLSOptions = [&tlsOptions, &verifyNone](CLI::App* app) {
 | 
				
			||||||
        app->add_option(
 | 
					        app->add_option(
 | 
				
			||||||
@@ -173,24 +174,6 @@ int main(int argc, char** argv)
 | 
				
			|||||||
        app->add_option("--rolesecret", cobraConfig.rolesecret, "Role secret")->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_flag("--version", version, "Print ws version");
 | 
					    app.add_flag("--version", version, "Print ws version");
 | 
				
			||||||
    app.add_option("--logfile", logfile, "path where all logs will be redirected");
 | 
					    app.add_option("--logfile", logfile, "path where all logs will be redirected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -298,11 +281,15 @@ int main(int argc, char** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    CLI::App* cobraSubscribeApp = app.add_subcommand("cobra_subscribe", "Cobra subscriber");
 | 
					    CLI::App* cobraSubscribeApp = app.add_subcommand("cobra_subscribe", "Cobra subscriber");
 | 
				
			||||||
    cobraSubscribeApp->fallthrough();
 | 
					    cobraSubscribeApp->fallthrough();
 | 
				
			||||||
 | 
					    cobraSubscribeApp->add_option("--channel", channel, "Channel")->required();
 | 
				
			||||||
    cobraSubscribeApp->add_option("--pidfile", pidfile, "Pid file");
 | 
					    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("-q", quiet, "Quiet / only display stats");
 | 
				
			||||||
    cobraSubscribeApp->add_flag("--fluentd", fluentd, "Write fluentd prefix");
 | 
					    cobraSubscribeApp->add_flag("--fluentd", fluentd, "Write fluentd prefix");
 | 
				
			||||||
 | 
					    cobraSubscribeApp->add_option("--runtime", runtime, "Runtime in seconds");
 | 
				
			||||||
    addTLSOptions(cobraSubscribeApp);
 | 
					    addTLSOptions(cobraSubscribeApp);
 | 
				
			||||||
    addCobraBotConfig(cobraSubscribeApp);
 | 
					    addCobraConfig(cobraSubscribeApp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher");
 | 
					    CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher");
 | 
				
			||||||
    cobraPublish->fallthrough();
 | 
					    cobraPublish->fallthrough();
 | 
				
			||||||
@@ -336,18 +323,32 @@ int main(int argc, char** argv)
 | 
				
			|||||||
        ->join();
 | 
					        ->join();
 | 
				
			||||||
    cobra2statsd->add_option("--timer", timer, "Value to extract, and use as a statsd timer")
 | 
					    cobra2statsd->add_option("--timer", timer, "Value to extract, and use as a statsd timer")
 | 
				
			||||||
        ->join();
 | 
					        ->join();
 | 
				
			||||||
 | 
					    cobra2statsd->add_option("channel", channel, "Channel")->required();
 | 
				
			||||||
    cobra2statsd->add_flag("-v", verbose, "Verbose");
 | 
					    cobra2statsd->add_flag("-v", verbose, "Verbose");
 | 
				
			||||||
    cobra2statsd->add_option("--pidfile", pidfile, "Pid file");
 | 
					    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("--queue_size",
 | 
				
			||||||
 | 
					                             maxQueueSize,
 | 
				
			||||||
 | 
					                             "Size of the queue to hold messages before they are sent to Sentry");
 | 
				
			||||||
 | 
					    cobra2statsd->add_option("--runtime", runtime, "Runtime in seconds");
 | 
				
			||||||
    addTLSOptions(cobra2statsd);
 | 
					    addTLSOptions(cobra2statsd);
 | 
				
			||||||
    addCobraBotConfig(cobra2statsd);
 | 
					    addCobraConfig(cobra2statsd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra metrics to sentry");
 | 
					    CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra metrics to sentry");
 | 
				
			||||||
    cobra2sentry->fallthrough();
 | 
					    cobra2sentry->fallthrough();
 | 
				
			||||||
    cobra2sentry->add_option("--dsn", dsn, "Sentry DSN");
 | 
					    cobra2sentry->add_option("--dsn", dsn, "Sentry DSN");
 | 
				
			||||||
 | 
					    cobra2sentry->add_option("--queue_size",
 | 
				
			||||||
 | 
					                             maxQueueSize,
 | 
				
			||||||
 | 
					                             "Size of the queue to hold messages before they are sent to Sentry");
 | 
				
			||||||
 | 
					    cobra2sentry->add_option("channel", channel, "Channel")->required();
 | 
				
			||||||
    cobra2sentry->add_flag("-v", verbose, "Verbose");
 | 
					    cobra2sentry->add_flag("-v", verbose, "Verbose");
 | 
				
			||||||
    cobra2sentry->add_option("--pidfile", pidfile, "Pid file");
 | 
					    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");
 | 
				
			||||||
    addTLSOptions(cobra2sentry);
 | 
					    addTLSOptions(cobra2sentry);
 | 
				
			||||||
    addCobraBotConfig(cobra2sentry);
 | 
					    addCobraConfig(cobra2sentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CLI::App* cobra2redisApp =
 | 
					    CLI::App* cobra2redisApp =
 | 
				
			||||||
        app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis");
 | 
					        app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis");
 | 
				
			||||||
@@ -458,10 +459,6 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    cobraConfig.webSocketPerMessageDeflateOptions = ix::WebSocketPerMessageDeflateOptions(true);
 | 
					    cobraConfig.webSocketPerMessageDeflateOptions = ix::WebSocketPerMessageDeflateOptions(true);
 | 
				
			||||||
    cobraConfig.socketTLSOptions = tlsOptions;
 | 
					    cobraConfig.socketTLSOptions = tlsOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cobraBotConfig.cobraConfig.webSocketPerMessageDeflateOptions =
 | 
					 | 
				
			||||||
        ix::WebSocketPerMessageDeflateOptions(true);
 | 
					 | 
				
			||||||
    cobraBotConfig.cobraConfig.socketTLSOptions = tlsOptions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int ret = 1;
 | 
					    int ret = 1;
 | 
				
			||||||
    if (app.got_subcommand("transfer"))
 | 
					    if (app.got_subcommand("transfer"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -531,7 +528,17 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (app.got_subcommand("cobra_subscribe"))
 | 
					    else if (app.got_subcommand("cobra_subscribe"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, quiet);
 | 
					        bool enableHeartbeat = true;
 | 
				
			||||||
 | 
					        int64_t sentCount = ix::cobra_to_stdout_bot(cobraConfig,
 | 
				
			||||||
 | 
					                                                    channel,
 | 
				
			||||||
 | 
					                                                    filter,
 | 
				
			||||||
 | 
					                                                    position,
 | 
				
			||||||
 | 
					                                                    fluentd,
 | 
				
			||||||
 | 
					                                                    quiet,
 | 
				
			||||||
 | 
					                                                    verbose,
 | 
				
			||||||
 | 
					                                                    maxQueueSize,
 | 
				
			||||||
 | 
					                                                    enableHeartbeat,
 | 
				
			||||||
 | 
					                                                    runtime);
 | 
				
			||||||
        ret = (int) sentCount;
 | 
					        ret = (int) sentCount;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (app.got_subcommand("cobra_publish"))
 | 
					    else if (app.got_subcommand("cobra_publish"))
 | 
				
			||||||
@@ -552,6 +559,7 @@ int main(int argc, char** argv)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            bool enableHeartbeat = true;
 | 
				
			||||||
            ix::StatsdClient statsdClient(hostname, statsdPort, prefix);
 | 
					            ix::StatsdClient statsdClient(hostname, statsdPort, prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string errMsg;
 | 
					            std::string errMsg;
 | 
				
			||||||
@@ -563,17 +571,36 @@ int main(int argc, char** argv)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ret = (int) ix::cobra_to_statsd_bot(
 | 
					                ret = (int) ix::cobra_to_statsd_bot(cobraConfig,
 | 
				
			||||||
                    cobraBotConfig, statsdClient, fields, gauge, timer, verbose);
 | 
					                                                    channel,
 | 
				
			||||||
 | 
					                                                    filter,
 | 
				
			||||||
 | 
					                                                    position,
 | 
				
			||||||
 | 
					                                                    statsdClient,
 | 
				
			||||||
 | 
					                                                    fields,
 | 
				
			||||||
 | 
					                                                    gauge,
 | 
				
			||||||
 | 
					                                                    timer,
 | 
				
			||||||
 | 
					                                                    verbose,
 | 
				
			||||||
 | 
					                                                    maxQueueSize,
 | 
				
			||||||
 | 
					                                                    enableHeartbeat,
 | 
				
			||||||
 | 
					                                                    runtime);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (app.got_subcommand("cobra_to_sentry"))
 | 
					    else if (app.got_subcommand("cobra_to_sentry"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        bool enableHeartbeat = true;
 | 
				
			||||||
        ix::SentryClient sentryClient(dsn);
 | 
					        ix::SentryClient sentryClient(dsn);
 | 
				
			||||||
        sentryClient.setTLSOptions(tlsOptions);
 | 
					        sentryClient.setTLSOptions(tlsOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ret = (int) ix::cobra_to_sentry_bot(cobraBotConfig, sentryClient, verbose);
 | 
					        ret = (int) ix::cobra_to_sentry_bot(cobraConfig,
 | 
				
			||||||
 | 
					                                            channel,
 | 
				
			||||||
 | 
					                                            filter,
 | 
				
			||||||
 | 
					                                            position,
 | 
				
			||||||
 | 
					                                            sentryClient,
 | 
				
			||||||
 | 
					                                            verbose,
 | 
				
			||||||
 | 
					                                            maxQueueSize,
 | 
				
			||||||
 | 
					                                            enableHeartbeat,
 | 
				
			||||||
 | 
					                                            runtime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (app.got_subcommand("cobra_metrics_to_redis"))
 | 
					    else if (app.got_subcommand("cobra_metrics_to_redis"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user