Compare commits
	
		
			23 Commits
		
	
	
		
			v11.2.0
			...
			feature/pr
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0c5a4af722 | ||
| 
						 | 
					3baf59a031 | ||
| 
						 | 
					b5804c2082 | ||
| 
						 | 
					30bcddb99f | ||
| 
						 | 
					47fd04e210 | ||
| 
						 | 
					4f5b0c4f07 | ||
| 
						 | 
					c2d497abc5 | ||
| 
						 | 
					bbe2ae6dd3 | ||
| 
						 | 
					26897b2425 | ||
| 
						 | 
					e3c98a03cc | ||
| 
						 | 
					97fedf9482 | ||
| 
						 | 
					ae187c0e98 | ||
| 
						 | 
					0f21a20fe3 | ||
| 
						 | 
					54db6ec8bb | ||
| 
						 | 
					0e0a748037 | ||
| 
						 | 
					3b19b0eeca | ||
| 
						 | 
					dbfe3104e8 | ||
| 
						 | 
					68fd8c20d6 | ||
| 
						 | 
					d932af8568 | ||
| 
						 | 
					3add6d4c2e | ||
| 
						 | 
					0d7fb05567 | ||
| 
						 | 
					bf1747ef18 | ||
| 
						 | 
					5c9c05caff | 
							
								
								
									
										2
									
								
								.github/workflows/mkdocs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/mkdocs.yml
									
									
									
									
										vendored
									
									
								
							@@ -21,5 +21,7 @@ jobs:
 | 
			
		||||
        pip install pygments
 | 
			
		||||
    - name: Build doc
 | 
			
		||||
      run: |
 | 
			
		||||
        git clean -dfx .
 | 
			
		||||
        git fetch
 | 
			
		||||
        git pull
 | 
			
		||||
        mkdocs gh-deploy
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/unittest_linux.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/unittest_linux.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  linux:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/unittest_linux_asan.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/unittest_linux_asan.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  linux:
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  mac_tsan_mbedtls:
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  mac_tsan_openssl:
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  mac_tsan_sectransport:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/unittest_uwp.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/unittest_uwp.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  uwp:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/unittest_windows.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/unittest_windows.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  windows:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/unittest_windows_gcc.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/unittest_windows_gcc.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ on:
 | 
			
		||||
  push:
 | 
			
		||||
    paths-ignore:
 | 
			
		||||
    - 'docs/**'
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  windows:
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ set( IXWEBSOCKET_HEADERS
 | 
			
		||||
    ixwebsocket/IXSocketTLSOptions.h
 | 
			
		||||
    ixwebsocket/IXStrCaseCompare.h
 | 
			
		||||
    ixwebsocket/IXUdpSocket.h
 | 
			
		||||
    ixwebsocket/IXUniquePtr.h
 | 
			
		||||
    ixwebsocket/IXUrlParser.h
 | 
			
		||||
    ixwebsocket/IXUuid.h
 | 
			
		||||
    ixwebsocket/IXUtf8Validator.h
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							@@ -24,6 +24,7 @@ A bad security bug affecting users compiling with SSL enabled and OpenSSL as the
 | 
			
		||||
 | 
			
		||||
#include <ixwebsocket/IXNetSystem.h>
 | 
			
		||||
#include <ixwebsocket/IXWebSocket.h>
 | 
			
		||||
#include <ixwebsocket/IXUserAgent.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
@@ -34,6 +35,8 @@ int main()
 | 
			
		||||
    // Our websocket object
 | 
			
		||||
    ix::WebSocket webSocket;
 | 
			
		||||
 | 
			
		||||
    // Connect to a server with encryption
 | 
			
		||||
    // See https://machinezone.github.io/IXWebSocket/usage/#tls-support-and-configuration
 | 
			
		||||
    std::string url("wss://echo.websocket.org");
 | 
			
		||||
    webSocket.setUrl(url);
 | 
			
		||||
 | 
			
		||||
@@ -53,6 +56,12 @@ int main()
 | 
			
		||||
                std::cout << "Connection established" << std::endl;
 | 
			
		||||
                std::cout << "> " << std::flush;
 | 
			
		||||
            }
 | 
			
		||||
            else if (msg->type == ix::WebSocketMessageType::Error)
 | 
			
		||||
            {
 | 
			
		||||
                // Maybe SSL is not configured properly
 | 
			
		||||
                std::cout << "Connection error: " << msg->errorInfo.reason << std::endl;
 | 
			
		||||
                std::cout << "> " << std::flush;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@@ -123,6 +132,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
 | 
			
		||||
@@ -136,4 +146,5 @@ 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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,50 @@
 | 
			
		||||
 | 
			
		||||
All changes to this project will be documented in this file.
 | 
			
		||||
 | 
			
		||||
## [11.2.10] - 2021-07-27
 | 
			
		||||
 | 
			
		||||
(ws) bump CLI command line parsing library from 1.8 to 2.0
 | 
			
		||||
 | 
			
		||||
## [11.2.9] - 2021-06-08
 | 
			
		||||
 | 
			
		||||
(ws) ws connect has a -g option to gzip decompress messages for API such as the websocket Huobi Global.
 | 
			
		||||
 | 
			
		||||
## [11.2.8] - 2021-06-03
 | 
			
		||||
 | 
			
		||||
(websocket client + server) WebSocketMessage class tweak to fix unsafe patterns
 | 
			
		||||
 | 
			
		||||
## [11.2.7] - 2021-05-27
 | 
			
		||||
 | 
			
		||||
(websocket server) Handle and accept firefox browser special upgrade value (keep-alive, Upgrade)
 | 
			
		||||
 | 
			
		||||
## [11.2.6] - 2021-05-18
 | 
			
		||||
 | 
			
		||||
(Windows) move EINVAL (re)definition from IXSocket.h to IXNetSystem.h (fix #289)
 | 
			
		||||
 | 
			
		||||
## [11.2.5] - 2021-04-04
 | 
			
		||||
 | 
			
		||||
(http client) DEL is not an HTTP method name, but DELETE is
 | 
			
		||||
 | 
			
		||||
## [11.2.4] - 2021-03-25
 | 
			
		||||
 | 
			
		||||
(cmake) install IXUniquePtr.h
 | 
			
		||||
 | 
			
		||||
## [11.2.3] - 2021-03-24
 | 
			
		||||
 | 
			
		||||
(ssl + windows) missing include for CertOpenStore function
 | 
			
		||||
 | 
			
		||||
## [11.2.2] - 2021-03-23
 | 
			
		||||
 | 
			
		||||
(ixwebsocket) version bump
 | 
			
		||||
 | 
			
		||||
## [11.2.1] - 2021-03-23
 | 
			
		||||
 | 
			
		||||
(ixwebsocket) version bump
 | 
			
		||||
 | 
			
		||||
## [11.2.0] - 2021-03-23
 | 
			
		||||
 | 
			
		||||
(ixwebsocket) correct mingw support (gcc on windows)
 | 
			
		||||
 | 
			
		||||
## [11.1.4] - 2021-03-23
 | 
			
		||||
 | 
			
		||||
(ixwebsocket) add getMinWaitBetweenReconnectionRetries
 | 
			
		||||
 
 | 
			
		||||
@@ -374,13 +374,10 @@ The webSocket reference is guaranteed to be always valid ; by design the callbac
 | 
			
		||||
// Bound host name, max connections and listen backlog can also be passed in as parameters.
 | 
			
		||||
ix::WebSocketServer server(port);
 | 
			
		||||
 | 
			
		||||
server.setOnClientMessageCallback(std::shared_ptr<ConnectionState> connectionState,
 | 
			
		||||
                                  WebSocket& webSocket,
 | 
			
		||||
                                  const WebSocketMessagePtr& msg)
 | 
			
		||||
{
 | 
			
		||||
server.setOnClientMessageCallback([](std::shared_ptr<ix::ConnectionState> connectionState, ix::WebSocket & webSocket, const ix::WebSocketMessagePtr & msg) {
 | 
			
		||||
    // The ConnectionState object contains information about the connection,
 | 
			
		||||
    // at this point only the client ip address and the port.
 | 
			
		||||
    std::cout << "Remote ip: " << connectionState->getRemoteIp();
 | 
			
		||||
    std::cout << "Remote ip: " << connectionState->getRemoteIp() << std::endl;
 | 
			
		||||
 | 
			
		||||
    if (msg->type == ix::WebSocketMessageType::Open)
 | 
			
		||||
    {
 | 
			
		||||
@@ -398,7 +395,7 @@ server.setOnClientMessageCallback(std::shared_ptr<ConnectionState> connectionSta
 | 
			
		||||
        std::cout << "Headers:" << std::endl;
 | 
			
		||||
        for (auto it : msg->openInfo.headers)
 | 
			
		||||
        {
 | 
			
		||||
            std::cout << it.first << ": " << it.second << std::endl;
 | 
			
		||||
            std::cout << "\t" << it.first << ": " << it.second << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (msg->type == ix::WebSocketMessageType::Message)
 | 
			
		||||
@@ -407,9 +404,11 @@ server.setOnClientMessageCallback(std::shared_ptr<ConnectionState> connectionSta
 | 
			
		||||
        // All connected clients are available in an std::set. See the broadcast cpp example.
 | 
			
		||||
        // Second parameter tells whether we are sending the message in binary or text mode.
 | 
			
		||||
        // Here we send it in the same mode as it was received.
 | 
			
		||||
        std::cout << "Received: " << msg->str << std::endl;
 | 
			
		||||
 | 
			
		||||
        webSocket.send(msg->str, msg->binary);
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
auto res = server.listen();
 | 
			
		||||
if (!res.first)
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ namespace ix
 | 
			
		||||
            {
 | 
			
		||||
                contentLength = std::stoi(headers["Content-Length"]);
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::exception)
 | 
			
		||||
            catch (const std::exception&)
 | 
			
		||||
            {
 | 
			
		||||
                return std::make_tuple(
 | 
			
		||||
                    false, "Error parsing HTTP Header 'Content-Length'", httpRequest);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,10 +20,11 @@
 | 
			
		||||
 | 
			
		||||
namespace ix
 | 
			
		||||
{
 | 
			
		||||
    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
 | 
			
		||||
    const std::string HttpClient::kPost = "POST";
 | 
			
		||||
    const std::string HttpClient::kGet = "GET";
 | 
			
		||||
    const std::string HttpClient::kHead = "HEAD";
 | 
			
		||||
    const std::string HttpClient::kDel = "DEL";
 | 
			
		||||
    const std::string HttpClient::kDelete = "DELETE";
 | 
			
		||||
    const std::string HttpClient::kPut = "PUT";
 | 
			
		||||
    const std::string HttpClient::kPatch = "PATCH";
 | 
			
		||||
 | 
			
		||||
@@ -189,14 +190,14 @@ namespace ix
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set a default Accept header if none is present
 | 
			
		||||
        if (headers.find("Accept") == headers.end())
 | 
			
		||||
        if (args->extraHeaders.find("Accept") == args->extraHeaders.end())
 | 
			
		||||
        {
 | 
			
		||||
            ss << "Accept: */*"
 | 
			
		||||
               << "\r\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set a default User agent if none is present
 | 
			
		||||
        if (headers.find("User-Agent") == headers.end())
 | 
			
		||||
        if (args->extraHeaders.find("User-Agent") == args->extraHeaders.end())
 | 
			
		||||
        {
 | 
			
		||||
            ss << "User-Agent: " << userAgent() << "\r\n";
 | 
			
		||||
        }
 | 
			
		||||
@@ -557,9 +558,9 @@ namespace ix
 | 
			
		||||
        return request(url, kHead, std::string(), args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HttpResponsePtr HttpClient::del(const std::string& url, HttpRequestArgsPtr args)
 | 
			
		||||
    HttpResponsePtr HttpClient::Delete(const std::string& url, HttpRequestArgsPtr args)
 | 
			
		||||
    {
 | 
			
		||||
        return request(url, kDel, std::string(), args);
 | 
			
		||||
        return request(url, kDelete, std::string(), args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HttpResponsePtr HttpClient::request(const std::string& url,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
        HttpResponsePtr get(const std::string& url, HttpRequestArgsPtr args);
 | 
			
		||||
        HttpResponsePtr head(const std::string& url, HttpRequestArgsPtr args);
 | 
			
		||||
        HttpResponsePtr del(const std::string& url, HttpRequestArgsPtr args);
 | 
			
		||||
        HttpResponsePtr Delete(const std::string& url, HttpRequestArgsPtr args);
 | 
			
		||||
 | 
			
		||||
        HttpResponsePtr post(const std::string& url,
 | 
			
		||||
                             const HttpParameters& httpParameters,
 | 
			
		||||
@@ -94,7 +94,7 @@ namespace ix
 | 
			
		||||
        const static std::string kPost;
 | 
			
		||||
        const static std::string kGet;
 | 
			
		||||
        const static std::string kHead;
 | 
			
		||||
        const static std::string kDel;
 | 
			
		||||
        const static std::string kDelete;
 | 
			
		||||
        const static std::string kPut;
 | 
			
		||||
        const static std::string kPatch;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -193,6 +193,7 @@ namespace ix
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) && defined(__GNUC__)
 | 
			
		||||
    static int hexval(unsigned c)
 | 
			
		||||
    {
 | 
			
		||||
        if (c - '0' < 10) return c - '0';
 | 
			
		||||
@@ -200,6 +201,7 @@ namespace ix
 | 
			
		||||
        if (c - 'a' < 6) return c - 'a' + 10;
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // mingw does not have inet_pton, which were taken as is from the musl C library.
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,19 @@
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#include <ws2def.h>
 | 
			
		||||
 | 
			
		||||
#undef EWOULDBLOCK
 | 
			
		||||
#undef EAGAIN
 | 
			
		||||
#undef EINPROGRESS
 | 
			
		||||
#undef EBADF
 | 
			
		||||
#undef EINVAL
 | 
			
		||||
 | 
			
		||||
// map to WSA error codes
 | 
			
		||||
#define EWOULDBLOCK WSAEWOULDBLOCK
 | 
			
		||||
#define EAGAIN WSATRY_AGAIN
 | 
			
		||||
#define EINPROGRESS WSAEINPROGRESS
 | 
			
		||||
#define EBADF WSAEBADF
 | 
			
		||||
#define EINVAL WSAEINVAL
 | 
			
		||||
 | 
			
		||||
// Define our own poll on Windows, as a wrapper on top of select
 | 
			
		||||
typedef unsigned long int nfds_t;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,20 +15,6 @@
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <BaseTsd.h>
 | 
			
		||||
typedef SSIZE_T ssize_t;
 | 
			
		||||
 | 
			
		||||
#undef EWOULDBLOCK
 | 
			
		||||
#undef EAGAIN
 | 
			
		||||
#undef EINPROGRESS
 | 
			
		||||
#undef EBADF
 | 
			
		||||
#undef EINVAL
 | 
			
		||||
 | 
			
		||||
// map to WSA error codes
 | 
			
		||||
#define EWOULDBLOCK WSAEWOULDBLOCK
 | 
			
		||||
#define EAGAIN WSATRY_AGAIN
 | 
			
		||||
#define EINPROGRESS WSAEINPROGRESS
 | 
			
		||||
#define EBADF WSAEBADF
 | 
			
		||||
#define EINVAL WSAEINVAL
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "IXCancellationRequest.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,11 @@
 | 
			
		||||
#include "IXSocketConnect.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
// For manipulating the certificate store
 | 
			
		||||
#include <wincrypt.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ix
 | 
			
		||||
{
 | 
			
		||||
    SocketMbedTLS::SocketMbedTLS(const SocketTLSOptions& tlsOptions, int fd)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,11 @@
 | 
			
		||||
#endif
 | 
			
		||||
#define socketerrno errno
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
// For manipulating the certificate store
 | 
			
		||||
#include <wincrypt.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -357,7 +357,8 @@ namespace ix
 | 
			
		||||
            else // AF_INET6
 | 
			
		||||
            {
 | 
			
		||||
                char remoteIp6[INET6_ADDRSTRLEN];
 | 
			
		||||
                if (ix::inet_ntop(AF_INET6, &client.sin_addr, remoteIp6, INET6_ADDRSTRLEN) == nullptr)
 | 
			
		||||
                if (ix::inet_ntop(AF_INET6, &client.sin_addr, remoteIp6, INET6_ADDRSTRLEN) ==
 | 
			
		||||
                    nullptr)
 | 
			
		||||
                {
 | 
			
		||||
                    int err = Socket::getErrno();
 | 
			
		||||
                    std::stringstream ss;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,12 @@
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    const std::string emptyMsg;
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace ix
 | 
			
		||||
{
 | 
			
		||||
    OnTrafficTrackerCallback WebSocket::_onTrafficTrackerCallback = nullptr;
 | 
			
		||||
@@ -38,7 +44,7 @@ namespace ix
 | 
			
		||||
            [this](uint16_t code, const std::string& reason, size_t wireSize, bool remote) {
 | 
			
		||||
                _onMessageCallback(
 | 
			
		||||
                    ix::make_unique<WebSocketMessage>(WebSocketMessageType::Close,
 | 
			
		||||
                                                      "",
 | 
			
		||||
                                                      emptyMsg,
 | 
			
		||||
                                                      wireSize,
 | 
			
		||||
                                                      WebSocketErrorInfo(),
 | 
			
		||||
                                                      WebSocketOpenInfo(),
 | 
			
		||||
@@ -69,7 +75,7 @@ namespace ix
 | 
			
		||||
        _extraHeaders = headers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const std::string& WebSocket::getUrl() const
 | 
			
		||||
    const std::string WebSocket::getUrl() const
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<std::mutex> lock(_configMutex);
 | 
			
		||||
        return _url;
 | 
			
		||||
@@ -88,7 +94,7 @@ namespace ix
 | 
			
		||||
        _socketTLSOptions = socketTLSOptions;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const WebSocketPerMessageDeflateOptions& WebSocket::getPerMessageDeflateOptions() const
 | 
			
		||||
    const WebSocketPerMessageDeflateOptions WebSocket::getPerMessageDeflateOptions() const
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<std::mutex> lock(_configMutex);
 | 
			
		||||
        return _perMessageDeflateOptions;
 | 
			
		||||
@@ -217,7 +223,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
        _onMessageCallback(ix::make_unique<WebSocketMessage>(
 | 
			
		||||
            WebSocketMessageType::Open,
 | 
			
		||||
            "",
 | 
			
		||||
            emptyMsg,
 | 
			
		||||
            0,
 | 
			
		||||
            WebSocketErrorInfo(),
 | 
			
		||||
            WebSocketOpenInfo(status.uri, status.headers, status.protocol),
 | 
			
		||||
@@ -251,7 +257,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
        _onMessageCallback(
 | 
			
		||||
            ix::make_unique<WebSocketMessage>(WebSocketMessageType::Open,
 | 
			
		||||
                                              "",
 | 
			
		||||
                                              emptyMsg,
 | 
			
		||||
                                              0,
 | 
			
		||||
                                              WebSocketErrorInfo(),
 | 
			
		||||
                                              WebSocketOpenInfo(status.uri, status.headers),
 | 
			
		||||
@@ -338,7 +344,7 @@ namespace ix
 | 
			
		||||
                connectErr.http_status = status.http_status;
 | 
			
		||||
 | 
			
		||||
                _onMessageCallback(ix::make_unique<WebSocketMessage>(WebSocketMessageType::Error,
 | 
			
		||||
                                                                     "",
 | 
			
		||||
                                                                     emptyMsg,
 | 
			
		||||
                                                                     0,
 | 
			
		||||
                                                                     connectErr,
 | 
			
		||||
                                                                     WebSocketOpenInfo(),
 | 
			
		||||
 
 | 
			
		||||
@@ -92,8 +92,8 @@ namespace ix
 | 
			
		||||
        ReadyState getReadyState() const;
 | 
			
		||||
        static std::string readyStateToString(ReadyState readyState);
 | 
			
		||||
 | 
			
		||||
        const std::string& getUrl() const;
 | 
			
		||||
        const WebSocketPerMessageDeflateOptions& getPerMessageDeflateOptions() const;
 | 
			
		||||
        const std::string getUrl() const;
 | 
			
		||||
        const WebSocketPerMessageDeflateOptions getPerMessageDeflateOptions() const;
 | 
			
		||||
        int getPingInterval() const;
 | 
			
		||||
        size_t bufferedAmount() const;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -204,6 +204,9 @@ namespace ix
 | 
			
		||||
        // Check the value of the connection field
 | 
			
		||||
        // Some websocket servers (Go/Gorilla?) send lowercase values for the
 | 
			
		||||
        // connection header, so do a case insensitive comparison
 | 
			
		||||
        //
 | 
			
		||||
        // See https://github.com/apache/thrift/commit/7c4bdf9914fcba6c89e0f69ae48b9675578f084a
 | 
			
		||||
        //
 | 
			
		||||
        if (!insensitiveStringCompare(headers["connection"], "Upgrade"))
 | 
			
		||||
        {
 | 
			
		||||
            std::stringstream ss;
 | 
			
		||||
@@ -296,7 +299,8 @@ namespace ix
 | 
			
		||||
            return sendErrorResponse(400, "Missing Upgrade header");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!insensitiveStringCompare(headers["upgrade"], "WebSocket"))
 | 
			
		||||
        if (!insensitiveStringCompare(headers["upgrade"], "WebSocket") &&
 | 
			
		||||
            headers["Upgrade"] != "keep-alive, Upgrade") // special case for firefox
 | 
			
		||||
        {
 | 
			
		||||
            return sendErrorResponse(400,
 | 
			
		||||
                                     "Invalid Upgrade header, "
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,18 @@ namespace ix
 | 
			
		||||
        {
 | 
			
		||||
            ;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @brief Deleted overload to prevent binding `str` to a temporary, which would cause
 | 
			
		||||
         * undefined behavior since class members don't extend lifetime beyond the constructor call.
 | 
			
		||||
         */
 | 
			
		||||
        WebSocketMessage(WebSocketMessageType t,
 | 
			
		||||
                         std::string&& s,
 | 
			
		||||
                         size_t w,
 | 
			
		||||
                         WebSocketErrorInfo e,
 | 
			
		||||
                         WebSocketOpenInfo o,
 | 
			
		||||
                         WebSocketCloseInfo c,
 | 
			
		||||
                         bool b = false) = delete;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    using WebSocketMessagePtr = std::unique_ptr<WebSocketMessage>;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,12 +14,12 @@ namespace ix
 | 
			
		||||
{
 | 
			
		||||
    /// Default values as defined in the RFC
 | 
			
		||||
    const uint8_t WebSocketPerMessageDeflateOptions::kDefaultServerMaxWindowBits = 15;
 | 
			
		||||
    static const int minServerMaxWindowBits = 8;
 | 
			
		||||
    static const int maxServerMaxWindowBits = 15;
 | 
			
		||||
    static const uint8_t minServerMaxWindowBits = 8;
 | 
			
		||||
    static const uint8_t maxServerMaxWindowBits = 15;
 | 
			
		||||
 | 
			
		||||
    const uint8_t WebSocketPerMessageDeflateOptions::kDefaultClientMaxWindowBits = 15;
 | 
			
		||||
    static const int minClientMaxWindowBits = 8;
 | 
			
		||||
    static const int maxClientMaxWindowBits = 15;
 | 
			
		||||
    static const uint8_t minClientMaxWindowBits = 8;
 | 
			
		||||
    static const uint8_t maxClientMaxWindowBits = 15;
 | 
			
		||||
 | 
			
		||||
    WebSocketPerMessageDeflateOptions::WebSocketPerMessageDeflateOptions(
 | 
			
		||||
        bool enabled,
 | 
			
		||||
@@ -85,11 +85,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
            if (startsWith(token, "server_max_window_bits="))
 | 
			
		||||
            {
 | 
			
		||||
                std::string val = token.substr(token.find_last_of("=") + 1);
 | 
			
		||||
                std::stringstream ss;
 | 
			
		||||
                ss << val;
 | 
			
		||||
                int x;
 | 
			
		||||
                ss >> x;
 | 
			
		||||
                uint8_t x = strtol(token.substr(token.find_last_of("=") + 1).c_str(), nullptr, 10);
 | 
			
		||||
 | 
			
		||||
                // Sanitize values to be in the proper range [8, 15] in
 | 
			
		||||
                // case a server would give us bogus values
 | 
			
		||||
@@ -99,11 +95,7 @@ namespace ix
 | 
			
		||||
 | 
			
		||||
            if (startsWith(token, "client_max_window_bits="))
 | 
			
		||||
            {
 | 
			
		||||
                std::string val = token.substr(token.find_last_of("=") + 1);
 | 
			
		||||
                std::stringstream ss;
 | 
			
		||||
                ss << val;
 | 
			
		||||
                int x;
 | 
			
		||||
                ss >> x;
 | 
			
		||||
                uint8_t x = strtol(token.substr(token.find_last_of("=") + 1).c_str(), nullptr, 10);
 | 
			
		||||
 | 
			
		||||
                // Sanitize values to be in the proper range [8, 15] in
 | 
			
		||||
                // case a server would give us bogus values
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,8 @@ namespace ix
 | 
			
		||||
        bool _enabled;
 | 
			
		||||
        bool _clientNoContextTakeover;
 | 
			
		||||
        bool _serverNoContextTakeover;
 | 
			
		||||
        int _clientMaxWindowBits;
 | 
			
		||||
        int _serverMaxWindowBits;
 | 
			
		||||
        uint8_t _clientMaxWindowBits;
 | 
			
		||||
        uint8_t _serverMaxWindowBits;
 | 
			
		||||
 | 
			
		||||
        void sanitizeClientMaxWindowBits();
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -191,7 +191,6 @@ namespace ix
 | 
			
		||||
                        // Make sure the OS send buffer is flushed before moving on
 | 
			
		||||
                        do
 | 
			
		||||
                        {
 | 
			
		||||
                            size_t bufferedAmount = client->bufferedAmount();
 | 
			
		||||
                            std::chrono::duration<double, std::milli> duration(500);
 | 
			
		||||
                            std::this_thread::sleep_for(duration);
 | 
			
		||||
                        } while (client->bufferedAmount() != 0);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,4 +6,4 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define IX_WEBSOCKET_VERSION "11.1.4"
 | 
			
		||||
#define IX_WEBSOCKET_VERSION "11.2.10"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.cpp
									
									
									
									
									
								
							@@ -15,6 +15,7 @@
 | 
			
		||||
 | 
			
		||||
#include <ixwebsocket/IXNetSystem.h>
 | 
			
		||||
#include <ixwebsocket/IXWebSocket.h>
 | 
			
		||||
#include <ixwebsocket/IXUserAgent.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
@@ -25,9 +26,12 @@ int main()
 | 
			
		||||
    // Our websocket object
 | 
			
		||||
    ix::WebSocket webSocket;
 | 
			
		||||
 | 
			
		||||
    // Connect to a server with encryption
 | 
			
		||||
    // See https://machinezone.github.io/IXWebSocket/usage/#tls-support-and-configuration
 | 
			
		||||
    std::string url("wss://echo.websocket.org");
 | 
			
		||||
    webSocket.setUrl(url);
 | 
			
		||||
 | 
			
		||||
    std::cout << ix::userAgent() << std::endl;
 | 
			
		||||
    std::cout << "Connecting to " << url << "..." << std::endl;
 | 
			
		||||
 | 
			
		||||
    // Setup a callback to be fired (in a background thread, watch out for race conditions !)
 | 
			
		||||
@@ -44,6 +48,12 @@ int main()
 | 
			
		||||
                std::cout << "Connection established" << std::endl;
 | 
			
		||||
                std::cout << "> " << std::flush;
 | 
			
		||||
            }
 | 
			
		||||
            else if (msg->type == ix::WebSocketMessageType::Error)
 | 
			
		||||
            {
 | 
			
		||||
                // Maybe SSL is not configured properly
 | 
			
		||||
                std::cout << "Connection error: " << msg->errorInfo.reason << std::endl;
 | 
			
		||||
                std::cout << "> " << std::flush;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								makefile.dev
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								makefile.dev
									
									
									
									
									
								
							@@ -22,37 +22,37 @@ install: brew
 | 
			
		||||
# Default rule does not use python as that requires first time users to have Python3 installed
 | 
			
		||||
#
 | 
			
		||||
brew:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -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 -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)
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
# Linux for the SSL backend, which works great.
 | 
			
		||||
ws_mbedtls_install:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_ZLIB=OFF -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_ZLIB=OFF -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_TLS=1 -DUSE_WS=1 .. && ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
 | 
			
		||||
 | 
			
		||||
ws_unity:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. && ninja install)
 | 
			
		||||
 | 
			
		||||
ws_install:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
 | 
			
		||||
 | 
			
		||||
ws_install_release:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. -DUSE_TEST=0 && ninja install)
 | 
			
		||||
 | 
			
		||||
ws_openssl_install:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_OPEN_SSL=1 .. ; ninja install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_OPEN_SSL=1 .. ; ninja install)
 | 
			
		||||
 | 
			
		||||
ws_mbedtls:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; make -j 4)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; make -j 4)
 | 
			
		||||
 | 
			
		||||
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_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=Debug -DUSE_WS=1 .. ; make -j 4)
 | 
			
		||||
 | 
			
		||||
ws_no_python:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j4 install)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j4 install)
 | 
			
		||||
 | 
			
		||||
uninstall:
 | 
			
		||||
	xargs rm -fv < build/install_manifest.txt
 | 
			
		||||
@@ -111,27 +111,27 @@ test_server:
 | 
			
		||||
	(cd test && npm i ws && node broadcast-server.js)
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_TEST=1 ..)
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_TEST=1 ..)
 | 
			
		||||
	(cd build ; ninja)
 | 
			
		||||
	(cd build ; ninja -v test)
 | 
			
		||||
 | 
			
		||||
test_asan:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_TEST=1 .. -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer")
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -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 -GNinja -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -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")
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -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)
 | 
			
		||||
 | 
			
		||||
test_tsan_openssl:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja --DCMAKE_UNITY_BUILD=ON DCMAKE_BUILD_TYPE=Debug -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")
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_UNITY_BUILD=ON DCMAKE_BUILD_TYPE=Debug -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_tsan_sectransport:
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja --DCMAKE_UNITY_BUILD=ON DCMAKE_BUILD_TYPE=Debug -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")
 | 
			
		||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_INSTALL_MESSAGE=LAZY -DCMAKE_UNITY_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -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)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5444
									
								
								third_party/cli11/CLI11.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5444
									
								
								third_party/cli11/CLI11.hpp
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35
									
								
								ws/ws.cpp
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								ws/ws.cpp
									
									
									
									
									
								
							@@ -632,7 +632,8 @@ namespace ix
 | 
			
		||||
                         uint32_t maxWaitBetweenReconnectionRetries,
 | 
			
		||||
                         const ix::SocketTLSOptions& tlsOptions,
 | 
			
		||||
                         const std::string& subprotocol,
 | 
			
		||||
                         int pingIntervalSecs);
 | 
			
		||||
                         int pingIntervalSecs,
 | 
			
		||||
                         bool decompressGzipMessages);
 | 
			
		||||
 | 
			
		||||
        void subscribe(const std::string& channel);
 | 
			
		||||
        void start();
 | 
			
		||||
@@ -657,6 +658,7 @@ namespace ix
 | 
			
		||||
        bool _binaryMode;
 | 
			
		||||
        std::atomic<int> _receivedBytes;
 | 
			
		||||
        std::atomic<int> _sentBytes;
 | 
			
		||||
        bool _decompressGzipMessages;
 | 
			
		||||
 | 
			
		||||
        void log(const std::string& msg);
 | 
			
		||||
        WebSocketHttpHeaders parseHeaders(const std::string& data);
 | 
			
		||||
@@ -670,12 +672,14 @@ namespace ix
 | 
			
		||||
                                       uint32_t maxWaitBetweenReconnectionRetries,
 | 
			
		||||
                                       const ix::SocketTLSOptions& tlsOptions,
 | 
			
		||||
                                       const std::string& subprotocol,
 | 
			
		||||
                                       int pingIntervalSecs)
 | 
			
		||||
                                       int pingIntervalSecs,
 | 
			
		||||
                                       bool decompressGzipMessages)
 | 
			
		||||
        : _url(url)
 | 
			
		||||
        , _disablePerMessageDeflate(disablePerMessageDeflate)
 | 
			
		||||
        , _binaryMode(binaryMode)
 | 
			
		||||
        , _receivedBytes(0)
 | 
			
		||||
        , _sentBytes(0)
 | 
			
		||||
        , _decompressGzipMessages(decompressGzipMessages)
 | 
			
		||||
    {
 | 
			
		||||
        if (disableAutomaticReconnection)
 | 
			
		||||
        {
 | 
			
		||||
@@ -784,7 +788,21 @@ namespace ix
 | 
			
		||||
            {
 | 
			
		||||
                spdlog::info("Received {} bytes", msg->wireSize);
 | 
			
		||||
 | 
			
		||||
                ss << "ws_connect: received message: " << msg->str;
 | 
			
		||||
                std::string payload = msg->str;
 | 
			
		||||
                if (_decompressGzipMessages)
 | 
			
		||||
                {
 | 
			
		||||
                    std::string decompressedBytes;
 | 
			
		||||
                    if (gzipDecompress(payload, decompressedBytes))
 | 
			
		||||
                    {
 | 
			
		||||
                        payload = decompressedBytes;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        spdlog::error("Error decompressing: {}", payload);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ss << "ws_connect: received message: " << payload;
 | 
			
		||||
                log(ss.str());
 | 
			
		||||
            }
 | 
			
		||||
            else if (msg->type == ix::WebSocketMessageType::Error)
 | 
			
		||||
@@ -837,7 +855,8 @@ namespace ix
 | 
			
		||||
                        uint32_t maxWaitBetweenReconnectionRetries,
 | 
			
		||||
                        const ix::SocketTLSOptions& tlsOptions,
 | 
			
		||||
                        const std::string& subprotocol,
 | 
			
		||||
                        int pingIntervalSecs)
 | 
			
		||||
                        int pingIntervalSecs,
 | 
			
		||||
                        bool decompressGzipMessages)
 | 
			
		||||
    {
 | 
			
		||||
        std::cout << "Type Ctrl-D to exit prompt..." << std::endl;
 | 
			
		||||
        WebSocketConnect webSocketChat(url,
 | 
			
		||||
@@ -848,7 +867,8 @@ namespace ix
 | 
			
		||||
                                       maxWaitBetweenReconnectionRetries,
 | 
			
		||||
                                       tlsOptions,
 | 
			
		||||
                                       subprotocol,
 | 
			
		||||
                                       pingIntervalSecs);
 | 
			
		||||
                                       pingIntervalSecs,
 | 
			
		||||
                                       decompressGzipMessages);
 | 
			
		||||
        webSocketChat.start();
 | 
			
		||||
 | 
			
		||||
        while (true)
 | 
			
		||||
@@ -2490,6 +2510,7 @@ int main(int argc, char** argv)
 | 
			
		||||
    uint32_t maxWaitBetweenReconnectionRetries = 10 * 1000; // 10 seconds
 | 
			
		||||
    int pingIntervalSecs = 30;
 | 
			
		||||
    int runCount = 1;
 | 
			
		||||
    bool decompressGzipMessages = false;
 | 
			
		||||
 | 
			
		||||
    auto addGenericOptions = [&pidfile](CLI::App* app) {
 | 
			
		||||
        app->add_option("--pidfile", pidfile, "Pid file");
 | 
			
		||||
@@ -2552,6 +2573,7 @@ int main(int argc, char** argv)
 | 
			
		||||
                           "Max Wait Time between reconnection retries");
 | 
			
		||||
    connectApp->add_option("--ping_interval", pingIntervalSecs, "Interval between sending pings");
 | 
			
		||||
    connectApp->add_option("--subprotocol", subprotocol, "Subprotocol");
 | 
			
		||||
    connectApp->add_flag("-g", decompressGzipMessages, "Decompress gziped messages");
 | 
			
		||||
    addGenericOptions(connectApp);
 | 
			
		||||
    addTLSOptions(connectApp);
 | 
			
		||||
 | 
			
		||||
@@ -2740,7 +2762,8 @@ int main(int argc, char** argv)
 | 
			
		||||
                                  maxWaitBetweenReconnectionRetries,
 | 
			
		||||
                                  tlsOptions,
 | 
			
		||||
                                  subprotocol,
 | 
			
		||||
                                  pingIntervalSecs);
 | 
			
		||||
                                  pingIntervalSecs,
 | 
			
		||||
                                  decompressGzipMessages);
 | 
			
		||||
    }
 | 
			
		||||
    else if (app.got_subcommand("autoroute"))
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user