Compare commits

...

23 Commits

Author SHA1 Message Date
2ddac836ad Update unittest_windows_gcc.yml 2023-11-17 06:16:53 -08:00
69e4bc4c05 Update unittest_windows_gcc.yml 2023-11-17 06:15:35 -08:00
RH
3b66efbb6a Fix C++/WinRT compile issue (#493) 2023-11-15 10:40:49 -08:00
f29906c72f Allow building without rtti (#487)
Since factory returns a ProxyConnectionState, setOnConnectionCallback
will be a ProxyConnectionState. The code already makes that assumption,
since it does not check of state return value. Using a
static_pointer_cast will allow the library to be build with rtti.
2023-10-13 19:56:24 -07:00
872f516ede allow building when cpp exceptions are disabled (#489)
IXWebSocket needs exceptions support because of the use of stoi. In
order to build when cpp exceptions are disabled, we can use strtol.
2023-10-13 19:55:26 -07:00
014d43eb13 stop building mingw ; if someone wants to maintain this port please reach out ! 2023-10-13 19:54:25 -07:00
d77067e50f Update window gcc action to latest setup_mingw 2023-10-13 19:39:41 -07:00
ed5b1a0895 Fix links & update info in README (#485) 2023-09-15 22:36:52 -07:00
ef57e3a2b1 Fix hanging of WebSocket::stop() waiting for its thread to join (#481)
This might happen in some special cases where
WebSocketTransport::sendOnSocket() fails, closes the socket, and set
the ready state to CLOSED, but WebSocket::run() stills wait the
interrupt event to happen.

Possibly related to #474
2023-09-01 08:11:36 -07:00
28832f8732 Fix #286 - http response headers overwritten with request headers (#483) 2023-09-01 08:11:07 -07:00
0dd284267a Fix MinGW build warning (#482) 2023-09-01 08:00:35 -07:00
a7019631b7 Fix server empty thread name (#478) 2023-08-01 22:16:43 -07:00
632ee31509 Update IXSocketMbedTLS.cpp (#471) 2023-06-22 14:12:51 -07:00
688af99747 bump version 2023-06-05 10:06:53 -07:00
397bb5d18a Fix version in CMakeLists.txt (#467)
* Fix version in CMakeLists.txt

* Disable IXHttpClientTest
2023-06-05 10:03:17 -07:00
f79c64ae97 Add a reference to Candy in the README (#462) 2023-05-04 00:03:28 -07:00
bc765e73a3 Add pkgconfig file (#459) 2023-04-25 11:54:25 -07:00
dfa10df5ae Set an origin header in websocket and http clients (#455) 2023-04-01 12:19:38 -07:00
eb9a7bed76 fix warning about member variable initialization order + minor makefile build fix 2023-04-01 09:03:39 -07:00
d20864d7d1 Replace CMAKE_BINARY_DIR with CMAKE_CURRENT_BINARY_DIR (#454) 2023-03-29 20:59:39 -07:00
f184a7adef fix incorrect closures with code 1011 Internal error (#450)
* fix incorrect closures with code 1011 Internal error

* enable IXWebSocketCloseTest
2023-03-29 20:45:29 -07:00
dc7b986e10 Build fix for FreeBSD (#449) 2023-03-13 09:36:25 -07:00
1e3560014f Prevent deadlock when server is stopping (#426) 2023-02-25 14:41:05 -08:00
27 changed files with 142 additions and 68 deletions

View File

@ -1,27 +0,0 @@
name: windows
on:
push:
paths-ignore:
- 'docs/**'
pull_request:
jobs:
windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: seanmiddleditch/gha-setup-vsdevenv@master
- uses: seanmiddleditch/gha-setup-ninja@master
- run: |
mkdir build
cd build
cmake -GNinja -DCMAKE_CXX_COMPILER=cl.exe -DCMAKE_C_COMPILER=cl.exe -DUSE_WS=1 -DUSE_TEST=1 -DUSE_ZLIB=OFF -DBUILD_SHARED_LIBS=OFF ..
- run: |
cd build
ninja
- run: |
cd build
ninja test
#- run: ../build/test/ixwebsocket_unittest.exe
# working-directory: test

View File

@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: seanmiddleditch/gha-setup-ninja@master
- uses: egor-tensin/setup-mingw@v2
- uses: bsergean/setup-mingw@d79ce405bac9edef3a1726ef00554a56f0bafe66
- run: |
mkdir build
cd build

View File

@ -6,7 +6,7 @@
cmake_minimum_required(VERSION 3.4.1...3.17.2)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
project(ixwebsocket C CXX)
project(ixwebsocket LANGUAGES C CXX VERSION 11.4.4)
set (CMAKE_CXX_STANDARD 11)
set (CXX_STANDARD_REQUIRED ON)
@ -136,6 +136,7 @@ if (USE_TLS)
else() # default to OpenSSL on all other platforms
if (NOT USE_MBED_TLS) # Unless mbedtls is requested
set(USE_OPEN_SSL ON)
set(requires "openssl")
endif()
endif()
@ -165,9 +166,9 @@ if(BUILD_SHARED_LIBS)
${IXWEBSOCKET_SOURCES}
${IXWEBSOCKET_HEADERS}
)
# Set library version
set_target_properties(ixwebsocket PROPERTIES VERSION 11.3.2)
set_target_properties(ixwebsocket PROPERTIES VERSION ${CMAKE_PROJECT_VERSION})
else()
# Static library
@ -287,9 +288,13 @@ if (IXWEBSOCKET_INSTALL)
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ixwebsocket/
)
configure_file("${CMAKE_CURRENT_LIST_DIR}/ixwebsocket-config.cmake.in" "${CMAKE_BINARY_DIR}/ixwebsocket-config.cmake" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/ixwebsocket-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ixwebsocket")
configure_file("${CMAKE_CURRENT_LIST_DIR}/ixwebsocket-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/ixwebsocket-config.cmake" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ixwebsocket-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ixwebsocket")
set(prefix ${CMAKE_INSTALL_PREFIX})
configure_file("${CMAKE_CURRENT_LIST_DIR}/ixwebsocket.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/ixwebsocket.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ixwebsocket.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(EXPORT ixwebsocket
FILE ixwebsocket-targets.cmake
NAMESPACE ixwebsocket::

View File

@ -99,14 +99,15 @@ Starting with the 11.0.8 release, IXWebSocket should be fully C++11 compatible.
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)
- [Tokio](https://gitlab.com/HCInk/tokio), a discord library focused on audio playback with node bindings.
- [Tokio](https://github.com/liz3/tokio), a discord library focused on audio playback with node bindings.
- [libDiscordBot](https://github.com/tostc/libDiscordBot/tree/master), an easy to use Discord-bot framework.
- [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
- [DisCPP](https://github.com/DisCPP/DisCPP), a simple but feature rich Discord API wrapper (archived as of Oct 8, 2021)
- [discord.cpp](https://github.com/luccanunes/discord.cpp), a discord library for making bots
- [Teleport](http://teleportconnect.com/), Teleport is your own personal remote robot avatar
- [Abaddon](https://github.com/uowuo/abaddon), An alternative Discord client made with C++/gtkmm
- [NovaCoin](https://github.com/novacoin-project/novacoin), a hybrid scrypt PoW + PoS based cryptocurrency.
- [Candy](https://github.com/lanthora/candy), A WebSocket and TUN based VPN for Linux
## Alternative libraries
@ -114,8 +115,8 @@ There are plenty of great websocket libraries out there, which might work for yo
* [websocketpp](https://github.com/zaphoyd/websocketpp) - C++
* [beast](https://github.com/boostorg/beast) - C++
* [µWebSockets](https://github.com/uNetworking/uWebSockets) - C++
* [libwebsockets](https://libwebsockets.org/) - C
* [µWebSockets](https://github.com/uNetworking/uWebSockets) - C
* [wslay](https://github.com/tatsuhiro-t/wslay) - C
[uvweb](https://github.com/bsergean/uvweb) is a library written by the IXWebSocket author which is built on top of [uvw](https://github.com/skypjack/uvw), which is a C++ wrapper for [libuv](https://libuv.org/). It has more dependencies and does not support SSL at this point, but it can be used to open multiple connections within a single OS thread thanks to libuv.
@ -133,9 +134,7 @@ To check the performance of a websocket library, you can look at the [autoroute]
| Windows | Disabled | None | [![Build2][5]][0] |
| UWP | Disabled | None | [![Build2][6]][0] |
| Linux | OpenSSL | Address Sanitizer | [![Build2][7]][0] |
| Mingw | Disabled | None | [![Build2][8]][0] |
* ASAN fails on Linux because of a known problem, we need a
* Some tests are disabled on Windows/UWP because of a pathing problem
* TLS and ZLIB are disabled on Windows/UWP because enabling make the CI run takes a lot of time, for setting up vcpkg.
@ -147,5 +146,4 @@ To check the performance of a websocket library, you can look at the [autoroute]
[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/workflows/linux_asan/badge.svg
[8]: https://github.com/machinezone/IXWebSocket/workflows/unittest_windows_gcc/badge.svg

View File

@ -2,6 +2,8 @@
All changes to this project will be documented in this file.
## [11.4.4] - 2023-06-05
## [11.4.3] - 2022-05-13
Set shorter thread names

11
ixwebsocket.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: ixwebsocket
Description: websocket and http client and server library, with TLS support and very few dependencies
Version: @CMAKE_PROJECT_VERSION@
Libs: -L${libdir} -lixwebsocket
Cflags: -I${includedir}
Requires: @requires@

View File

@ -27,9 +27,13 @@
// mingw build quirks
#if defined(_WIN32) && defined(__GNUC__)
#ifndef AI_NUMERICSERV
#define AI_NUMERICSERV NI_NUMERICSERV
#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG LUP_ADDRCONFIG
#endif
#endif
namespace ix
{

View File

@ -133,16 +133,20 @@ namespace ix
if (headers.find("Content-Length") != headers.end())
{
int contentLength = 0;
try
{
contentLength = std::stoi(headers["Content-Length"]);
const char* p = headers["Content-Length"].c_str();
char* p_end{};
errno = 0;
long val = std::strtol(p, &p_end, 10);
if (p_end == p // invalid argument
|| errno == ERANGE // out of range
|| val < std::numeric_limits<int>::min()
|| val > std::numeric_limits<int>::max()) {
return std::make_tuple(
false, "Error parsing HTTP Header 'Content-Length'", httpRequest);
}
contentLength = val;
}
catch (const std::exception&)
{
return std::make_tuple(
false, "Error parsing HTTP Header 'Content-Length'", httpRequest);
}
if (contentLength < 0)
{
return std::make_tuple(

View File

@ -209,6 +209,12 @@ namespace ix
ss << "User-Agent: " << userAgent() << "\r\n";
}
// Set an origin header if missing
if (args->extraHeaders.find("Origin") == args->extraHeaders.end())
{
ss << "Origin: " << protocol << "://" << host << ":" << port << "\r\n";
}
if (verb == kPost || verb == kPut || verb == kPatch || _forceBody)
{
// Set request compression header

View File

@ -148,6 +148,7 @@ namespace ix
content = gzipCompress(content);
headers["Content-Encoding"] = "gzip";
}
headers["Accept-Encoding"] = "gzip";
#endif
// Log request
@ -161,11 +162,6 @@ namespace ix
// headers["Content-Type"] = "application/octet-stream";
headers["Accept-Ranges"] = "none";
for (auto&& it : request->headers)
{
headers[it.first] = it.second;
}
return std::make_shared<HttpResponse>(
200, "OK", HttpErrorCode::Ok, headers, content);
});

View File

@ -69,7 +69,7 @@ namespace ix
{
// We must deselect the networkevents from the socket event. Otherwise the
// socket will report states that aren't there.
if (_fd != nullptr && _fd->fd != -1)
if (_fd != nullptr && (int)_fd->fd != -1)
WSAEventSelect(_fd->fd, _event, 0);
WSACloseEvent(_event);
}
@ -171,7 +171,7 @@ namespace ix
int count = 0;
// WSAWaitForMultipleEvents returns the index of the first signaled event. And to emulate WSAPoll()
// all the signaled events must be processed.
while (socketIndex < socketEvents.size())
while (socketIndex < (int)socketEvents.size())
{
struct pollfd* fd = socketEvents[socketIndex];
@ -345,7 +345,7 @@ namespace ix
buf[best] = buf[best + 1] = ':';
memmove(buf + best + 2, buf + best + max, i - best - max + 1);
}
if (strlen(buf) < l)
if (strlen(buf) < (size_t)l)
{
strcpy(s, buf);
return s;

View File

@ -8,6 +8,10 @@
#include <cstdint>
#ifdef __FreeBSD__
#include <sys/types.h>
#endif
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN

View File

@ -49,7 +49,7 @@ namespace ix
mbedtls_pk_init(&_pkey);
}
bool SocketMbedTLS::loadSystemCertificates(std::string& /* errorMsg */)
bool SocketMbedTLS::loadSystemCertificates(std::string& errorMsg)
{
#ifdef _WIN32
DWORD flags = CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG |

View File

@ -26,6 +26,7 @@
#ifdef _WIN32
// For manipulating the certificate store
#include <windows.h>
#include <wincrypt.h>
#endif
@ -49,7 +50,7 @@ namespace
X509_STORE* opensslStore = SSL_CTX_get_cert_store(ssl);
int certificateCount = 0;
while (certificateIterator = CertEnumCertificatesInStore(systemStore, certificateIterator))
while ((certificateIterator = CertEnumCertificatesInStore(systemStore, certificateIterator)))
{
X509* x509 = d2i_X509(NULL,
(const unsigned char**) &certificateIterator->pbCertEncoded,
@ -293,10 +294,16 @@ namespace ix
*/
bool SocketOpenSSL::checkHost(const std::string& host, const char* pattern)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return true;
#else
#ifdef _WIN32
return PathMatchSpecA(host.c_str(), pattern);
#else
return fnmatch(pattern, host.c_str(), 0) != FNM_NOMATCH;
#endif
#endif
}

View File

@ -219,6 +219,10 @@ namespace ix
if (_gcThread.joinable())
{
_stopGc = true;
{
std::lock_guard<std::mutex> lock{ _conditionVariableMutexGC };
_canContinueGC = true;
}
_conditionVariableGC.notify_one();
_gcThread.join();
_stopGc = false;
@ -451,7 +455,10 @@ namespace ix
if (!_stopGc)
{
std::unique_lock<std::mutex> lock(_conditionVariableMutexGC);
_conditionVariableGC.wait(lock);
if(!_canContinueGC) {
_conditionVariableGC.wait(lock, [this]{ return _canContinueGC; });
}
_canContinueGC = false;
}
}
}
@ -465,6 +472,10 @@ namespace ix
{
// a connection got terminated, we can run the connection thread GC,
// so wake up the thread responsible for that
{
std::lock_guard<std::mutex> lock{ _conditionVariableMutexGC };
_canContinueGC = true;
}
_conditionVariableGC.notify_one();
}

View File

@ -126,5 +126,6 @@ namespace ix
// as a connection
std::condition_variable _conditionVariableGC;
std::mutex _conditionVariableMutexGC;
bool _canContinueGC{ false };
};
} // namespace ix

View File

@ -41,6 +41,7 @@ namespace ix
, _enablePong(kDefaultEnablePong)
, _pingIntervalSecs(kDefaultPingIntervalSecs)
, _pingType(SendMessageKind::Ping)
, _autoThreadName(true)
{
_ws.setOnCloseCallback(
[this](uint16_t code, const std::string& reason, size_t wireSize, bool remote)
@ -370,7 +371,10 @@ namespace ix
void WebSocket::run()
{
setThreadName(getUrl());
if (_autoThreadName)
{
setThreadName(getUrl());
}
bool firstConnectionAttempt = true;
@ -627,4 +631,9 @@ namespace ix
std::lock_guard<std::mutex> lock(_configMutex);
return _subProtocols;
}
void WebSocket::setAutoThreadName(bool enabled)
{
_autoThreadName = enabled;
}
} // namespace ix

View File

@ -119,6 +119,8 @@ namespace ix
uint32_t getMinWaitBetweenReconnectionRetries() const;
const std::vector<std::string>& getSubProtocols();
void setAutoThreadName(bool enabled);
private:
WebSocketSendInfo sendMessage(const IXWebSocketSendData& message,
SendMessageKind sendMessageKind,
@ -182,6 +184,9 @@ namespace ix
// Subprotocols
std::vector<std::string> _subProtocols;
// enable or disable auto set thread name
bool _autoThreadName;
friend class WebSocketServer;
};
} // namespace ix

View File

@ -87,6 +87,7 @@ namespace ix
WebSocketInitResult WebSocketHandshake::clientHandshake(
const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
const std::string& protocol,
const std::string& host,
const std::string& path,
int port,
@ -125,6 +126,12 @@ namespace ix
ss << "User-Agent: " << userAgent() << "\r\n";
}
// Set an origin header if missing
if (extraHeaders.find("Origin") == extraHeaders.end())
{
ss << "Origin: " << protocol << "://" << host << ":" << port << "\r\n";
}
for (auto& it : extraHeaders)
{
ss << it.first << ": " << it.second << "\r\n";

View File

@ -31,6 +31,7 @@ namespace ix
WebSocketInitResult clientHandshake(const std::string& url,
const WebSocketHttpHeaders& extraHeaders,
const std::string& protocol,
const std::string& host,
const std::string& path,
int port,

View File

@ -57,7 +57,7 @@ namespace ix
server.setOnConnectionCallback(
[remoteUrl, remoteUrlsMapping](std::weak_ptr<ix::WebSocket> webSocket,
std::shared_ptr<ConnectionState> connectionState) {
auto state = std::dynamic_pointer_cast<ProxyConnectionState>(connectionState);
auto state = std::static_pointer_cast<ProxyConnectionState>(connectionState);
auto remoteIp = connectionState->getRemoteIp();
// Server connection

View File

@ -91,6 +91,9 @@ namespace ix
setThreadName("Srv:ws:" + connectionState->getId());
auto webSocket = std::make_shared<WebSocket>();
webSocket->setAutoThreadName(false);
if (_onConnectionCallback)
{
_onConnectionCallback(webSocket, connectionState);

View File

@ -71,10 +71,10 @@ namespace ix
, _closingTimePoint(std::chrono::steady_clock::now())
, _enablePong(kDefaultEnablePong)
, _pingIntervalSecs(kDefaultPingIntervalSecs)
, _pongReceived(false)
, _setCustomMessage(false)
, _kPingMessage("ixwebsocket::heartbeat")
, _pingType(SendMessageKind::Ping)
, _pongReceived(false)
, _pingCount(0)
, _lastSendPingTimePoint(std::chrono::steady_clock::now())
{
@ -140,7 +140,7 @@ namespace ix
_enablePerMessageDeflate);
result = webSocketHandshake.clientHandshake(
remoteUrl, headers, host, path, port, timeoutSecs);
remoteUrl, headers, protocol, host, path, port, timeoutSecs);
if (result.http_status >= 300 && result.http_status < 400)
{
@ -700,6 +700,7 @@ namespace ix
if (_readyState != ReadyState::CLOSING)
{
// send back the CLOSE frame
setReadyState(ReadyState::CLOSING);
sendCloseFrame(code, reason);
wakeUpFromPoll(SelectInterrupt::kCloseRequest);
@ -1072,7 +1073,10 @@ namespace ix
else if (ret <= 0)
{
closeSocket();
setReadyState(ReadyState::CLOSED);
if (_readyState != ReadyState::CLOSING)
{
setReadyState(ReadyState::CLOSED);
}
return false;
}
else
@ -1170,7 +1174,22 @@ namespace ix
{
_requestInitCancellation = true;
if (_readyState == ReadyState::CLOSING || _readyState == ReadyState::CLOSED) return;
if (_readyState == ReadyState::CLOSING || _readyState == ReadyState::CLOSED)
{
// Wake up the socket polling thread, as
// Socket::isReadyToRead() might be still waiting the
// interrupt event to happen.
bool wakeUpPoll = false;
{
std::lock_guard<std::mutex> lock(_socketMutex);
wakeUpPoll = (_socket && _socket->isWakeUpFromPollSupported());
}
if (wakeUpPoll)
{
wakeUpFromPoll(SelectInterrupt::kCloseRequest);
}
return;
}
if (closeWireSize == 0)
{

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "11.4.3"
#define IX_WEBSOCKET_VERSION "11.4.4"

View File

@ -13,16 +13,24 @@ all: brew
install: brew
-DCMAKE_INSTALL_PREFIX=/opt/homebrew
# Use -DCMAKE_INSTALL_PREFIX= to install into another location
# on osx it is good practice to make /usr/local user writable
# sudo chown -R `whoami`/staff /usr/local
#
# Those days (since Apple Silicon mac shipped), on macOS homebrew installs in /opt/homebrew, and /usr/local is readonly
#
# Release, Debug, MinSizeRel, RelWithDebInfo are the build types
#
# Default rule does not use python as that requires first time users to have Python3 installed
#
brew:
ifeq ($(shell uname),Darwin)
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_PREFIX=/opt/homebrew -DCMAKE_UNITY_BUILD=OFF -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; ninja install)
else
mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=OFF -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_TEST=1 .. ; ninja install)
endif
# Docker default target. We've had problems with OpenSSL and TLS 1.3 (on the
# server side ?) and I can't work-around it easily, so we're using mbedtls on

View File

@ -16,7 +16,7 @@ set (TEST_TARGET_NAMES
IXWebSocketServerTest
IXWebSocketTestConnectionDisconnection
IXUrlParserTest
IXHttpClientTest
# IXHttpClientTest ## FIXME httpbin.org does not seem normal
IXUnityBuildsTest
IXHttpTest
IXDNSLookupTest
@ -24,14 +24,13 @@ set (TEST_TARGET_NAMES
# IXWebSocketBroadcastTest ## FIXME was depending on cobra / take a broadcast server from ws
IXStrCaseCompareTest
IXExponentialBackoffTest
IXWebSocketCloseTest
)
# Some unittest don't work on windows yet
# Windows without TLS does not have hmac yet
if (UNIX)
list(APPEND TEST_TARGET_NAMES
IXWebSocketCloseTest
# Fail on Windows in CI probably because the pathing is wrong and
# some resource files cannot be found
IXHttpServerTest

View File

@ -60,6 +60,7 @@ TEST_CASE("http server", "[httpd]")
REQUIRE(response->errorCode == HttpErrorCode::Ok);
REQUIRE(response->statusCode == 200);
REQUIRE(response->headers["Accept-Encoding"] == "gzip");
REQUIRE(response->headers["Content-Encoding"] == "gzip");
server.stop();
}