From 23606b45c719e5b8a133976b4a128e1dfe9488b2 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Sun, 15 Nov 2020 21:08:45 -0800 Subject: [PATCH] C++11 compatible --- CMakeLists.txt | 4 ++- docker/Dockerfile.centos7 | 26 ++++++++++++++++++ ixcobra/ixcobra/IXCobraConnection.cpp | 3 ++- ixsentry/CMakeLists.txt | 15 +++++++++++ ixsentry/ixsentry/IXSentryClient.cpp | 6 +++++ ixsentry/ixsentry/IXSentryClient.h | 4 +++ ixsnake/ixsnake/IXSnakeProtocol.cpp | 3 ++- ixwebsocket/IXSocketOpenSSL.cpp | 12 ++++++--- ixwebsocket/IXStrCaseCompare.cpp | 37 ++++++++++++++++++++++++++ ixwebsocket/IXStrCaseCompare.h | 25 +++++++++++++++++ ixwebsocket/IXWebSocketHandshake.cpp | 5 ++-- ixwebsocket/IXWebSocketHttpHeaders.cpp | 19 ------------- ixwebsocket/IXWebSocketHttpHeaders.h | 12 +-------- makefile | 2 +- test/CMakeLists.txt | 2 +- ws/CMakeLists.txt | 2 +- 16 files changed, 135 insertions(+), 42 deletions(-) create mode 100644 docker/Dockerfile.centos7 create mode 100644 ixwebsocket/IXStrCaseCompare.cpp create mode 100644 ixwebsocket/IXStrCaseCompare.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cbfdd1d..0186ba5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/docker/Dockerfile.centos7 b/docker/Dockerfile.centos7 new file mode 100644 index 00000000..adf5c651 --- /dev/null +++ b/docker/Dockerfile.centos7 @@ -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"] diff --git a/ixcobra/ixcobra/IXCobraConnection.cpp b/ixcobra/ixcobra/IXCobraConnection.cpp index a76c88f2..2b1aed6a 100644 --- a/ixcobra/ixcobra/IXCobraConnection.cpp +++ b/ixcobra/ixcobra/IXCobraConnection.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,7 @@ namespace ix if (_eventCallback) { _eventCallback( - std::make_unique(eventType, errorMsg, headers, subscriptionId, msgId, connectionId)); + ix::make_unique(eventType, errorMsg, headers, subscriptionId, msgId, connectionId)); } } diff --git a/ixsentry/CMakeLists.txt b/ixsentry/CMakeLists.txt index 7a430d79..86a3e446 100644 --- a/ixsentry/CMakeLists.txt +++ b/ixsentry/CMakeLists.txt @@ -2,6 +2,17 @@ # Author: Benjamin Sergeant # Copyright (c) 2019 Machine Zone, Inc. All rights reserved. # +include(CheckCSourceCompiles) + +check_c_source_compiles("#include + int main() + { + const std::regex dsnRegex; + std::smatch group; + std::regex_match(std::string(), group, dsnRegex); + return 0; + }" + HAVE_STD_REGEX) set (IXSENTRY_SOURCES ixsentry/IXSentryClient.cpp @@ -28,3 +39,7 @@ set(IXSENTRY_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIRS}) target_include_directories( ixsentry PUBLIC ${IXSENTRY_INCLUDE_DIRS} ) + +if (HAVE_STD_REGEX) + target_compile_definitions( ixsentry PUBLIC HAVE_STD_REGEX=1 ) +endif() diff --git a/ixsentry/ixsentry/IXSentryClient.cpp b/ixsentry/ixsentry/IXSentryClient.cpp index e6a5b773..d9abc600 100644 --- a/ixsentry/ixsentry/IXSentryClient.cpp +++ b/ixsentry/ixsentry/IXSentryClient.cpp @@ -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(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; } diff --git a/ixsentry/ixsentry/IXSentryClient.h b/ixsentry/ixsentry/IXSentryClient.h index 81291988..fd7ee5cd 100644 --- a/ixsentry/ixsentry/IXSentryClient.h +++ b/ixsentry/ixsentry/IXSentryClient.h @@ -11,7 +11,9 @@ #include #include #include +#ifdef HAVE_STD_REGEX #include +#endif namespace ix { @@ -62,7 +64,9 @@ namespace ix Json::FastWriter _jsonWriter; +#ifdef HAVE_STD_REGEX std::regex _luaFrameRegex; +#endif std::shared_ptr _httpClient; }; diff --git a/ixsnake/ixsnake/IXSnakeProtocol.cpp b/ixsnake/ixsnake/IXSnakeProtocol.cpp index 1422aa6b..40dace0e 100644 --- a/ixsnake/ixsnake/IXSnakeProtocol.cpp +++ b/ixsnake/ixsnake/IXSnakeProtocol.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace snake @@ -196,7 +197,7 @@ namespace snake { std::string filterStr = pdu["body"]["filter"]; } - state->streamSql = std::make_unique(filterStr); + state->streamSql = ix::make_unique(filterStr); state->id = 0; state->onRedisSubscribeCallback = [&ws, state](const std::string& messageStr) { auto msg = nlohmann::json::parse(messageStr); diff --git a/ixwebsocket/IXSocketOpenSSL.cpp b/ixwebsocket/IXSocketOpenSSL.cpp index 46e2b25c..db1b5d15 100644 --- a/ixwebsocket/IXSocketOpenSSL.cpp +++ b/ixwebsocket/IXSocketOpenSSL.cpp @@ -13,6 +13,7 @@ #include "IXUniquePtr.h" #include #include +#include #ifdef _WIN32 #include #else @@ -86,7 +87,7 @@ namespace ix std::atomic SocketOpenSSL::_openSSLInitializationSuccessful(false); std::once_flag SocketOpenSSL::_openSSLInitFlag; - std::array openSSLMutexes; + std::vector> 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()); + } 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(); } } diff --git a/ixwebsocket/IXStrCaseCompare.cpp b/ixwebsocket/IXStrCaseCompare.cpp new file mode 100644 index 00000000..d2fceb60 --- /dev/null +++ b/ixwebsocket/IXStrCaseCompare.cpp @@ -0,0 +1,37 @@ +/* + * IXStrCaseCompare.cpp + * Author: Benjamin Sergeant + * Copyright (c) 2020 Machine Zone. All rights reserved. + */ + +#include "IXStrCaseCompare.h" + +#include +#include + +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 diff --git a/ixwebsocket/IXStrCaseCompare.h b/ixwebsocket/IXStrCaseCompare.h new file mode 100644 index 00000000..8a55de0e --- /dev/null +++ b/ixwebsocket/IXStrCaseCompare.h @@ -0,0 +1,25 @@ +/* + * IXStrCaseCompare.h + * Author: Benjamin Sergeant + * Copyright (c) 2020 Machine Zone. All rights reserved. + */ + +#pragma once + +#include + +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 diff --git a/ixwebsocket/IXWebSocketHandshake.cpp b/ixwebsocket/IXWebSocketHandshake.cpp index 4ff676d8..0e0b0546 100644 --- a/ixwebsocket/IXWebSocketHandshake.cpp +++ b/ixwebsocket/IXWebSocketHandshake.cpp @@ -11,6 +11,7 @@ #include "IXUrlParser.h" #include "IXUserAgent.h" #include "IXWebSocketHandshakeKeyGen.h" +#include "IXStrCaseCompare.h" #include #include #include @@ -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); } std::string WebSocketHandshake::genRandomString(const int len) diff --git a/ixwebsocket/IXWebSocketHttpHeaders.cpp b/ixwebsocket/IXWebSocketHttpHeaders.cpp index 77fd7955..55634301 100644 --- a/ixwebsocket/IXWebSocketHttpHeaders.cpp +++ b/ixwebsocket/IXWebSocketHttpHeaders.cpp @@ -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 parseHttpHeaders( std::unique_ptr& socket, const CancellationRequest& isCancellationRequested) { diff --git a/ixwebsocket/IXWebSocketHttpHeaders.h b/ixwebsocket/IXWebSocketHttpHeaders.h index 777e7a9d..7ba8c4ef 100644 --- a/ixwebsocket/IXWebSocketHttpHeaders.h +++ b/ixwebsocket/IXWebSocketHttpHeaders.h @@ -7,6 +7,7 @@ #pragma once #include "IXCancellationRequest.h" +#include "IXStrCaseCompare.h" #include #include #include @@ -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::pair parseHttpHeaders( diff --git a/makefile b/makefile index eeac92f6..32fff680 100644 --- a/makefile +++ b/makefile @@ -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 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f7db5d08..1a476411 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,7 +5,7 @@ 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) diff --git a/ws/CMakeLists.txt b/ws/CMakeLists.txt index e05417d3..2967d529 100644 --- a/ws/CMakeLists.txt +++ b/ws/CMakeLists.txt @@ -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)