Compare commits
15 Commits
v7.5.7
...
feature/ma
Author | SHA1 | Date | |
---|---|---|---|
84361c16a9 | |||
d72e5e70f6 | |||
e2c5f751bd | |||
351b86e266 | |||
d0cbff4f4e | |||
cbfc9b9f94 | |||
ca816d801f | |||
2f354d31eb | |||
2c6c1edd37 | |||
9799e7e84b | |||
81be970679 | |||
52221906f6 | |||
3e786fe23a | |||
de24aac7d5 | |||
cd4b0ccf6f |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,7 @@
|
||||
build
|
||||
*.pyc
|
||||
venv
|
||||
ixsnake/ixsnake/.certs/
|
||||
site/
|
||||
ws/.certs/
|
||||
ws/.srl
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM alpine:edge as build
|
||||
FROM alpine:3.11 as build
|
||||
|
||||
RUN apk add --no-cache gcc g++ musl-dev linux-headers cmake openssl-dev
|
||||
RUN apk add --no-cache make
|
||||
@ -16,7 +16,7 @@ WORKDIR /opt
|
||||
USER app
|
||||
RUN [ "make", "ws_install" ]
|
||||
|
||||
FROM alpine:edge as runtime
|
||||
FROM alpine:3.11 as runtime
|
||||
|
||||
RUN apk add --no-cache libstdc++
|
||||
RUN apk add --no-cache strace
|
||||
|
@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
All changes to this project will be documented in this file.
|
||||
|
||||
## [7.6.4] - 2019-12-22
|
||||
|
||||
(client) error handling, quote url in error case when failing to parse one
|
||||
(ws) ws_cobra_publish: register callbacks before connecting
|
||||
(doc) mention mbedtls in supported ssl server backend
|
||||
|
||||
|
||||
## [7.6.3] - 2019-12-20
|
||||
|
||||
(tls) add a simple description of the TLS configuration routine for debugging
|
||||
|
||||
## [7.6.2] - 2019-12-20
|
||||
|
||||
(mbedtls) correct support for using own certificate and private key
|
||||
|
||||
## [7.6.1] - 2019-12-20
|
||||
|
||||
(ws commands) in websocket proxy, disable automatic reconnections + in Dockerfile, use alpine 3.11
|
||||
|
||||
## [7.6.0] - 2019-12-19
|
||||
|
||||
(cobra) Add TLS options to all cobra commands and classes. Add example to the doc.
|
||||
|
||||
## [7.5.8] - 2019-12-18
|
||||
|
||||
(cobra-to-sentry) capture application version from device field
|
||||
|
||||
## [7.5.7] - 2019-12-18
|
||||
|
||||
|
125
docs/ws.md
125
docs/ws.md
@ -243,6 +243,127 @@ Options:
|
||||
--transfer-timeout INT Transfer timeout
|
||||
```
|
||||
|
||||
## Cobra Client
|
||||
## Cobra client and server
|
||||
|
||||
[cobra](https://github.com/machinezone/cobra) is a real time messenging server. ws has a sub-command to interact with cobra.
|
||||
[cobra](https://github.com/machinezone/cobra) is a real time messenging server. ws has several sub-command to interact with cobra. There is also a minimal cobra compatible server named snake available.
|
||||
|
||||
Below are examples on running a snake server and clients with TLS enabled (the server only works with the OpenSSL and the Mbed TLS backend for now).
|
||||
|
||||
First, generate certificates.
|
||||
|
||||
```
|
||||
$ cd /path/to/IXWebSocket
|
||||
$ cd ixsnake/ixsnake
|
||||
$ bash ../../ws/generate_certs.sh
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
.....+++
|
||||
.................+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/trusted-ca-key.pem
|
||||
generated ./.certs/trusted-ca-crt.pem
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
..+++
|
||||
.......................................+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/trusted-server-key.pem
|
||||
Signature ok
|
||||
subject=/O=machinezone/O=IXWebSocket/CN=trusted-server
|
||||
Getting CA Private Key
|
||||
generated ./.certs/trusted-server-crt.pem
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
...................................+++
|
||||
..................................................+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/trusted-client-key.pem
|
||||
Signature ok
|
||||
subject=/O=machinezone/O=IXWebSocket/CN=trusted-client
|
||||
Getting CA Private Key
|
||||
generated ./.certs/trusted-client-crt.pem
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
..............+++
|
||||
.......................................+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/untrusted-ca-key.pem
|
||||
generated ./.certs/untrusted-ca-crt.pem
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
..........+++
|
||||
................................................+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/untrusted-client-key.pem
|
||||
Signature ok
|
||||
subject=/O=machinezone/O=IXWebSocket/CN=untrusted-client
|
||||
Getting CA Private Key
|
||||
generated ./.certs/untrusted-client-crt.pem
|
||||
Generating RSA private key, 2048 bit long modulus
|
||||
.....................................................................................+++
|
||||
...........+++
|
||||
e is 65537 (0x10001)
|
||||
generated ./.certs/selfsigned-client-key.pem
|
||||
Signature ok
|
||||
subject=/O=machinezone/O=IXWebSocket/CN=selfsigned-client
|
||||
Getting Private key
|
||||
generated ./.certs/selfsigned-client-crt.pem
|
||||
```
|
||||
|
||||
Now run the snake server.
|
||||
|
||||
```
|
||||
$ export certs=.certs
|
||||
$ ws snake --tls --port 8765 --cert-file ${certs}/trusted-server-crt.pem --key-file ${certs}/trusted-server-key.pem --ca-file ${certs}/trusted-ca-crt.pem
|
||||
{
|
||||
"apps": {
|
||||
"FC2F10139A2BAc53BB72D9db967b024f": {
|
||||
"roles": {
|
||||
"_sub": {
|
||||
"secret": "66B1dA3ED5fA074EB5AE84Dd8CE3b5ba"
|
||||
},
|
||||
"_pub": {
|
||||
"secret": "1c04DB8fFe76A4EeFE3E318C72d771db"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redis host: 127.0.0.1
|
||||
redis password:
|
||||
redis port: 6379
|
||||
```
|
||||
|
||||
As a new connection comes in, such output should be printed
|
||||
|
||||
```
|
||||
[2019-12-19 20:27:19.724] [info] New connection
|
||||
id: 0
|
||||
Uri: /v2?appkey=_health
|
||||
Headers:
|
||||
Connection: Upgrade
|
||||
Host: 127.0.0.1:8765
|
||||
Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=15; client_max_window_bits=15
|
||||
Sec-WebSocket-Key: d747B0fE61Db73f7Eh47c0==
|
||||
Sec-WebSocket-Protocol: json
|
||||
Sec-WebSocket-Version: 13
|
||||
Upgrade: websocket
|
||||
User-Agent: ixwebsocket/7.5.8 macos ssl/OpenSSL OpenSSL 1.0.2q 20 Nov 2018 zlib 1.2.11
|
||||
```
|
||||
|
||||
To connect and publish a message, do:
|
||||
|
||||
```
|
||||
$ export certs=.certs
|
||||
$ cd /path/to/ws/folder
|
||||
$ ls cobraMetricsSample.json
|
||||
cobraMetricsSample.json
|
||||
$ ws cobra_publish --endpoint wss://127.0.0.1:8765 --appkey FC2F10139A2BAc53BB72D9db967b024f --rolename _pub --rolesecret 1c04DB8fFe76A4EeFE3E318C72d771db --channel foo --cert-file ${certs}/trusted-client-crt.pem --key-file ${certs}/trusted-client-key.pem --ca-file ${certs}/trusted-ca-crt.pem cobraMetricsSample.json
|
||||
[2019-12-19 20:46:42.656] [info] Publisher connected
|
||||
[2019-12-19 20:46:42.657] [info] Connection: Upgrade
|
||||
[2019-12-19 20:46:42.657] [info] Sec-WebSocket-Accept: rs99IFThoBrhSg+k8G4ixH9yaq4=
|
||||
[2019-12-19 20:46:42.657] [info] Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=15; client_max_window_bits=15
|
||||
[2019-12-19 20:46:42.657] [info] Server: ixwebsocket/7.5.8 macos ssl/OpenSSL OpenSSL 1.0.2q 20 Nov 2018 zlib 1.2.11
|
||||
[2019-12-19 20:46:42.657] [info] Upgrade: websocket
|
||||
[2019-12-19 20:46:42.658] [info] Publisher authenticated
|
||||
[2019-12-19 20:46:42.658] [info] Published msg 3
|
||||
[2019-12-19 20:46:42.659] [info] Published message id 3 acked
|
||||
```
|
||||
|
||||
To use OpenSSL on macOS, compile with `make ws_openssl`. First you will have to install OpenSSL libraries, which can be done with Homebrew. Use `make ws_mbedtls` accordingly to use MbedTLS.
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "IXCobraConnection.h"
|
||||
#include <ixcrypto/IXHMac.h>
|
||||
#include <ixwebsocket/IXWebSocket.h>
|
||||
#include <ixwebsocket/IXSocketTLSOptions.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
@ -244,7 +245,8 @@ namespace ix
|
||||
const std::string& endpoint,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions)
|
||||
const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions,
|
||||
const SocketTLSOptions& socketTLSOptions)
|
||||
{
|
||||
_roleName = rolename;
|
||||
_roleSecret = rolesecret;
|
||||
@ -257,6 +259,7 @@ namespace ix
|
||||
std::string url = ss.str();
|
||||
_webSocket->setUrl(url);
|
||||
_webSocket->setPerMessageDeflateOptions(webSocketPerMessageDeflateOptions);
|
||||
_webSocket->setTLSOptions(socketTLSOptions);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -20,6 +20,7 @@
|
||||
namespace ix
|
||||
{
|
||||
class WebSocket;
|
||||
struct SocketTLSOptions;
|
||||
|
||||
enum CobraConnectionEventType
|
||||
{
|
||||
@ -62,7 +63,8 @@ namespace ix
|
||||
const std::string& endpoint,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions);
|
||||
const WebSocketPerMessageDeflateOptions& webSocketPerMessageDeflateOptions,
|
||||
const SocketTLSOptions& socketTLSOptions);
|
||||
|
||||
/// Set the traffic tracker callback
|
||||
static void setTrafficTrackerCallback(const TrafficTrackerCallback& callback);
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "IXCobraMetricsPublisher.h"
|
||||
#include <ixwebsocket/IXSocketTLSOptions.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
@ -31,14 +32,15 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
bool enablePerMessageDeflate)
|
||||
bool enablePerMessageDeflate,
|
||||
const SocketTLSOptions& socketTLSOptions)
|
||||
{
|
||||
// Configure the satori connection and start its publish background thread
|
||||
_cobra_metrics_theaded_publisher.start();
|
||||
|
||||
_cobra_metrics_theaded_publisher.configure(appkey, endpoint, channel,
|
||||
rolename, rolesecret,
|
||||
enablePerMessageDeflate);
|
||||
enablePerMessageDeflate, socketTLSOptions);
|
||||
}
|
||||
|
||||
Json::Value& CobraMetricsPublisher::getGenericAttributes()
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
namespace ix
|
||||
{
|
||||
struct SocketTLSOptions;
|
||||
|
||||
class CobraMetricsPublisher
|
||||
{
|
||||
public:
|
||||
@ -43,7 +45,8 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
bool enablePerMessageDeflate);
|
||||
bool enablePerMessageDeflate,
|
||||
const SocketTLSOptions& socketTLSOptions);
|
||||
|
||||
/// Setter for the list of blacklisted metrics ids.
|
||||
/// That list is sorted internally for fast lookups
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "IXCobraMetricsThreadedPublisher.h"
|
||||
#include <ixwebsocket/IXSetThreadName.h>
|
||||
#include <ixwebsocket/IXSocketTLSOptions.h>
|
||||
#include <ixcore/utils/IXCoreLogger.h>
|
||||
|
||||
#include <algorithm>
|
||||
@ -92,14 +93,17 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
bool enablePerMessageDeflate)
|
||||
bool enablePerMessageDeflate,
|
||||
const SocketTLSOptions& socketTLSOptions)
|
||||
{
|
||||
_channel = channel;
|
||||
|
||||
ix::IXCoreLogger::Log(socketTLSOptions.getDescription().c_str());
|
||||
|
||||
ix::WebSocketPerMessageDeflateOptions webSocketPerMessageDeflateOptions(enablePerMessageDeflate);
|
||||
_cobra_connection.configure(appkey, endpoint,
|
||||
rolename, rolesecret,
|
||||
webSocketPerMessageDeflateOptions);
|
||||
webSocketPerMessageDeflateOptions, socketTLSOptions);
|
||||
}
|
||||
|
||||
void CobraMetricsThreadedPublisher::pushMessage(MessageKind messageKind)
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
namespace ix
|
||||
{
|
||||
struct SocketTLSOptions;
|
||||
|
||||
class CobraMetricsThreadedPublisher
|
||||
{
|
||||
public:
|
||||
@ -30,7 +32,8 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
bool enablePerMessageDeflate);
|
||||
bool enablePerMessageDeflate,
|
||||
const SocketTLSOptions& socketTLSOptions);
|
||||
|
||||
/// Start the worker thread, used for background publishing
|
||||
void start();
|
||||
|
@ -182,7 +182,6 @@ namespace ix
|
||||
|
||||
Json::Value extra;
|
||||
extra["cobra_event"] = msg;
|
||||
extra["cobra_event"] = msg;
|
||||
|
||||
// Builtin tags
|
||||
Json::Value gameTag;
|
||||
@ -200,6 +199,11 @@ namespace ix
|
||||
environmentTag.append(msg["device"]["environment"]);
|
||||
tags.append(environmentTag);
|
||||
|
||||
Json::Value clientVersionTag;
|
||||
clientVersionTag.append("client_version");
|
||||
clientVersionTag.append(msg["device"]["app_version"]);
|
||||
tags.append(clientVersionTag);
|
||||
|
||||
payload["tags"] = tags;
|
||||
|
||||
return _jsonWriter.write(payload);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ixwebsocket/IXSocketTLSOptions.h>
|
||||
|
||||
namespace snake
|
||||
{
|
||||
@ -26,6 +27,9 @@ namespace snake
|
||||
// AppKeys
|
||||
nlohmann::json apps;
|
||||
|
||||
// TLS options
|
||||
ix::SocketTLSOptions socketTLSOptions;
|
||||
|
||||
// Misc
|
||||
bool verbose;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ namespace snake
|
||||
: _appConfig(appConfig)
|
||||
, _server(appConfig.port, appConfig.hostname)
|
||||
{
|
||||
;
|
||||
_server.setTLSOptions(appConfig.socketTLSOptions);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -117,8 +117,7 @@ namespace
|
||||
{
|
||||
char localBuffer[128];
|
||||
Boolean success;
|
||||
success =
|
||||
CFStringGetCString(message, localBuffer, 128, kCFStringEncodingUTF8);
|
||||
success = CFStringGetCString(message, localBuffer, 128, kCFStringEncodingUTF8);
|
||||
if (success)
|
||||
{
|
||||
errMsg = localBuffer;
|
||||
@ -131,6 +130,104 @@ namespace
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
#undef CURL_BUILD_IOS
|
||||
OSStatus CopyIdentityFromPKCS12File(
|
||||
const char *cPath,
|
||||
const char *cPassword,
|
||||
SecIdentityRef *out_cert_and_key)
|
||||
{
|
||||
OSStatus status = errSecItemNotFound;
|
||||
CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(
|
||||
NULL, (const UInt8 *)cPath, strlen(cPath), false);
|
||||
CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
|
||||
cPassword, kCFStringEncodingUTF8) : NULL;
|
||||
CFDataRef pkcs_data = NULL;
|
||||
|
||||
/* We can import P12 files on iOS or OS X 10.7 or later: */
|
||||
/* These constants are documented as having first appeared in 10.6 but they
|
||||
raise linker errors when used on that cat for some reason. */
|
||||
if (CFURLCreateDataAndPropertiesFromResource(
|
||||
NULL, pkcs_url, &pkcs_data, NULL, NULL, &status)) {
|
||||
CFArrayRef items = NULL;
|
||||
|
||||
/* On iOS SecPKCS12Import will never add the client certificate to the
|
||||
* Keychain.
|
||||
*
|
||||
* It gives us back a SecIdentityRef that we can use directly. */
|
||||
#if CURL_BUILD_IOS
|
||||
const void *cKeys[] = {kSecImportExportPassphrase};
|
||||
const void *cValues[] = {password};
|
||||
CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
|
||||
password ? 1L : 0L, NULL, NULL);
|
||||
|
||||
if (options != NULL) {
|
||||
status = SecPKCS12Import(pkcs_data, options, &items);
|
||||
CFRelease(options);
|
||||
}
|
||||
|
||||
/* On macOS SecPKCS12Import will always add the client certificate to
|
||||
* the Keychain.
|
||||
*
|
||||
* As this doesn't match iOS, and apps may not want to see their client
|
||||
* certificate saved in the the user's keychain, we use SecItemImport
|
||||
* with a NULL keychain to avoid importing it.
|
||||
*
|
||||
* This returns a SecCertificateRef from which we can construct a
|
||||
* SecIdentityRef.
|
||||
*/
|
||||
#else
|
||||
SecItemImportExportKeyParameters keyParams;
|
||||
SecExternalFormat inputFormat = kSecFormatPKCS12;
|
||||
SecExternalItemType inputType = kSecItemTypeCertificate;
|
||||
|
||||
memset(&keyParams, 0x00, sizeof(keyParams));
|
||||
keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
|
||||
keyParams.passphrase = password;
|
||||
|
||||
status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType,
|
||||
0, &keyParams, NULL, &items);
|
||||
#endif
|
||||
|
||||
/* Extract the SecIdentityRef */
|
||||
if (status == errSecSuccess && items && CFArrayGetCount(items))
|
||||
{
|
||||
CFIndex i, count;
|
||||
count = CFArrayGetCount(items);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
|
||||
CFTypeID itemID = CFGetTypeID(item);
|
||||
|
||||
if (itemID == CFDictionaryGetTypeID())
|
||||
{
|
||||
CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
|
||||
(CFDictionaryRef) item,
|
||||
kSecImportItemIdentity);
|
||||
CFRetain(identity);
|
||||
*out_cert_and_key = (SecIdentityRef) identity;
|
||||
break;
|
||||
}
|
||||
else if (itemID == SecCertificateGetTypeID())
|
||||
{
|
||||
status = SecIdentityCreateWithCertificate(NULL,
|
||||
(SecCertificateRef) item,
|
||||
out_cert_and_key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (items) CFRelease(items);
|
||||
CFRelease(pkcs_data);
|
||||
}
|
||||
|
||||
if (password) CFRelease(password);
|
||||
CFRelease(pkcs_url);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ix
|
||||
@ -154,6 +251,63 @@ namespace ix
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SocketAppleSSL::handleTLSOptions(std::string& errMsg)
|
||||
{
|
||||
SecIdentityRef cert_and_key = NULL;
|
||||
|
||||
const char* ssl_cert = _tlsOptions.certFile.c_str();
|
||||
|
||||
OSStatus err = CopyIdentityFromPKCS12File(ssl_cert, "foobar", &cert_and_key);
|
||||
|
||||
if (err == noErr && cert_and_key)
|
||||
{
|
||||
SecCertificateRef cert = NULL;
|
||||
CFTypeRef certs_c[1];
|
||||
CFArrayRef certs;
|
||||
|
||||
err = SecIdentityCopyCertificate(cert_and_key, &cert);
|
||||
|
||||
certs_c[0] = cert_and_key;
|
||||
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
|
||||
&kCFTypeArrayCallBacks);
|
||||
err = SSLSetCertificate(_sslContext, certs);
|
||||
if (err != noErr)
|
||||
{
|
||||
errMsg = "SSLSetCertificate failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(err) {
|
||||
case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
|
||||
errMsg = "SSL: Incorrect password for the certificate \"%s\" "
|
||||
"and its private key."; // , ssl_cert);
|
||||
break;
|
||||
case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
|
||||
errMsg = "SSL: Couldn't make sense of the data in the "
|
||||
"certificate \"%s\" and its private key.";
|
||||
; // ssl_cert);
|
||||
break;
|
||||
case -25260: /* errSecPassphraseRequired */
|
||||
errMsg = "SSL The certificate \"%s\" requires a password.";
|
||||
// ssl_cert);
|
||||
break;
|
||||
case errSecItemNotFound:
|
||||
errMsg = "SSL: Can't find the certificate \"%s\" and its private "
|
||||
"key in the Keychain."; // , ssl_cert);
|
||||
break;
|
||||
default:
|
||||
errMsg = "SSL: Can't load the certificate \"%s\" and its private "
|
||||
"key: OSStatus %d" ; // , ssl_cert, err);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// No wait support
|
||||
bool SocketAppleSSL::connect(const std::string& host,
|
||||
int port,
|
||||
@ -174,6 +328,8 @@ namespace ix
|
||||
SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12);
|
||||
SSLSetPeerDomainName(_sslContext, host.c_str(), host.size());
|
||||
|
||||
if (!handleTLSOptions(errMsg)) return false; // FIXME not calling close()
|
||||
|
||||
if (_tlsOptions.isPeerVerifyDisabled())
|
||||
{
|
||||
Boolean option(1);
|
||||
|
@ -34,6 +34,8 @@ namespace ix
|
||||
virtual ssize_t recv(void* buffer, size_t length) final;
|
||||
|
||||
private:
|
||||
bool handleTLSOptions(std::string& errMsg);
|
||||
|
||||
SSLContextRef _sslContext;
|
||||
mutable std::mutex _mutex; // AppleSSL routines are not thread-safe
|
||||
|
||||
|
@ -59,8 +59,7 @@ namespace ix
|
||||
}
|
||||
|
||||
if (mbedtls_ssl_config_defaults(&_conf,
|
||||
(isClient) ? MBEDTLS_SSL_IS_CLIENT
|
||||
: MBEDTLS_SSL_IS_SERVER,
|
||||
(isClient) ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT) != 0)
|
||||
{
|
||||
@ -72,11 +71,16 @@ namespace ix
|
||||
|
||||
if (_tlsOptions.hasCertAndKey())
|
||||
{
|
||||
if (mbedtls_x509_crt_parse_file(&_cacert, _tlsOptions.certFile.c_str()) < 0)
|
||||
if (mbedtls_x509_crt_parse_file(&_cert, _tlsOptions.certFile.c_str()) < 0)
|
||||
{
|
||||
errMsg = "Cannot parse cert file '" + _tlsOptions.certFile + "'";
|
||||
return false;
|
||||
}
|
||||
if (mbedtls_pk_parse_keyfile(&_pkey, _tlsOptions.keyFile.c_str(), "") < 0)
|
||||
{
|
||||
errMsg = "Cannot parse key file '" + _tlsOptions.keyFile + "'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_tlsOptions.isPeerVerifyDisabled())
|
||||
@ -85,7 +89,7 @@ namespace ix
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_conf_ca_chain(&_conf, &_cacert, NULL);
|
||||
mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
|
||||
// FIXME: should we call mbedtls_ssl_conf_verify ?
|
||||
|
||||
@ -98,7 +102,13 @@ namespace ix
|
||||
errMsg = "Cannot parse CA file '" + _tlsOptions.caFile + "'";
|
||||
return false;
|
||||
}
|
||||
mbedtls_ssl_conf_authmode(&_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&_conf, &_cacert, NULL);
|
||||
|
||||
if (_tlsOptions.hasCertAndKey())
|
||||
{
|
||||
mbedtls_ssl_conf_own_cert(&_conf, &_cert, &_pkey);
|
||||
}
|
||||
}
|
||||
|
||||
if (mbedtls_ssl_setup(&_ssl, &_conf) != 0)
|
||||
|
@ -45,6 +45,7 @@ namespace ix
|
||||
mbedtls_ctr_drbg_context _ctr_drbg;
|
||||
mbedtls_x509_crt _cacert;
|
||||
mbedtls_x509_crt _cert;
|
||||
mbedtls_pk_context _pkey;
|
||||
|
||||
std::mutex _mutex;
|
||||
SocketTLSOptions _tlsOptions;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace ix
|
||||
{
|
||||
@ -71,4 +72,16 @@ namespace ix
|
||||
{
|
||||
return _errMsg;
|
||||
}
|
||||
|
||||
std::string SocketTLSOptions::getDescription() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "TLS Options:" << std::endl;
|
||||
ss << " certFile = " << certFile << std::endl;
|
||||
ss << " keyFile = " << keyFile << std::endl;
|
||||
ss << " caFile = " << caFile << std::endl;
|
||||
ss << " ciphers = " << ciphers << std::endl;
|
||||
ss << " ciphers = " << ciphers << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace ix
|
||||
|
@ -43,6 +43,8 @@ namespace ix
|
||||
|
||||
const std::string& getErrorMsg() const;
|
||||
|
||||
std::string getDescription() const;
|
||||
|
||||
private:
|
||||
mutable std::string _errMsg;
|
||||
mutable bool _validated = false;
|
||||
|
@ -144,7 +144,9 @@ namespace ix
|
||||
|
||||
if (!UrlParser::parse(url, protocol, host, path, query, port))
|
||||
{
|
||||
return WebSocketInitResult(false, 0, std::string("Could not parse URL ") + url);
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse url: '" << url << "'";
|
||||
return WebSocketInitResult(false, 0, ss.str());
|
||||
}
|
||||
|
||||
std::string errorMsg;
|
||||
|
@ -6,4 +6,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define IX_WEBSOCKET_VERSION "7.5.7"
|
||||
#define IX_WEBSOCKET_VERSION "7.6.4"
|
||||
|
@ -34,10 +34,10 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
class SatoriChat
|
||||
class CobraChat
|
||||
{
|
||||
public:
|
||||
SatoriChat(const std::string& user,
|
||||
CobraChat(const std::string& user,
|
||||
const std::string& session,
|
||||
const std::string& endpoint);
|
||||
|
||||
@ -72,9 +72,9 @@ namespace
|
||||
std::mutex _logMutex;
|
||||
};
|
||||
|
||||
SatoriChat::SatoriChat(const std::string& user,
|
||||
const std::string& session,
|
||||
const std::string& endpoint)
|
||||
CobraChat::CobraChat(const std::string& user,
|
||||
const std::string& session,
|
||||
const std::string& endpoint)
|
||||
: _user(user)
|
||||
, _session(session)
|
||||
, _endpoint(endpoint)
|
||||
@ -83,34 +83,34 @@ namespace
|
||||
{
|
||||
}
|
||||
|
||||
void SatoriChat::start()
|
||||
void CobraChat::start()
|
||||
{
|
||||
_thread = std::thread(&SatoriChat::run, this);
|
||||
_thread = std::thread(&CobraChat::run, this);
|
||||
}
|
||||
|
||||
void SatoriChat::stop()
|
||||
void CobraChat::stop()
|
||||
{
|
||||
_stop = true;
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
bool SatoriChat::isReady() const
|
||||
bool CobraChat::isReady() const
|
||||
{
|
||||
return _connectedAndSubscribed;
|
||||
}
|
||||
|
||||
size_t SatoriChat::getReceivedMessagesCount() const
|
||||
size_t CobraChat::getReceivedMessagesCount() const
|
||||
{
|
||||
return _receivedQueue.size();
|
||||
}
|
||||
|
||||
bool SatoriChat::hasPendingMessages() const
|
||||
bool CobraChat::hasPendingMessages() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_queue_mutex);
|
||||
return !_publish_queue.empty();
|
||||
}
|
||||
|
||||
Json::Value SatoriChat::popMessage()
|
||||
Json::Value CobraChat::popMessage()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_queue_mutex);
|
||||
auto msg = _publish_queue.front();
|
||||
@ -121,7 +121,7 @@ namespace
|
||||
//
|
||||
// Callback to handle received messages, that are printed on the console
|
||||
//
|
||||
void SatoriChat::subscribe(const std::string& channel)
|
||||
void CobraChat::subscribe(const std::string& channel)
|
||||
{
|
||||
std::string filter;
|
||||
_conn.subscribe(channel, filter, [this](const Json::Value& msg) {
|
||||
@ -151,7 +151,7 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
void SatoriChat::sendMessage(const std::string& text)
|
||||
void CobraChat::sendMessage(const std::string& text)
|
||||
{
|
||||
Json::Value msg;
|
||||
msg["user"] = _user;
|
||||
@ -166,16 +166,21 @@ namespace
|
||||
// Do satori communication on a background thread, where we can have
|
||||
// something like an event loop that publish, poll and receive data
|
||||
//
|
||||
void SatoriChat::run()
|
||||
void CobraChat::run()
|
||||
{
|
||||
// "chat" conf
|
||||
std::string appkey("FC2F10139A2BAc53BB72D9db967b024f");
|
||||
std::string channel = _session;
|
||||
std::string role = "_sub";
|
||||
std::string secret = "66B1dA3ED5fA074EB5AE84Dd8CE3b5ba";
|
||||
SocketTLSOptions socketTLSOptions;
|
||||
|
||||
_conn.configure(
|
||||
appkey, _endpoint, role, secret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
_conn.configure(appkey,
|
||||
_endpoint,
|
||||
role,
|
||||
secret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
socketTLSOptions);
|
||||
_conn.connect();
|
||||
|
||||
_conn.setEventCallback([this, channel](ix::CobraConnectionEventType eventType,
|
||||
@ -280,8 +285,8 @@ TEST_CASE("Cobra_chat", "[cobra_chat]")
|
||||
ss << "ws://localhost:" << port;
|
||||
std::string endpoint = ss.str();
|
||||
|
||||
SatoriChat chatA("jean", session, endpoint);
|
||||
SatoriChat chatB("paul", session, endpoint);
|
||||
CobraChat chatA("jean", session, endpoint);
|
||||
CobraChat chatB("paul", session, endpoint);
|
||||
|
||||
chatA.start();
|
||||
chatB.start();
|
||||
|
@ -62,11 +62,14 @@ namespace
|
||||
gMessageCount = 0;
|
||||
|
||||
ix::CobraConnection conn;
|
||||
SocketTLSOptions socketTLSOptions;
|
||||
|
||||
conn.configure(APPKEY,
|
||||
endpoint,
|
||||
SUBSCRIBER_ROLE,
|
||||
SUBSCRIBER_SECRET,
|
||||
ix::WebSocketPerMessageDeflateOptions(true));
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
socketTLSOptions);
|
||||
conn.connect();
|
||||
|
||||
conn.setEventCallback([&conn](ix::CobraConnectionEventType eventType,
|
||||
@ -202,9 +205,15 @@ TEST_CASE("Cobra_Metrics_Publisher", "[cobra]")
|
||||
|
||||
ix::CobraMetricsPublisher cobraMetricsPublisher;
|
||||
|
||||
SocketTLSOptions socketTLSOptions;
|
||||
bool perMessageDeflate = true;
|
||||
cobraMetricsPublisher.configure(
|
||||
APPKEY, endpoint, CHANNEL, PUBLISHER_ROLE, PUBLISHER_SECRET, perMessageDeflate);
|
||||
cobraMetricsPublisher.configure(APPKEY,
|
||||
endpoint,
|
||||
CHANNEL,
|
||||
PUBLISHER_ROLE,
|
||||
PUBLISHER_SECRET,
|
||||
perMessageDeflate,
|
||||
socketTLSOptions);
|
||||
cobraMetricsPublisher.setSession(uuid4());
|
||||
cobraMetricsPublisher.enable(true); // disabled by default, needs to be enabled to be active
|
||||
|
||||
|
62
ws/ws.cpp
62
ws/ws.cpp
@ -218,6 +218,7 @@ int main(int argc, char** argv)
|
||||
cobraSubscribeApp->add_option("--pidfile", pidfile, "Pid file");
|
||||
cobraSubscribeApp->add_option("--filter", filter, "Stream SQL Filter");
|
||||
cobraSubscribeApp->add_flag("-q", quiet, "Quiet / only display stats");
|
||||
addTLSOptions(cobraSubscribeApp);
|
||||
|
||||
CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher");
|
||||
cobraPublish->add_option("--appkey", appkey, "Appkey")->required();
|
||||
@ -229,6 +230,7 @@ int main(int argc, char** argv)
|
||||
cobraPublish->add_option("path", path, "Path to the file to send")
|
||||
->required()
|
||||
->check(CLI::ExistingPath);
|
||||
addTLSOptions(cobraPublish);
|
||||
|
||||
CLI::App* cobraMetricsPublish =
|
||||
app.add_subcommand("cobra_metrics_publish", "Cobra metrics publisher");
|
||||
@ -242,6 +244,7 @@ int main(int argc, char** argv)
|
||||
->required()
|
||||
->check(CLI::ExistingPath);
|
||||
cobraMetricsPublish->add_flag("--stress", stress, "Stress mode");
|
||||
addTLSOptions(cobraMetricsPublish);
|
||||
|
||||
CLI::App* cobra2statsd = app.add_subcommand("cobra_to_statsd", "Cobra metrics to statsd");
|
||||
cobra2statsd->add_option("--appkey", appkey, "Appkey");
|
||||
@ -256,6 +259,7 @@ int main(int argc, char** argv)
|
||||
cobra2statsd->add_flag("-v", verbose, "Verbose");
|
||||
cobra2statsd->add_option("--pidfile", pidfile, "Pid file");
|
||||
cobra2statsd->add_option("--filter", filter, "Stream SQL Filter");
|
||||
addTLSOptions(cobra2statsd);
|
||||
|
||||
CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra metrics to sentry");
|
||||
cobra2sentry->add_option("--appkey", appkey, "Appkey")->required();
|
||||
@ -269,6 +273,7 @@ int main(int argc, char** argv)
|
||||
cobra2sentry->add_flag("-s", strict, "Strict mode. Error out when sending to sentry fails");
|
||||
cobra2sentry->add_option("--pidfile", pidfile, "Pid file");
|
||||
cobra2sentry->add_option("--filter", filter, "Stream SQL Filter");
|
||||
addTLSOptions(cobra2sentry);
|
||||
|
||||
CLI::App* cobra2redisApp =
|
||||
app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis");
|
||||
@ -282,17 +287,19 @@ int main(int argc, char** argv)
|
||||
cobra2redisApp->add_option("--hostname", hostname, "Redis hostname");
|
||||
cobra2redisApp->add_option("--port", redisPort, "Redis port");
|
||||
cobra2redisApp->add_flag("-q", quiet, "Quiet / only display stats");
|
||||
addTLSOptions(cobra2redisApp);
|
||||
|
||||
CLI::App* runApp = app.add_subcommand("snake", "Snake server");
|
||||
runApp->add_option("--port", port, "Connection url");
|
||||
runApp->add_option("--host", hostname, "Hostname");
|
||||
runApp->add_option("--pidfile", pidfile, "Pid file");
|
||||
runApp->add_option("--redis_hosts", redisHosts, "Redis hosts");
|
||||
runApp->add_option("--redis_port", redisPort, "Redis hosts");
|
||||
runApp->add_option("--redis_password", redisPassword, "Redis password");
|
||||
runApp->add_option("--apps_config_path", appsConfigPath, "Path to auth data")
|
||||
CLI::App* snakeApp = app.add_subcommand("snake", "Snake server");
|
||||
snakeApp->add_option("--port", port, "Connection url");
|
||||
snakeApp->add_option("--host", hostname, "Hostname");
|
||||
snakeApp->add_option("--pidfile", pidfile, "Pid file");
|
||||
snakeApp->add_option("--redis_hosts", redisHosts, "Redis hosts");
|
||||
snakeApp->add_option("--redis_port", redisPort, "Redis hosts");
|
||||
snakeApp->add_option("--redis_password", redisPassword, "Redis password");
|
||||
snakeApp->add_option("--apps_config_path", appsConfigPath, "Path to auth data")
|
||||
->check(CLI::ExistingPath);
|
||||
runApp->add_flag("-v", verbose, "Verbose");
|
||||
snakeApp->add_flag("-v", verbose, "Verbose");
|
||||
addTLSOptions(snakeApp);
|
||||
|
||||
CLI::App* httpServerApp = app.add_subcommand("httpd", "HTTP server");
|
||||
httpServerApp->add_option("--port", port, "Port");
|
||||
@ -314,6 +321,7 @@ int main(int argc, char** argv)
|
||||
proxyServerApp->add_option("--host", hostname, "Hostname");
|
||||
proxyServerApp->add_option("--remote_host", remoteHost, "Remote Hostname");
|
||||
proxyServerApp->add_flag("-v", verbose, "Verbose");
|
||||
addTLSOptions(proxyServerApp);
|
||||
|
||||
CLI::App* minidumpApp = app.add_subcommand("upload_minidump", "Upload a minidump to sentry");
|
||||
minidumpApp->add_option("--minidump", minidump, "Minidump path")->check(CLI::ExistingPath);
|
||||
@ -408,16 +416,17 @@ int main(int argc, char** argv)
|
||||
else if (app.got_subcommand("cobra_subscribe"))
|
||||
{
|
||||
ret = ix::ws_cobra_subscribe_main(
|
||||
appkey, endpoint, rolename, rolesecret, channel, filter, quiet);
|
||||
appkey, endpoint, rolename, rolesecret, channel, filter, quiet, tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("cobra_publish"))
|
||||
{
|
||||
ret = ix::ws_cobra_publish_main(appkey, endpoint, rolename, rolesecret, channel, path);
|
||||
ret = ix::ws_cobra_publish_main(
|
||||
appkey, endpoint, rolename, rolesecret, channel, path, tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("cobra_metrics_publish"))
|
||||
{
|
||||
ret = ix::ws_cobra_metrics_publish_main(
|
||||
appkey, endpoint, rolename, rolesecret, channel, path, stress);
|
||||
appkey, endpoint, rolename, rolesecret, channel, path, stress, tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("cobra_to_statsd"))
|
||||
{
|
||||
@ -431,22 +440,39 @@ int main(int argc, char** argv)
|
||||
statsdPort,
|
||||
prefix,
|
||||
fields,
|
||||
verbose);
|
||||
verbose,
|
||||
tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("cobra_to_sentry"))
|
||||
{
|
||||
ret = ix::ws_cobra_to_sentry_main(
|
||||
appkey, endpoint, rolename, rolesecret, channel, filter, dsn, verbose, strict, jobs);
|
||||
ret = ix::ws_cobra_to_sentry_main(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
channel,
|
||||
filter,
|
||||
dsn,
|
||||
verbose,
|
||||
strict,
|
||||
jobs,
|
||||
tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("cobra_metrics_to_redis"))
|
||||
{
|
||||
ret = ix::ws_cobra_metrics_to_redis(
|
||||
appkey, endpoint, rolename, rolesecret, channel, filter, hostname, redisPort);
|
||||
ret = ix::ws_cobra_metrics_to_redis(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
channel,
|
||||
filter,
|
||||
hostname,
|
||||
redisPort,
|
||||
tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("snake"))
|
||||
{
|
||||
ret = ix::ws_snake_main(
|
||||
port, hostname, redisHosts, redisPort, redisPassword, verbose, appsConfigPath);
|
||||
port, hostname, redisHosts, redisPort, redisPassword, verbose, appsConfigPath, tlsOptions);
|
||||
}
|
||||
else if (app.got_subcommand("httpd"))
|
||||
{
|
||||
|
21
ws/ws.h
21
ws/ws.h
@ -76,14 +76,16 @@ namespace ix
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& filter,
|
||||
bool quiet);
|
||||
bool quiet,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_cobra_publish_main(const std::string& appkey,
|
||||
const std::string& endpoint,
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& path);
|
||||
const std::string& path,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_cobra_metrics_publish_main(const std::string& appkey,
|
||||
const std::string& endpoint,
|
||||
@ -91,7 +93,8 @@ namespace ix
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& path,
|
||||
bool stress);
|
||||
bool stress,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_cobra_to_statsd_main(const std::string& appkey,
|
||||
const std::string& endpoint,
|
||||
@ -103,7 +106,8 @@ namespace ix
|
||||
int port,
|
||||
const std::string& prefix,
|
||||
const std::string& fields,
|
||||
bool verbose);
|
||||
bool verbose,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_cobra_to_sentry_main(const std::string& appkey,
|
||||
const std::string& endpoint,
|
||||
@ -114,7 +118,8 @@ namespace ix
|
||||
const std::string& dsn,
|
||||
bool verbose,
|
||||
bool strict,
|
||||
int jobs);
|
||||
int jobs,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_cobra_metrics_to_redis(const std::string& appkey,
|
||||
const std::string& endpoint,
|
||||
@ -123,7 +128,8 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& filter,
|
||||
const std::string& host,
|
||||
int port);
|
||||
int port,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_snake_main(int port,
|
||||
const std::string& hostname,
|
||||
@ -131,7 +137,8 @@ namespace ix
|
||||
int redisPort,
|
||||
const std::string& redisPassword,
|
||||
bool verbose,
|
||||
const std::string& appsConfigPath);
|
||||
const std::string& appsConfigPath,
|
||||
const ix::SocketTLSOptions& tlsOptions);
|
||||
|
||||
int ws_httpd_main(int port,
|
||||
const std::string& hostname,
|
||||
|
@ -22,7 +22,8 @@ namespace ix
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& path,
|
||||
bool stress)
|
||||
bool stress,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
std::atomic<int> sentMessages(0);
|
||||
std::atomic<int> ackedMessages(0);
|
||||
@ -37,7 +38,7 @@ namespace ix
|
||||
|
||||
bool enablePerMessageDeflate = true;
|
||||
cobraMetricsPublisher.configure(
|
||||
appkey, endpoint, channel, rolename, rolesecret, enablePerMessageDeflate);
|
||||
appkey, endpoint, channel, rolename, rolesecret, enablePerMessageDeflate, tlsOptions);
|
||||
|
||||
while (!cobraMetricsPublisher.isAuthenticated())
|
||||
;
|
||||
|
@ -25,11 +25,16 @@ namespace ix
|
||||
const std::string& channel,
|
||||
const std::string& filter,
|
||||
const std::string& host,
|
||||
int port)
|
||||
int port,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
ix::CobraConnection conn;
|
||||
conn.configure(
|
||||
appkey, endpoint, rolename, rolesecret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
conn.configure(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
conn.connect();
|
||||
|
||||
// Display incoming messages
|
||||
|
@ -22,7 +22,8 @@ namespace ix
|
||||
const std::string& rolename,
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& path)
|
||||
const std::string& path,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
std::ifstream f(path);
|
||||
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||
@ -36,9 +37,12 @@ namespace ix
|
||||
}
|
||||
|
||||
ix::CobraConnection conn;
|
||||
conn.configure(
|
||||
appkey, endpoint, rolename, rolesecret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
conn.connect();
|
||||
conn.configure(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
|
||||
// Display incoming messages
|
||||
std::atomic<bool> authenticated(false);
|
||||
@ -89,6 +93,8 @@ namespace ix
|
||||
}
|
||||
});
|
||||
|
||||
conn.connect();
|
||||
|
||||
while (!authenticated)
|
||||
;
|
||||
while (!messageAcked)
|
||||
|
@ -20,11 +20,16 @@ namespace ix
|
||||
const std::string& rolesecret,
|
||||
const std::string& channel,
|
||||
const std::string& filter,
|
||||
bool quiet)
|
||||
bool quiet,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
ix::CobraConnection conn;
|
||||
conn.configure(
|
||||
appkey, endpoint, rolename, rolesecret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
conn.configure(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
conn.connect();
|
||||
|
||||
Json::FastWriter jsonWriter;
|
||||
|
@ -28,11 +28,16 @@ namespace ix
|
||||
const std::string& dsn,
|
||||
bool verbose,
|
||||
bool strict,
|
||||
int jobs)
|
||||
int jobs,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
ix::CobraConnection conn;
|
||||
conn.configure(
|
||||
appkey, endpoint, rolename, rolesecret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
conn.configure(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
conn.connect();
|
||||
|
||||
Json::FastWriter jsonWriter;
|
||||
@ -132,11 +137,13 @@ namespace ix
|
||||
{
|
||||
seconds = 30;
|
||||
spdlog::warn("Error parsing Retry-After header. "
|
||||
"Using {} for the sleep duration", seconds);
|
||||
"Using {} for the sleep duration",
|
||||
seconds);
|
||||
}
|
||||
|
||||
spdlog::warn("Error 429 - Too Many Requests. ws will sleep "
|
||||
"and retry after {} seconds", retryAfter);
|
||||
"and retry after {} seconds",
|
||||
retryAfter);
|
||||
|
||||
throttled = true;
|
||||
auto duration = std::chrono::seconds(seconds);
|
||||
|
@ -66,11 +66,16 @@ namespace ix
|
||||
int port,
|
||||
const std::string& prefix,
|
||||
const std::string& fields,
|
||||
bool verbose)
|
||||
bool verbose,
|
||||
const ix::SocketTLSOptions& tlsOptions)
|
||||
{
|
||||
ix::CobraConnection conn;
|
||||
conn.configure(
|
||||
appkey, endpoint, rolename, rolesecret, ix::WebSocketPerMessageDeflateOptions(true));
|
||||
conn.configure(appkey,
|
||||
endpoint,
|
||||
rolename,
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
conn.connect();
|
||||
|
||||
auto tokens = parseFields(fields);
|
||||
|
@ -61,7 +61,7 @@ namespace ix
|
||||
|
||||
// Server connection
|
||||
state->webSocket().setOnMessageCallback([webSocket, state, verbose](
|
||||
const WebSocketMessagePtr& msg) {
|
||||
const WebSocketMessagePtr& msg) {
|
||||
if (msg->type == ix::WebSocketMessageType::Open)
|
||||
{
|
||||
std::cerr << "New connection" << std::endl;
|
||||
@ -120,6 +120,7 @@ namespace ix
|
||||
std::string url(remoteUrl);
|
||||
url += msg->openInfo.uri;
|
||||
state->webSocket().setUrl(url);
|
||||
state->webSocket().disableAutomaticReconnection();
|
||||
state->webSocket().start();
|
||||
|
||||
// we should sleep here for a bit until we've established the
|
||||
|
@ -43,7 +43,8 @@ namespace ix
|
||||
int redisPort,
|
||||
const std::string& redisPassword,
|
||||
bool verbose,
|
||||
const std::string& appsConfigPath)
|
||||
const std::string& appsConfigPath,
|
||||
const SocketTLSOptions& socketTLSOptions)
|
||||
{
|
||||
snake::AppConfig appConfig;
|
||||
appConfig.port = port;
|
||||
@ -51,6 +52,7 @@ namespace ix
|
||||
appConfig.verbose = verbose;
|
||||
appConfig.redisPort = redisPort;
|
||||
appConfig.redisPassword = redisPassword;
|
||||
appConfig.socketTLSOptions = socketTLSOptions;
|
||||
|
||||
// Parse config file
|
||||
auto str = readAsString(appsConfigPath);
|
||||
|
Reference in New Issue
Block a user