C++11 compatible

This commit is contained in:
Benjamin Sergeant 2020-11-15 21:08:45 -08:00
parent 2aac0afca3
commit 23606b45c7
16 changed files with 135 additions and 42 deletions

View File

@ -8,7 +8,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
project(ixwebsocket C CXX) project(ixwebsocket C CXX)
set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD 11)
set (CXX_STANDARD_REQUIRED ON) set (CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_CXX_EXTENSIONS OFF)
@ -45,6 +45,7 @@ set( IXWEBSOCKET_SOURCES
ixwebsocket/IXSocketFactory.cpp ixwebsocket/IXSocketFactory.cpp
ixwebsocket/IXSocketServer.cpp ixwebsocket/IXSocketServer.cpp
ixwebsocket/IXSocketTLSOptions.cpp ixwebsocket/IXSocketTLSOptions.cpp
ixwebsocket/IXStrCaseCompare.cpp
ixwebsocket/IXUdpSocket.cpp ixwebsocket/IXUdpSocket.cpp
ixwebsocket/IXUrlParser.cpp ixwebsocket/IXUrlParser.cpp
ixwebsocket/IXUserAgent.cpp ixwebsocket/IXUserAgent.cpp
@ -82,6 +83,7 @@ set( IXWEBSOCKET_HEADERS
ixwebsocket/IXSocketFactory.h ixwebsocket/IXSocketFactory.h
ixwebsocket/IXSocketServer.h ixwebsocket/IXSocketServer.h
ixwebsocket/IXSocketTLSOptions.h ixwebsocket/IXSocketTLSOptions.h
ixwebsocket/IXStrCaseCompare.h
ixwebsocket/IXUdpSocket.h ixwebsocket/IXUdpSocket.h
ixwebsocket/IXUrlParser.h ixwebsocket/IXUrlParser.h
ixwebsocket/IXUtf8Validator.h ixwebsocket/IXUtf8Validator.h

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

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

View File

@ -2,6 +2,17 @@
# Author: Benjamin Sergeant # Author: Benjamin Sergeant
# Copyright (c) 2019 Machine Zone, Inc. All rights reserved. # Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
# #
include(CheckCSourceCompiles)
check_c_source_compiles("#include <regex>
int main()
{
const std::regex dsnRegex;
std::smatch group;
std::regex_match(std::string(), group, dsnRegex);
return 0;
}"
HAVE_STD_REGEX)
set (IXSENTRY_SOURCES set (IXSENTRY_SOURCES
ixsentry/IXSentryClient.cpp ixsentry/IXSentryClient.cpp
@ -28,3 +39,7 @@ set(IXSENTRY_INCLUDE_DIRS
${JSONCPP_INCLUDE_DIRS}) ${JSONCPP_INCLUDE_DIRS})
target_include_directories( ixsentry PUBLIC ${IXSENTRY_INCLUDE_DIRS} ) target_include_directories( ixsentry PUBLIC ${IXSENTRY_INCLUDE_DIRS} )
if (HAVE_STD_REGEX)
target_compile_definitions( ixsentry PUBLIC HAVE_STD_REGEX=1 )
endif()

View File

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

View File

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

View File

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

View File

@ -13,6 +13,7 @@
#include "IXUniquePtr.h" #include "IXUniquePtr.h"
#include <cassert> #include <cassert>
#include <errno.h> #include <errno.h>
#include <vector>
#ifdef _WIN32 #ifdef _WIN32
#include <Shlwapi.h> #include <Shlwapi.h>
#else #else
@ -86,7 +87,7 @@ 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::array<std::mutex, CRYPTO_num_locks()> openSSLMutexes; std::vector<std::unique_ptr<std::mutex>> openSSLMutexes;
SocketOpenSSL::SocketOpenSSL(const SocketTLSOptions& tlsOptions, int fd) SocketOpenSSL::SocketOpenSSL(const SocketTLSOptions& tlsOptions, int fd)
: Socket(fd) : Socket(fd)
@ -111,6 +112,11 @@ namespace ix
if (CRYPTO_get_locking_callback() == nullptr) 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); CRYPTO_set_locking_callback(SocketOpenSSL::openSSLLockingCallback);
} }
#endif #endif
@ -128,11 +134,11 @@ namespace ix
{ {
if (mode & CRYPTO_LOCK) if (mode & CRYPTO_LOCK)
{ {
openSSLMutexes[type].lock(); openSSLMutexes[type]->lock();
} }
else else
{ {
openSSLMutexes[type].unlock(); openSSLMutexes[type]->unlock();
} }
} }

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

View File

@ -11,6 +11,7 @@
#include "IXUrlParser.h" #include "IXUrlParser.h"
#include "IXUserAgent.h" #include "IXUserAgent.h"
#include "IXWebSocketHandshakeKeyGen.h" #include "IXWebSocketHandshakeKeyGen.h"
#include "IXStrCaseCompare.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <random> #include <random>
@ -35,9 +36,7 @@ namespace ix
bool WebSocketHandshake::insensitiveStringCompare(const std::string& a, const std::string& b) 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 CaseInsensitiveLess::cmp(a, b);
return tolower(a) == tolower(b);
});
} }
std::string WebSocketHandshake::genRandomString(const int len) std::string WebSocketHandshake::genRandomString(const int len)

View File

@ -12,25 +12,6 @@
namespace ix 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::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(
std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested) std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested)
{ {

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "IXCancellationRequest.h" #include "IXCancellationRequest.h"
#include "IXStrCaseCompare.h"
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
@ -15,17 +16,6 @@ namespace ix
{ {
class Socket; 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>; using WebSocketHttpHeaders = std::map<std::string, std::string, CaseInsensitiveLess>;
std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders( std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(

View File

@ -52,7 +52,7 @@ ws_no_ssl:
mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_WS=1 .. ; make -j 4) mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_WS=1 .. ; make -j 4)
ws_no_python: 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: uninstall:
xargs rm -fv < build/install_manifest.txt xargs rm -fv < build/install_manifest.txt

View File

@ -5,7 +5,7 @@
cmake_minimum_required (VERSION 3.14) cmake_minimum_required (VERSION 3.14)
project (ixwebsocket_unittest) project (ixwebsocket_unittest)
set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD 11)
option(USE_TLS "Add TLS support" ON) option(USE_TLS "Add TLS support" ON)

View File

@ -14,7 +14,7 @@ endif()
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
# set(CMAKE_LD_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) option(USE_TLS "Add TLS support" ON)