Compare commits

..

23 Commits

Author SHA1 Message Date
223cd41b3c (ixwebsocket) Handle EINTR return code in ix::poll and IXSelectInterrupt 2020-11-16 13:53:09 -08:00
60aeaec734 hand EINTR in IXSelectInterruptPipe::notify and IXSelectInterruptPipe::read 2020-11-16 13:52:13 -08:00
fcf114e2b2 Handle EINTR in ix::poll on Unix 2020-11-16 10:14:59 -08:00
ea32c0e1ec fix ixsentry detection of std::regex 2020-11-16 09:19:08 -08:00
866670a906 (ixwebsocket) Fix #252 / regression in 11.0.2 with string comparisons 2020-11-16 08:41:08 -08:00
80432edbd0 add 2 new ubuntu docker files 2020-11-15 21:26:59 -08:00
23606b45c7 C++11 compatible 2020-11-15 21:09:58 -08:00
2aac0afca3 compile attempt 2 with old OpenSSL versions 2020-11-15 11:32:50 -08:00
508d8c7253 compile attempt with old OpenSSL versions 2020-11-15 11:23:44 -08:00
8f5134528b (ixwebsocket) use a C++11 compatible make_unique shim 2020-11-15 09:56:54 -08:00
738c6040f7 fix memory leak in dns unittest 2020-11-12 13:07:31 -08:00
1350e9b307 missing vector header 2020-11-11 21:47:07 -08:00
4e2a40e031 (socket) replace a std::vector with an std::array used as a tmp buffer in Socket::readBytes 2020-11-11 21:39:31 -08:00
594d2e194a linux asan / run test in verbose mode 2020-11-11 11:32:47 -08:00
977a1ed7e1 link ordering fix for Linux 2020-11-11 19:23:51 +00:00
8b3789af56 linux build fix attempt 2020-11-11 11:16:19 -08:00
f60485d9c2 use ctest for testing 2020-11-11 11:11:34 -08:00
b05b124cb3 update readme 2020-11-11 09:20:42 -08:00
723c208f22 fix version 2020-11-11 09:18:03 -08:00
21758f1183 (openssl security fix) in the client to server connection, peer verification is not done in all cases. See https://github.com/machinezone/IXWebSocket/pull/250 2020-11-11 09:16:14 -08:00
422febf15d (openssl) Always set verify peer when it is not disabled (#250) 2020-11-11 09:12:39 -08:00
51ec32405d (docker) build docker container with zlib disabled 2020-11-07 11:22:52 -08:00
6a90dc7259 (cmake) DEFLATE -> Deflate in CMake to stop warnings about casing 2020-11-07 09:40:54 -08:00
46 changed files with 534 additions and 258 deletions

View File

@ -9,5 +9,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: make test_make
run: make test_make
- uses: seanmiddleditch/gha-setup-ninja@master
- name: make test
run: make test

View File

@ -0,0 +1,14 @@
name: linux_asan
on:
push:
paths-ignore:
- 'docs/**'
jobs:
linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: seanmiddleditch/gha-setup-ninja@master
- name: make test_asan
run: make test_asan

View File

@ -9,6 +9,7 @@ jobs:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- uses: seanmiddleditch/gha-setup-ninja@master
- name: install mbedtls
run: brew install mbedtls
- name: make test

View File

@ -9,6 +9,7 @@ jobs:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- uses: seanmiddleditch/gha-setup-ninja@master
- name: install openssl
run: brew install openssl@1.1
- name: make test

View File

@ -9,5 +9,6 @@ jobs:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- name: make test_tsan
run: make test_tsan
- uses: seanmiddleditch/gha-setup-ninja@master
- name: make test_tsan_sectransport
run: make test_tsan_sectransport

View File

@ -5,7 +5,7 @@ include(FindPackageHandleStandardArgs)
find_path(DEFLATE_INCLUDE_DIRS libdeflate.h)
find_library(DEFLATE_LIBRARY deflate)
find_package_handle_standard_args(DEFLATE
find_package_handle_standard_args(Deflate
FOUND_VAR
DEFLATE_FOUND
REQUIRED_VARS

View File

@ -8,7 +8,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
project(ixwebsocket C CXX)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 11)
set (CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF)
@ -45,6 +45,7 @@ set( IXWEBSOCKET_SOURCES
ixwebsocket/IXSocketFactory.cpp
ixwebsocket/IXSocketServer.cpp
ixwebsocket/IXSocketTLSOptions.cpp
ixwebsocket/IXStrCaseCompare.cpp
ixwebsocket/IXUdpSocket.cpp
ixwebsocket/IXUrlParser.cpp
ixwebsocket/IXUserAgent.cpp
@ -82,6 +83,7 @@ set( IXWEBSOCKET_HEADERS
ixwebsocket/IXSocketFactory.h
ixwebsocket/IXSocketServer.h
ixwebsocket/IXSocketTLSOptions.h
ixwebsocket/IXStrCaseCompare.h
ixwebsocket/IXUdpSocket.h
ixwebsocket/IXUrlParser.h
ixwebsocket/IXUtf8Validator.h
@ -203,7 +205,7 @@ if (USE_ZLIB)
endif()
# brew install libdeflate
find_package(DEFLATE)
find_package(Deflate)
if (DEFLATE_FOUND)
include_directories(${DEFLATE_INCLUDE_DIRS})
target_link_libraries(ixwebsocket ${DEFLATE_LIBRARIES})
@ -270,9 +272,10 @@ if (USE_WS OR USE_TEST)
FetchContent_MakeAvailable(spdlog)
if (USE_WS)
add_subdirectory(ws)
add_subdirectory(ws)
endif()
if (USE_TEST)
add_subdirectory(test)
enable_testing()
add_subdirectory(test)
endif()
endif()

View File

@ -4,6 +4,8 @@ IXWebSocket is a C++ library for WebSocket client and server development. It has
It is been used on big mobile video game titles sending and receiving tons of messages since 2017 (iOS and Android). It was tested on macOS, iOS, Linux, Android, Windows and FreeBSD. Note that the MinGW compiler is not supported at this point. Two important design goals are simplicity and correctness.
A bad security bug affecting users compiling with SSL enabled and OpenSSL as the backend was just fixed in newly released version 11.0.0. Please upgrade ! (more details in the [https://github.com/machinezone/IXWebSocket/pull/250](PR).
```cpp
/*
* main.cpp
@ -90,18 +92,20 @@ If your company or project is using this library, feel free to open an issue or
| OS | TLS | Sanitizer | Status |
|-------------------|-------------------|-------------------|-------------------|
| Linux | OpenSSL | None | [![Build2][1]][7] |
| macOS | Secure Transport | Thread Sanitizer | [![Build2][2]][7] |
| macOS | OpenSSL | Thread Sanitizer | [![Build2][3]][7] |
| macOS | MbedTLS | Thread Sanitizer | [![Build2][4]][7] |
| Windows | Disabled | None | [![Build2][5]][7] |
| UWP | Disabled | None | [![Build2][6]][7] |
| Linux | OpenSSL | None | [![Build2][1]][0] |
| macOS | Secure Transport | Thread Sanitizer | [![Build2][2]][0] |
| macOS | OpenSSL | Thread Sanitizer | [![Build2][3]][0] |
| macOS | MbedTLS | Thread Sanitizer | [![Build2][4]][0] |
| Windows | Disabled | None | [![Build2][5]][0] |
| UWP | Disabled | None | [![Build2][6]][0] |
| Linux | OpenSSL | Address Sanitizer | [![Build2][7]][0] |
[0]: https://github.com/machinezone/IXWebSocket
[1]: https://github.com/machinezone/IXWebSocket/workflows/linux/badge.svg
[2]: https://github.com/machinezone/IXWebSocket/workflows/mac_tsan_sectransport/badge.svg
[3]: https://github.com/machinezone/IXWebSocket/workflows/mac_tsan_openssl/badge.svg
[4]: https://github.com/machinezone/IXWebSocket/workflows/mac_tsan_mbedtls/badge.svg
[5]: https://github.com/machinezone/IXWebSocket/workflows/windows/badge.svg
[6]: https://github.com/machinezone/IXWebSocket/workflows/uwp/badge.svg
[7]: https://github.com/machinezone/IXWebSocket
[7]: https://github.com/machinezone/IXWebSocket/workflows/linux_asan/badge.svg

26
docker/Dockerfile.centos7 Normal file
View File

@ -0,0 +1,26 @@
FROM centos:7 as build
RUN yum install -y gcc-c++ make zlib-devel openssl-devel redhat-rpm-config
RUN groupadd app && useradd -g app app
RUN chown -R app:app /opt
RUN chown -R app:app /usr/local
WORKDIR /tmp
RUN curl -O https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.tar.gz
RUN tar zxvf cmake-3.14.0-Linux-x86_64.tar.gz
RUN cp -rf cmake-3.14.0-Linux-x86_64/* /usr/
RUN yum install -y git
# There is a bug in CMake where we cannot build from the root top folder
# So we build from /opt
COPY --chown=app:app . /opt
WORKDIR /opt
USER app
RUN [ "make", "ws_no_python" ]
RUN [ "rm", "-rf", "build" ]
ENTRYPOINT ["ws"]
CMD ["--help"]

View File

@ -0,0 +1,27 @@
# Build time
FROM ubuntu:precise as build
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get -y install wget
RUN mkdir -p /tmp/cmake
WORKDIR /tmp/cmake
RUN wget --no-check-certificate https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz
RUN tar zxf cmake-3.14.0-Linux-x86_64.tar.gz
RUN apt-get -y install g++
RUN apt-get -y install libssl-dev
RUN apt-get -y install libz-dev
RUN apt-get -y install make
RUN apt-get -y install python
RUN apt-get -y install git
COPY . .
ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-Linux-x86_64/bin
ENV PATH="${CMAKE_BIN_PATH}:${PATH}"
RUN ["make", "ws_no_python"]
ENTRYPOINT ["ws"]
CMD ["--help"]

View File

@ -0,0 +1,22 @@
# Build time
FROM ubuntu:trusty as build
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get -y install wget
RUN mkdir -p /tmp/cmake
WORKDIR /tmp/cmake
RUN wget --no-check-certificate https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz
RUN tar zxf cmake-3.14.0-Linux-x86_64.tar.gz
RUN apt-get -y install g++ libssl-dev libz-dev make python git
COPY . .
ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-Linux-x86_64/bin
ENV PATH="${CMAKE_BIN_PATH}:${PATH}"
RUN ["make", "ws_no_python"]
ENTRYPOINT ["ws"]
CMD ["--help"]

View File

@ -2,6 +2,34 @@
All changes to this project will be documented in this file.
## [11.0.4] - 2020-11-16
(ixwebsocket) Handle EINTR return code in ix::poll and IXSelectInterrupt
## [11.0.3] - 2020-11-16
(ixwebsocket) Fix #252 / regression in 11.0.2 with string comparisons
## [11.0.2] - 2020-11-15
(ixwebsocket) use a C++11 compatible make_unique shim
## [11.0.1] - 2020-11-11
(socket) replace a std::vector with an std::array used as a tmp buffer in Socket::readBytes
## [11.0.0] - 2020-11-11
(openssl security fix) in the client to server connection, peer verification is not done in all cases. See https://github.com/machinezone/IXWebSocket/pull/250
## [10.5.7] - 2020-11-07
(docker) build docker container with zlib disabled
## [10.5.6] - 2020-11-07
(cmake) DEFLATE -> Deflate in CMake to stop warnings about casing
## [10.5.5] - 2020-11-07
(ws autoroute) Display result in compliant way (AUTOROUTE IXWebSocket :: N ms) so that result can be parsed easily

View File

@ -14,6 +14,7 @@
#include <ixcrypto/IXHMac.h>
#include <ixwebsocket/IXSocketTLSOptions.h>
#include <ixwebsocket/IXWebSocket.h>
#include <ixwebsocket/IXUniquePtr.h>
#include <sstream>
#include <stdexcept>
@ -98,7 +99,7 @@ namespace ix
if (_eventCallback)
{
_eventCallback(
std::make_unique<CobraEvent>(eventType, errorMsg, headers, subscriptionId, msgId, connectionId));
ix::make_unique<CobraEvent>(eventType, errorMsg, headers, subscriptionId, msgId, connectionId));
}
}

View File

@ -10,6 +10,7 @@
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <ixwebsocket/IXSocket.h>
namespace ix

View File

@ -16,6 +16,7 @@
#include <string>
#include <thread>
#include <utility> // pair
#include <vector> // pair
namespace ix
{

View File

@ -16,6 +16,20 @@ add_library(ixsentry STATIC
${IXSENTRY_HEADERS}
)
#
# Using try_compile or other techniques to detect std::regex
# availability is hard, so resorting to an ugly compiler and compiler
# version check.
#
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0")
else()
target_compile_definitions( ixsentry PUBLIC HAVE_STD_REGEX=1 )
endif()
else()
target_compile_definitions( ixsentry PUBLIC HAVE_STD_REGEX=1 )
endif()
find_package(JsonCpp)
if (NOT JSONCPP_FOUND)
set(JSONCPP_INCLUDE_DIRS ../third_party/jsoncpp)

View File

@ -20,9 +20,12 @@ namespace ix
SentryClient::SentryClient(const std::string& dsn)
: _dsn(dsn)
, _validDsn(false)
#ifdef HAVE_STD_REGEX
, _luaFrameRegex("\t([^/]+):([0-9]+): in function ['<]([^/]+)['>]")
#endif
, _httpClient(std::make_shared<HttpClient>(true))
{
#ifdef HAVE_STD_REGEX
const std::regex dsnRegex("(http[s]?)://([^:]+):([^@]+)@([^/]+)/([0-9]+)");
std::smatch group;
@ -38,6 +41,7 @@ namespace ix
_publicKey = group.str(2);
_secretKey = group.str(3);
}
#endif
}
void SentryClient::setTLSOptions(const SocketTLSOptions& tlsOptions)
@ -77,6 +81,7 @@ namespace ix
{
Json::Value frames;
#ifdef HAVE_STD_REGEX
// Split by lines
std::string line;
std::stringstream tokenStream(stack);
@ -107,6 +112,7 @@ namespace ix
}
std::reverse(frames.begin(), frames.end());
#endif
return frames;
}

View File

@ -11,7 +11,9 @@
#include <ixwebsocket/IXSocketTLSOptions.h>
#include <json/json.h>
#include <memory>
#ifdef HAVE_STD_REGEX
#include <regex>
#endif
namespace ix
{
@ -62,7 +64,9 @@ namespace ix
Json::FastWriter _jsonWriter;
#ifdef HAVE_STD_REGEX
std::regex _luaFrameRegex;
#endif
std::shared_ptr<HttpClient> _httpClient;
};

View File

@ -13,6 +13,7 @@
#include <ixcore/utils/IXCoreLogger.h>
#include <ixcrypto/IXHMac.h>
#include <ixwebsocket/IXWebSocket.h>
#include <ixwebsocket/IXUniquePtr.h>
#include <sstream>
namespace snake
@ -196,7 +197,7 @@ namespace snake
{
std::string filterStr = pdu["body"]["filter"];
}
state->streamSql = std::make_unique<StreamSql>(filterStr);
state->streamSql = ix::make_unique<StreamSql>(filterStr);
state->id = 0;
state->onRedisSubscribeCallback = [&ws, state](const std::string& messageStr) {
auto msg = nlohmann::json::parse(messageStr);

View File

@ -68,6 +68,11 @@ namespace ix
: resolveUnCancellable(errMsg, isCancellationRequested);
}
void DNSLookup::release(struct addrinfo* addr)
{
freeaddrinfo(addr);
}
struct addrinfo* DNSLookup::resolveUnCancellable(
std::string& errMsg, const CancellationRequest& isCancellationRequested)
{

View File

@ -31,6 +31,8 @@ namespace ix
const CancellationRequest& isCancellationRequested,
bool cancellable = true);
void release(struct addrinfo* addr);
private:
struct addrinfo* resolveCancellable(std::string& errMsg,
const CancellationRequest& isCancellationRequested);

View File

@ -20,9 +20,11 @@
namespace ix
{
#ifdef IXWEBSOCKET_USE_ZLIB
std::string gzipCompress(const std::string& str)
{
#ifndef IXWEBSOCKET_USE_ZLIB
return std::string();
#else
#ifdef IXWEBSOCKET_USE_DEFLATE
int compressionLevel = 6;
struct libdeflate_compressor* compressor;
@ -99,7 +101,8 @@ namespace ix
deflateEnd(&zs);
return outstring;
#endif
#endif // IXWEBSOCKET_USE_DEFLATE
#endif // IXWEBSOCKET_USE_ZLIB
}
#ifdef IXWEBSOCKET_USE_DEFLATE
@ -112,6 +115,9 @@ namespace ix
bool gzipDecompress(const std::string& in, std::string& out)
{
#ifndef IXWEBSOCKET_USE_ZLIB
return false;
#else
#ifdef IXWEBSOCKET_USE_DEFLATE
struct libdeflate_decompressor* decompressor;
decompressor = libdeflate_alloc_decompressor();
@ -171,7 +177,7 @@ namespace ix
inflateEnd(&inflateState);
return true;
#endif
#endif // IXWEBSOCKET_USE_DEFLATE
#endif // IXWEBSOCKET_USE_ZLIB
}
#endif
} // namespace ix

View File

@ -105,7 +105,22 @@ namespace ix
return ret;
#else
return ::poll(fds, nfds, timeout);
//
// It was reported that on Android poll can fail and return -1 with
// errno == EINTR, which should be a temp error and should typically
// be handled by retrying in a loop.
// Maybe we need to put all syscall / C functions in
// a new IXSysCalls.cpp and wrap them all.
//
// The style from libuv is as such.
//
int ret = -1;
do
{
ret = ::poll(fds, nfds, timeout);
} while (ret == -1 && errno == EINTR);
return ret;
#endif
}

View File

@ -6,6 +6,7 @@
#include "IXSelectInterruptFactory.h"
#include "IXUniquePtr.h"
#if defined(__linux__) || defined(__APPLE__)
#include "IXSelectInterruptPipe.h"
#else
@ -17,9 +18,9 @@ namespace ix
SelectInterruptPtr createSelectInterrupt()
{
#if defined(__linux__) || defined(__APPLE__)
return std::make_unique<SelectInterruptPipe>();
return ix::make_unique<SelectInterruptPipe>();
#else
return std::make_unique<SelectInterrupt>();
return ix::make_unique<SelectInterrupt>();
#endif
}
} // namespace ix

View File

@ -117,8 +117,14 @@ namespace ix
int fd = _fildes[kPipeWriteIndex];
if (fd == -1) return false;
ssize_t ret = -1;
do
{
ret = ::write(fd, &value, sizeof(value));
} while (ret == -1 && errno == EINTR);
// we should write 8 bytes for an uint64_t
return write(fd, &value, sizeof(value)) == 8;
return ret == 8;
}
// TODO: return max uint64_t for errors ?
@ -129,7 +135,12 @@ namespace ix
int fd = _fildes[kPipeReadIndex];
uint64_t value = 0;
::read(fd, &value, sizeof(value));
ssize_t ret = -1;
do
{
ret = ::read(fd, &value, sizeof(value));
} while (ret == -1 && errno == EINTR);
return value;
}

View File

@ -11,6 +11,7 @@
#include "IXSelectInterruptFactory.h"
#include "IXSocketConnect.h"
#include <algorithm>
#include <array>
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
@ -18,6 +19,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <vector>
#ifdef min
#undef min
@ -27,7 +29,6 @@ namespace ix
{
const int Socket::kDefaultPollNoTimeout = -1; // No poll timeout by default
const int Socket::kDefaultPollTimeout = kDefaultPollNoTimeout;
constexpr size_t Socket::kChunkSize;
Socket::Socket(int fd)
: _sockfd(fd)
@ -364,10 +365,7 @@ namespace ix
const OnProgressCallback& onProgressCallback,
const CancellationRequest& isCancellationRequested)
{
if (_readBuffer.empty())
{
_readBuffer.resize(kChunkSize);
}
std::array<uint8_t, 1 << 14> readBuffer;
std::vector<uint8_t> output;
while (output.size() != length)
@ -378,12 +376,12 @@ namespace ix
return std::make_pair(false, errorMsg);
}
size_t size = std::min(kChunkSize, length - output.size());
ssize_t ret = recv((char*) &_readBuffer[0], size);
size_t size = std::min(readBuffer.size(), length - output.size());
ssize_t ret = recv((char*) &readBuffer[0], size);
if (ret > 0)
{
output.insert(output.end(), _readBuffer.begin(), _readBuffer.begin() + ret);
output.insert(output.end(), readBuffer.begin(), readBuffer.begin() + ret);
}
else if (ret <= 0 && !Socket::isWaitNeeded())
{

View File

@ -11,7 +11,6 @@
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#ifdef _WIN32
#include <BaseTsd.h>
@ -102,10 +101,6 @@ namespace ix
static const int kDefaultPollTimeout;
static const int kDefaultPollNoTimeout;
// Buffer for reading from our socket. That buffer is never resized.
std::vector<uint8_t> _readBuffer;
static constexpr size_t kChunkSize = 1 << 15;
SelectInterruptPtr _selectInterrupt;
};
} // namespace ix

View File

@ -10,6 +10,7 @@
#include "IXNetSystem.h"
#include "IXSelectInterrupt.h"
#include "IXSocket.h"
#include "IXUniquePtr.h"
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
@ -65,7 +66,7 @@ namespace ix
int timeoutMs = 10;
bool readyToRead = false;
auto selectInterrupt = std::make_unique<SelectInterrupt>();
auto selectInterrupt = ix::make_unique<SelectInterrupt>();
PollResultType pollResult = Socket::poll(readyToRead, timeoutMs, fd, selectInterrupt);
if (pollResult == PollResultType::Timeout)

View File

@ -6,6 +6,7 @@
#include "IXSocketFactory.h"
#include "IXUniquePtr.h"
#ifdef IXWEBSOCKET_USE_TLS
#ifdef IXWEBSOCKET_USE_MBED_TLS
@ -35,17 +36,17 @@ namespace ix
if (!tls)
{
socket = std::make_unique<Socket>(fd);
socket = ix::make_unique<Socket>(fd);
}
else
{
#ifdef IXWEBSOCKET_USE_TLS
#if defined(IXWEBSOCKET_USE_MBED_TLS)
socket = std::make_unique<SocketMbedTLS>(tlsOptions, fd);
socket = ix::make_unique<SocketMbedTLS>(tlsOptions, fd);
#elif defined(IXWEBSOCKET_USE_OPEN_SSL)
socket = std::make_unique<SocketOpenSSL>(tlsOptions, fd);
socket = ix::make_unique<SocketOpenSSL>(tlsOptions, fd);
#elif defined(__APPLE__)
socket = std::make_unique<SocketAppleSSL>(tlsOptions, fd);
socket = ix::make_unique<SocketAppleSSL>(tlsOptions, fd);
#endif
#else
errorMsg = "TLS support is not enabled on this platform.";

View File

@ -10,8 +10,10 @@
#include "IXSocketOpenSSL.h"
#include "IXSocketConnect.h"
#include "IXUniquePtr.h"
#include <cassert>
#include <errno.h>
#include <vector>
#ifdef _WIN32
#include <Shlwapi.h>
#else
@ -85,8 +87,7 @@ namespace ix
std::atomic<bool> SocketOpenSSL::_openSSLInitializationSuccessful(false);
std::once_flag SocketOpenSSL::_openSSLInitFlag;
std::unique_ptr<std::mutex[]> SocketOpenSSL::_openSSLMutexes =
std::make_unique<std::mutex[]>(CRYPTO_num_locks());
std::vector<std::unique_ptr<std::mutex>> openSSLMutexes;
SocketOpenSSL::SocketOpenSSL(const SocketTLSOptions& tlsOptions, int fd)
: Socket(fd)
@ -111,6 +112,11 @@ namespace ix
if (CRYPTO_get_locking_callback() == nullptr)
{
openSSLMutexes.clear();
for (int i = 0; i < CRYPTO_num_locks(); ++i)
{
openSSLMutexes.push_back(ix::make_unique<std::mutex>());
}
CRYPTO_set_locking_callback(SocketOpenSSL::openSSLLockingCallback);
}
#endif
@ -128,11 +134,11 @@ namespace ix
{
if (mode & CRYPTO_LOCK)
{
_openSSLMutexes[type].lock();
openSSLMutexes[type]->lock();
}
else
{
_openSSLMutexes[type].unlock();
openSSLMutexes[type]->unlock();
}
}
@ -503,14 +509,13 @@ namespace ix
errMsg += ERR_error_string(sslErr, nullptr);
return false;
}
SSL_CTX_set_verify(
_ssl_context, SSL_VERIFY_PEER, [](int preverify, X509_STORE_CTX*) -> int {
return preverify;
});
SSL_CTX_set_verify_depth(_ssl_context, 4);
}
}
SSL_CTX_set_verify(_ssl_context,
SSL_VERIFY_PEER,
[](int preverify, X509_STORE_CTX*) -> int { return preverify; });
SSL_CTX_set_verify_depth(_ssl_context, 4);
}
else
{

View File

@ -61,7 +61,6 @@ namespace ix
static std::once_flag _openSSLInitFlag;
static std::atomic<bool> _openSSLInitializationSuccessful;
static std::unique_ptr<std::mutex[]> _openSSLMutexes;
};
} // namespace ix

View File

@ -0,0 +1,37 @@
/*
* IXStrCaseCompare.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone. All rights reserved.
*/
#include "IXStrCaseCompare.h"
#include <algorithm>
#include <locale>
namespace ix
{
bool CaseInsensitiveLess::NocaseCompare::operator()(const unsigned char& c1,
const unsigned char& c2) const
{
#ifdef _WIN32
return std::tolower(c1, std::locale()) < std::tolower(c2, std::locale());
#else
return std::tolower(c1) < std::tolower(c2);
#endif
}
bool CaseInsensitiveLess::cmp(const std::string& s1, const std::string& s2)
{
return std::lexicographical_compare(s1.begin(),
s1.end(), // source range
s2.begin(),
s2.end(), // dest range
NocaseCompare()); // comparison
}
bool CaseInsensitiveLess::operator()(const std::string& s1, const std::string& s2) const
{
return CaseInsensitiveLess::cmp(s1, s2);
}
} // namespace ix

View File

@ -0,0 +1,25 @@
/*
* IXStrCaseCompare.h
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone. All rights reserved.
*/
#pragma once
#include <string>
namespace ix
{
struct CaseInsensitiveLess
{
// Case Insensitive compare_less binary function
struct NocaseCompare
{
bool operator()(const unsigned char& c1, const unsigned char& c2) const;
};
static bool cmp(const std::string& s1, const std::string& s2);
bool operator()(const std::string& s1, const std::string& s2) const;
};
} // namespace ix

18
ixwebsocket/IXUniquePtr.h Normal file
View File

@ -0,0 +1,18 @@
/*
* IXUniquePtr.h
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
*/
#pragma once
#include <memory>
namespace ix
{
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
} // namespace ix

View File

@ -8,6 +8,7 @@
#include "IXExponentialBackoff.h"
#include "IXSetThreadName.h"
#include "IXUniquePtr.h"
#include "IXUtf8Validator.h"
#include "IXWebSocketHandshake.h"
#include <cassert>
@ -34,12 +35,12 @@ namespace ix
_ws.setOnCloseCallback(
[this](uint16_t code, const std::string& reason, size_t wireSize, bool remote) {
_onMessageCallback(
std::make_unique<WebSocketMessage>(WebSocketMessageType::Close,
"",
wireSize,
WebSocketErrorInfo(),
WebSocketOpenInfo(),
WebSocketCloseInfo(code, reason, remote)));
ix::make_unique<WebSocketMessage>(WebSocketMessageType::Close,
"",
wireSize,
WebSocketErrorInfo(),
WebSocketOpenInfo(),
WebSocketCloseInfo(code, reason, remote)));
});
}
@ -195,7 +196,7 @@ namespace ix
return status;
}
_onMessageCallback(std::make_unique<WebSocketMessage>(
_onMessageCallback(ix::make_unique<WebSocketMessage>(
WebSocketMessageType::Open,
"",
0,
@ -227,12 +228,12 @@ namespace ix
}
_onMessageCallback(
std::make_unique<WebSocketMessage>(WebSocketMessageType::Open,
"",
0,
WebSocketErrorInfo(),
WebSocketOpenInfo(status.uri, status.headers),
WebSocketCloseInfo()));
ix::make_unique<WebSocketMessage>(WebSocketMessageType::Open,
"",
0,
WebSocketErrorInfo(),
WebSocketOpenInfo(status.uri, status.headers),
WebSocketCloseInfo()));
if (_pingIntervalSecs > 0)
{
@ -312,12 +313,12 @@ namespace ix
connectErr.reason = status.errorStr;
connectErr.http_status = status.http_status;
_onMessageCallback(std::make_unique<WebSocketMessage>(WebSocketMessageType::Error,
"",
0,
connectErr,
WebSocketOpenInfo(),
WebSocketCloseInfo()));
_onMessageCallback(ix::make_unique<WebSocketMessage>(WebSocketMessageType::Error,
"",
0,
connectErr,
WebSocketOpenInfo(),
WebSocketCloseInfo()));
}
}
}
@ -388,13 +389,13 @@ namespace ix
bool binary = messageKind == WebSocketTransport::MessageKind::MSG_BINARY;
_onMessageCallback(std::make_unique<WebSocketMessage>(webSocketMessageType,
msg,
wireSize,
webSocketErrorInfo,
WebSocketOpenInfo(),
WebSocketCloseInfo(),
binary));
_onMessageCallback(ix::make_unique<WebSocketMessage>(webSocketMessageType,
msg,
wireSize,
webSocketErrorInfo,
WebSocketOpenInfo(),
WebSocketCloseInfo(),
binary));
WebSocket::invokeTrafficTrackerCallback(wireSize, true);
});

View File

@ -8,6 +8,7 @@
#include "IXHttp.h"
#include "IXSocketConnect.h"
#include "IXStrCaseCompare.h"
#include "IXUrlParser.h"
#include "IXUserAgent.h"
#include "IXWebSocketHandshakeKeyGen.h"
@ -35,9 +36,7 @@ namespace ix
bool WebSocketHandshake::insensitiveStringCompare(const std::string& a, const std::string& b)
{
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) {
return tolower(a) == tolower(b);
});
return CaseInsensitiveLess::cmp(a, b) == 0;
}
std::string WebSocketHandshake::genRandomString(const int len)

View File

@ -12,25 +12,6 @@
namespace ix
{
bool CaseInsensitiveLess::NocaseCompare::operator()(const unsigned char& c1,
const unsigned char& c2) const
{
#ifdef _WIN32
return std::tolower(c1, std::locale()) < std::tolower(c2, std::locale());
#else
return std::tolower(c1) < std::tolower(c2);
#endif
}
bool CaseInsensitiveLess::operator()(const std::string& s1, const std::string& s2) const
{
return std::lexicographical_compare(s1.begin(),
s1.end(), // source range
s2.begin(),
s2.end(), // dest range
NocaseCompare()); // comparison
}
std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(
std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested)
{

View File

@ -7,6 +7,7 @@
#pragma once
#include "IXCancellationRequest.h"
#include "IXStrCaseCompare.h"
#include <map>
#include <memory>
#include <string>
@ -15,17 +16,6 @@ namespace ix
{
class Socket;
struct CaseInsensitiveLess
{
// Case Insensitive compare_less binary function
struct NocaseCompare
{
bool operator()(const unsigned char& c1, const unsigned char& c2) const;
};
bool operator()(const std::string& s1, const std::string& s2) const;
};
using WebSocketHttpHeaders = std::map<std::string, std::string, CaseInsensitiveLess>;
std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(

View File

@ -48,14 +48,15 @@
#include "IXWebSocketPerMessageDeflate.h"
#include "IXUniquePtr.h"
#include "IXWebSocketPerMessageDeflateCodec.h"
#include "IXWebSocketPerMessageDeflateOptions.h"
namespace ix
{
WebSocketPerMessageDeflate::WebSocketPerMessageDeflate()
: _compressor(std::make_unique<WebSocketPerMessageDeflateCompressor>())
, _decompressor(std::make_unique<WebSocketPerMessageDeflateDecompressor>())
: _compressor(ix::make_unique<WebSocketPerMessageDeflateCompressor>())
, _decompressor(ix::make_unique<WebSocketPerMessageDeflateDecompressor>())
{
;
}

View File

@ -36,6 +36,7 @@
#include "IXSocketFactory.h"
#include "IXSocketTLSOptions.h"
#include "IXUniquePtr.h"
#include "IXUrlParser.h"
#include "IXUtf8Validator.h"
#include "IXWebSocketHandshake.h"
@ -124,7 +125,7 @@ namespace ix
std::string errorMsg;
bool tls = protocol == "wss";
_socket = createSocket(tls, -1, errorMsg, _socketTLSOptions);
_perMessageDeflate = std::make_unique<WebSocketPerMessageDeflate>();
_perMessageDeflate = ix::make_unique<WebSocketPerMessageDeflate>();
if (!_socket)
{
@ -177,7 +178,7 @@ namespace ix
_blockingSend = true;
_socket = std::move(socket);
_perMessageDeflate = std::make_unique<WebSocketPerMessageDeflate>();
_perMessageDeflate = ix::make_unique<WebSocketPerMessageDeflate>();
WebSocketHandshake webSocketHandshake(_requestInitCancellation,
_socket,

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "10.5.5"
#define IX_WEBSOCKET_VERSION "11.0.4"

View File

@ -28,7 +28,7 @@ brew:
# server side ?) and I can't work-around it easily, so we're using mbedtls on
# Linux for the SSL backend, which works great.
ws_mbedtls_install:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_ZLIB=OFF -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
ws:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
@ -52,7 +52,7 @@ ws_no_ssl:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_WS=1 .. ; make -j 4)
ws_no_python:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; ninja install)
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j4 install)
uninstall:
xargs rm -fv < build/install_manifest.txt
@ -110,71 +110,30 @@ format:
test_server:
(cd test && npm i ws && node broadcast-server.js)
# env TEST=Websocket_server make test
# env TEST=Websocket_chat make test
# env TEST=heartbeat make test
build_test:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_TEST=1 .. ; ninja install)
test:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 ..)
(cd build ; ninja)
(cd build ; ninja test)
test: build_test
(cd test ; python2.7 run.py -r)
test_make:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; make -j 4)
(cd test ; python2.7 run.py -r)
test_tsan:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableThreadSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
test_ubsan:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableUndefinedBehaviorSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
test_asan: build_test_asan
(cd test ; python2.7 run.py -r)
build_test_asan:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableAddressSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
test_tsan_openssl:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 -DUSE_OPEN_SSL=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableThreadSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
test_ubsan_openssl:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 -DUSE_OPEN_SSL=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableUndefinedBehaviorSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
test_tsan_openssl_release:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Release -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 -DUSE_OPEN_SSL=1 .. && xcodebuild -project ixwebsocket.xcodeproj -configuration Release -target ixwebsocket_unittest -enableThreadSanitizer YES)
(cd build/test ; ln -sf Release/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
test_asan:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 .. -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer")
(cd build ; ninja)
(cd build ; ctest -V .)
test_tsan_mbedtls:
mkdir -p build && (cd build && cmake -GXcode -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_TEST=1 -DUSE_MBED_TLS=1 .. && xcodebuild -project ixwebsocket.xcodeproj -target ixwebsocket_unittest -enableThreadSanitizer YES)
(cd build/test ; ln -sf Debug/ixwebsocket_unittest)
(cd test ; python2.7 run.py -r)
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_MBED_TLS=1 -DUSE_TEST=1 .. -DCMAKE_C_FLAGS="-fsanitize=thread -fno-omit-frame-pointer" -DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer")
(cd build ; ninja)
(cd build ; ninja test)
build_test_openssl:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_OPEN_SSL=1 -DUSE_TEST=1 .. ; ninja install)
test_tsan_openssl:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_OPENS_SSL=1 -DUSE_TEST=1 .. -DCMAKE_C_FLAGS="-fsanitize=thread -fno-omit-frame-pointer" -DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer")
(cd build ; ninja)
(cd build ; ninja test)
test_openssl: build_test_openssl
(cd test ; python2.7 run.py -r)
build_test_mbedtls:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_MBED_TLS=1 -DUSE_TEST=1 .. ; make -j 4)
test_mbedtls: build_test_mbedtls
(cd test ; python2.7 run.py -r)
test_no_ssl:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TEST=1 .. ; make -j 4)
(cd test ; python2.7 run.py -r)
test_tsan_sectransport:
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_PYTHON=1 -DUSE_TLS=1 -DUSE_OPENS_SSL=1 -DUSE_TEST=1 .. -DCMAKE_C_FLAGS="-fsanitize=thread -fno-omit-frame-pointer" -DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer")
(cd build ; ninja)
(cd build ; ninja test)
ws_test: ws
(cd ws ; env DEBUG=1 PATH=../ws/build:$$PATH bash test_ws.sh)

View File

@ -5,63 +5,41 @@
cmake_minimum_required (VERSION 3.14)
project (ixwebsocket_unittest)
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 11)
option(USE_TLS "Add TLS support" ON)
include_directories(
${PROJECT_SOURCE_DIR}/Catch2/single_include
../third_party
../third_party/msgpack11
../ws
)
add_definitions(-DSPDLOG_COMPILED_LIB=1)
find_package(JsonCpp)
if (NOT JSONCPP_FOUND)
include_directories(../third_party/jsoncpp)
set(JSONCPP_SOURCES ../third_party/jsoncpp/jsoncpp.cpp)
endif()
# Shared sources
set (SOURCES
${JSONCPP_SOURCES}
test_runner.cpp
IXTest.cpp
../third_party/msgpack11/msgpack11.cpp
IXSocketTest.cpp
IXSocketConnectTest.cpp
# IXWebSocketLeakTest.cpp # commented until we have a fix for #224
IXWebSocketServerTest.cpp
IXWebSocketTestConnectionDisconnection.cpp
IXUrlParserTest.cpp
IXWebSocketServerTest.cpp
IXHttpClientTest.cpp
IXHttpServerTest.cpp
IXUnityBuildsTest.cpp
IXHttpTest.cpp
IXDNSLookupTest.cpp
IXWebSocketSubProtocolTest.cpp
IXSentryClientTest.cpp
IXWebSocketChatTest.cpp
IXWebSocketBroadcastTest.cpp
IXWebSocketPerMessageDeflateCompressorTest.cpp
IXStreamSqlTest.cpp
set (TEST_TARGET_NAMES
IXSocketTest
IXSocketConnectTest
IXWebSocketServerTest
IXWebSocketTestConnectionDisconnection
IXUrlParserTest
IXHttpClientTest
IXHttpServerTest
IXUnityBuildsTest
IXHttpTest
IXDNSLookupTest
IXWebSocketSubProtocolTest
IXSentryClientTest
IXWebSocketChatTest
IXWebSocketBroadcastTest
IXWebSocketPerMessageDeflateCompressorTest
IXStreamSqlTest
IXStrCaseCompareTest
)
# Some unittest don't work on windows yet
# Windows without TLS does not have hmac yet
if (UNIX)
list(APPEND SOURCES
IXWebSocketCloseTest.cpp
IXCobraChatTest.cpp
IXCobraMetricsPublisherTest.cpp
IXCobraToSentryBotTest.cpp
IXCobraToStatsdBotTest.cpp
IXCobraToStdoutBotTest.cpp
list(APPEND TEST_TARGET_NAMES
IXWebSocketCloseTest
IXCobraChatTest
IXCobraMetricsPublisherTest
IXCobraToSentryBotTest
IXCobraToStatsdBotTest
IXCobraToStdoutBotTest
)
endif()
@ -69,21 +47,14 @@ endif()
# IXWebSocketPingTest.cpp
# IXWebSocketPingTimeoutTest.cpp
# IXWebSocketLeakTest.cpp # commented until we have a fix for #224 /
# that was was fixed but now the test does not compile
# Disable tests for now that are failing or not reliable
add_executable(ixwebsocket_unittest ${SOURCES})
if (MAC)
add_sanitizers(ixwebsocket_unittest)
endif()
if (APPLE AND USE_TLS)
target_link_libraries(ixwebsocket_unittest "-framework foundation" "-framework security")
endif()
if (JSONCPP_FOUND)
target_include_directories(ixwebsocket_unittest PUBLIC ${JSONCPP_INCLUDE_DIRS})
target_link_libraries(ixwebsocket_unittest ${JSONCPP_LIBRARIES})
find_package(JsonCpp)
if (NOT JSONCPP_FOUND)
set(JSONCPP_SOURCES ../third_party/jsoncpp/jsoncpp.cpp)
endif()
if (USE_PYTHON)
@ -97,19 +68,69 @@ if (USE_PYTHON)
message("Python_LIBRARIES:${Python_LIBRARIES}")
endif()
# library with the most dependencies come first
target_link_libraries(ixwebsocket_unittest ixbots)
target_link_libraries(ixwebsocket_unittest ixsnake)
target_link_libraries(ixwebsocket_unittest ixcobra)
target_link_libraries(ixwebsocket_unittest ixsentry)
target_link_libraries(ixwebsocket_unittest ixredis)
target_link_libraries(ixwebsocket_unittest ixwebsocket)
target_link_libraries(ixwebsocket_unittest ixcrypto)
target_link_libraries(ixwebsocket_unittest ixcore)
add_library(ixwebsocket_test)
target_sources(ixwebsocket_test PRIVATE
${JSONCPP_SOURCES}
test_runner.cpp
IXTest.cpp
../third_party/msgpack11/msgpack11.cpp
)
target_compile_definitions(ixwebsocket_test PRIVATE ${TEST_PROGRAMS_DEFINITIONS})
target_include_directories(ixwebsocket_test PRIVATE
${PROJECT_SOURCE_DIR}/Catch2/single_include
../third_party
)
target_link_libraries(ixwebsocket_test ixsnake)
target_link_libraries(ixwebsocket_test ixcobra)
target_link_libraries(ixwebsocket_test ixwebsocket)
target_link_libraries(ixwebsocket_test ixcrypto)
target_link_libraries(ixwebsocket_test spdlog)
target_link_libraries(ixwebsocket_unittest spdlog)
if (USE_PYTHON)
target_link_libraries(ixwebsocket_unittest ${Python_LIBRARIES})
endif()
foreach(TEST_TARGET_NAME ${TEST_TARGET_NAMES})
add_executable(${TEST_TARGET_NAME}
${TEST_TARGET_NAME}.cpp
)
install(TARGETS ixwebsocket_unittest DESTINATION bin)
target_include_directories(${TEST_TARGET_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/Catch2/single_include
../third_party
../third_party/msgpack11
)
target_compile_definitions(${TEST_TARGET_NAME} PRIVATE SPDLOG_COMPILED_LIB=1)
if (NOT JSONCPP_FOUND)
target_include_directories(${TEST_TARGET_NAME} PRIVATE ../third_party/jsoncpp)
endif()
if (APPLE AND USE_TLS)
target_link_libraries(${TEST_TARGET_NAME} "-framework foundation" "-framework security")
endif()
# library with the most dependencies come first
target_link_libraries(${TEST_TARGET_NAME} ixwebsocket_test)
target_link_libraries(${TEST_TARGET_NAME} ixbots)
target_link_libraries(${TEST_TARGET_NAME} ixsnake)
target_link_libraries(${TEST_TARGET_NAME} ixcobra)
target_link_libraries(${TEST_TARGET_NAME} ixsentry)
if (JSONCPP_FOUND)
target_include_directories(${TEST_TARGET_NAME} PRIVATE ${JSONCPP_INCLUDE_DIRS})
target_link_libraries(${TEST_TARGET_NAME} ${JSONCPP_LIBRARIES})
endif()
target_link_libraries(${TEST_TARGET_NAME} ixredis)
target_link_libraries(${TEST_TARGET_NAME} ixwebsocket)
target_link_libraries(${TEST_TARGET_NAME} ixcrypto)
target_link_libraries(${TEST_TARGET_NAME} ixcore)
target_link_libraries(${TEST_TARGET_NAME} spdlog)
if (USE_PYTHON)
target_link_libraries(${TEST_TARGET_NAME} ${Python_LIBRARIES})
endif()
add_test(NAME ${TEST_TARGET_NAME}
COMMAND ${TEST_TARGET_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endforeach()

View File

@ -24,6 +24,8 @@ TEST_CASE("dns", "[net]")
res = dnsLookup->resolve(errMsg, [] { return false; });
std::cerr << "Error message: " << errMsg << std::endl;
REQUIRE(res != nullptr);
dnsLookup->release(res);
}
SECTION("Test resolving a non-existing hostname")

View File

@ -0,0 +1,46 @@
/*
* IXStrCaseCompareTest.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone. All rights reserved.
*/
#include "IXTest.h"
#include "catch.hpp"
#include <iostream>
#include <ixwebsocket/IXUrlParser.h>
#include <string.h>
using namespace ix;
namespace ix
{
TEST_CASE("str_case_compare", "[str_case_compare]")
{
SECTION("1")
{
using HttpHeaders = std::map<std::string, std::string, CaseInsensitiveLess>;
HttpHeaders httpHeaders;
httpHeaders["foo"] = "foo";
REQUIRE(httpHeaders["foo"] == "foo");
REQUIRE(httpHeaders["missing"] == "");
// Comparison should be case insensitive
REQUIRE(httpHeaders["Foo"] == "foo");
}
SECTION("2")
{
using HttpHeaders = std::map<std::string, std::string, CaseInsensitiveLess>;
HttpHeaders headers;
headers["Upgrade"] = "webSocket";
REQUIRE(CaseInsensitiveLess::cmp(headers["upgrade"], "WebSocket") == 0);
}
}
} // namespace ix

View File

@ -14,7 +14,7 @@ endif()
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
# set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 11)
option(USE_TLS "Add TLS support" ON)