Compare commits

..

722 Commits

Author SHA1 Message Date
84361c16a9 (ssl) wip code to handle certs on apple 2019-12-23 15:59:54 -08:00
d72e5e70f6 socket tls options: display ciphers 2019-12-23 12:25:25 -08:00
e2c5f751bd (doc) fix typo 2019-12-22 20:33:14 -08:00
351b86e266 v7.6.4 2019-12-22 20:32:10 -08:00
d0cbff4f4e (client) error handling, quote url in error case when failing to parse on 2019-12-22 20:30:29 -08:00
cbfc9b9f94 (ws) ws_cobra_publish: register callbacks before connecting 2019-12-22 20:29:37 -08:00
ca816d801f (doc) mention mbedtls in supported ssl server backend 2019-12-22 20:28:44 -08:00
2f354d31eb update gitignore file 2019-12-20 15:21:36 -08:00
2c6c1edd37 (tls) add a simple description of the TLS configuration routine for debugging 2019-12-20 15:18:04 -08:00
9799e7e84b (mbedtls) correct support for using own certificate and private key 2019-12-20 15:13:26 -08:00
81be970679 (ws commands) in websocket proxy, disable automatic reconnections + in Dockerfile, use alpine 3.11 2019-12-20 09:51:21 -08:00
52221906f6 (cobra) Add TLS options to all cobra commands and classes. Add example to the doc. 2019-12-19 20:49:28 -08:00
3e786fe23a formatting 2019-12-19 19:13:55 -08:00
de24aac7d5 (cobra-to-sentry) capture application version from device field 2019-12-18 15:41:59 -08:00
cd4b0ccf6f IXSentryClient: remove duplicated line 2019-12-18 15:29:53 -08:00
4e1888ac19 (tls) Experimental TLS server support with mbedtls (windows) + process cert tlsoption (client + server) 2019-12-18 11:51:02 -08:00
237ede56aa (tls servers) Make it clear that apple ssl and mbedtls backends do not support SSL in server mode 2019-12-18 10:43:05 -08:00
ba3b1c1a0f (tls options client) TLSOptions struct _validated member should be initialized to false 2019-12-17 14:10:28 -08:00
c60c606e0f (websocket client) improve the error message when connecting to a non websocket server 2019-12-16 17:57:43 -08:00
5897de6bd9 (server) attempt at fixing #131 by using blocking writes in server mode 2019-12-12 12:17:29 -08:00
cca304fc18 (ws) cobra to sentry - created events with sentry tags based on tags present in the cobra messages 2019-12-11 17:28:11 -08:00
432624df0d update spdlog 2019-12-06 22:05:12 -08:00
9c047fac72 (mac) convert SSL errors to utf8 2019-12-06 16:45:49 -08:00
615df9cef0 Add script to extract the version from the header file and remove DOCKER_VERSION 2019-12-06 16:44:05 -08:00
094d16304d (ws) cobra to sentry. Handle Error 429 Too Many Requests and politely wait before sending more data to sentry 2019-12-05 15:59:29 -08:00
c2377e8747 Using Alpine edge distribution to live on the edge 2019-12-05 15:46:01 -08:00
a63c0d6e78 sentry minidump upload timeout 2019-12-05 15:19:27 -08:00
aa3bface30 bunch of docker compose dev changes 2019-12-05 15:18:02 -08:00
5d75a3aac3 (ws) #125 / fix build problem when jsoncpp is not installed locally 2019-12-03 17:18:16 -08:00
c75959fcb5 (ws) #125 / cmake detects an already installed jsoncpp and will try to use this one if present 2019-12-03 16:01:46 -08:00
bfe0212250 Meta: documentation fixes (#127)
* Clarify versions, minor punctuation fix

* Copyediting, borked URL

* Fix Python comments in C++ code

* Copyediting

* Pretty code

* Copyediting, pretty code

* Typo

* Pretty code
2019-12-03 09:28:18 -08:00
af1a54f2ad (http client) use std::unordered_map instead of std::map for HttpParameters and HttpFormDataParameters class aliases 2019-12-03 09:25:00 -08:00
8a385449ce [#113] Mention StreamSSL as an example windows schannel implementation 2019-12-03 09:22:27 -08:00
396a6985ae (client) internal IXDNSLookup class requires a valid cancellation request function callback to be passed in 2019-12-02 14:52:19 -08:00
92db53c470 (client) fix an overflow in the exponential back off code 2019-12-02 13:51:45 -08:00
49865fed0a ws cobra_subscribe / sleep 1s instead of 10ms in the main loop 2019-12-02 09:52:52 -08:00
f3f71314d9 Improve the limitation section in the doc about TLS, cf bug #113 2019-12-02 09:52:05 -08:00
2d593dd63b ws cobra subcommands / channel is not a positional argument anymore 2019-11-28 15:17:13 -08:00
779b1e6077 add doc about using ws to run a cobra server/publisher/subscriber 2019-11-27 09:26:45 -08:00
6054dd4b49 (http client) Add support for multipart HTTP POST upload + (ixsentry) Add support for uploading a minidump to sentry 2019-11-25 21:11:11 -08:00
69aa3839bf Update README.md 2019-11-23 12:44:24 -08:00
6808a0b500 On Darwin SSL, add ability to skip peer verification. 2019-11-20 13:58:08 -08:00
a7df6120d5 bump version for 32-bit fix 2019-11-20 11:35:07 -08:00
d20ab19fa9 tweaks to the test python proxy code / (moved here) https://gist.github.com/bsergean/bad452fa543ec7df6b7fd496696b2cd8 2019-11-20 11:32:21 -08:00
b946cda65e Compile bug (#122)
* 1) IXWebSocketTransport: BUG: int type has no warranty of number of bits. It depends on compiler and architecture. In my system (64 bit) is 32 bit.
1 << 63 is bad idea in this case because the final number is 0 by overflow.
The symptom observed is that the server can't receive messages.

2) IXSocketFactory: Compilation Warning: Variable not in use.

* Better aproach suggested by Benjamin.
2019-11-20 11:12:24 -08:00
2cfadd93b5 add a python websocket proxy which works on Linux, while ws proxy_server does not 2019-11-18 13:46:11 -08:00
8607dc1a4a ws proxy_server / remote server close not forwarded to the client 2019-11-16 14:21:44 -08:00
521286ae88 fix android build + proxy work 2019-11-16 06:51:53 -08:00
d122e12a1f bump version 2019-11-15 17:19:06 -08:00
c26c3b6892 document new proxy command 2019-11-15 17:18:32 -08:00
ed75d14c86 proxy works but crash when the connection is refused 2019-11-15 17:07:31 -08:00
0841fcec44 add stub code for ws proxy server 2019-11-15 14:30:20 -08:00
4e717abdb8 fix typo 2019-11-15 14:28:30 -08:00
451d2b4253 update readme / add contributing notes 2019-11-15 14:21:28 -08:00
10b4ee353d update changelog 2019-11-06 23:12:45 -08:00
07822625b7 update readme 2019-11-06 23:12:45 -08:00
c943e72c7b check max frame size (#119) 2019-10-28 21:53:31 -07:00
ebb31b4e87 docker build fixes 2019-10-26 11:47:08 -07:00
6904dd3f4c Add unittest to IXSentryClient to lua backtrace parsing code 2019-10-26 10:54:47 -07:00
0e73fe51e9 move sentry code around and add a stub unittest for it 2019-10-25 14:54:31 -07:00
7e67598360 ws cobra to sentry / simplify sent and received message statistic reporting 2019-10-25 14:34:48 -07:00
91a95dc5f6 remove unused quiet argument of ws cobra_metrics_to_redis command 2019-10-25 14:02:56 -07:00
c40033b6d9 Add cobra_metrics_to_redis sub-command to create streams for each cobra metric event being received. 2019-10-24 14:42:36 -07:00
adf83f3255 Create SECURITY.md 2019-10-17 06:58:22 -07:00
8fda7cb131 remove unused code in ws cobra_publish 2019-10-14 11:15:14 -07:00
0e9cf863cf Add client support for websocket subprotocol. Look for the new addSubProtocol method for details 2019-10-13 13:37:34 -07:00
279f6fbfed OpenSSL: add an extra cipher to the default cipher set, which let us connect to wss//echo.websocket.org 2019-10-10 09:37:27 -07:00
f8e7b34bf0 add more docs about ws 2019-10-09 22:42:03 -07:00
d2cf616737 Freebsd (#117)
* add file

* CMake freebsd fix
2019-10-09 17:00:32 -07:00
11a3b64657 (freebsd compile fix) add some missing socket related headers 2019-10-09 15:38:40 -07:00
bab2295fc3 make sure the unittest pass withouth SSL 2019-10-03 09:41:17 -07:00
adcbf0d208 add a target for building wihout ssl + take Matt Boer updated script to run ws test with SSL (still broken for large payload) 2019-10-03 07:47:34 -07:00
19150115bb ws: Signal handling code isn't include on Windows 2019-10-01 16:12:32 -07:00
d93bd9b58b bump version 2019-10-01 16:01:32 -07:00
13801dff8a Add mbed tls version in user agent string + set user agent properly when enabling openssl on macOS 2019-10-01 15:58:35 -07:00
de87fa34dc Implement SSL server with OpenSSL backend / still flaky 2019-10-01 15:43:37 -07:00
d60f5de231 Add --tls option to pass to ws server command, to enable/disable tls 2019-10-01 13:54:46 -07:00
22b4e6a8fb Socket Factory has only one function which works for server and client code, and can do tls for both 2019-09-30 22:06:46 -07:00
1ed39677ce SocketServer::handleConnection takes an std::shared_ptr<Socket> instead of a file descriptor 2019-09-30 21:48:55 -07:00
562d7484e4 openSSLHandshake -> openSSLClientHandshake 2019-09-30 21:24:25 -07:00
58d6e4bb26 all ws subcommands propagate tls options to servers (unimplemented) or ws or http client (implemented) (contributed by Matt DeBoer) 2019-09-30 18:21:20 -07:00
0539d2df2e clang-format 2019-09-30 17:52:39 -07:00
e023dd9c36 ws has a --version option 2019-09-30 17:31:33 -07:00
a95cf727b1 bump version number 2019-09-29 22:10:07 -07:00
b96a65031e fix windows compile error in include/spdlog/details/pattern_formatter-inl.h 2019-09-29 22:00:57 -07:00
2a838d01a7 docs: WITH_TLS => USE_TLS 2019-09-29 21:31:13 -07:00
b0afd36cec document basic usage 2019-09-29 21:29:28 -07:00
77863c0e8b unittest / specify a cacert for tls client tests 2019-09-29 21:24:22 -07:00
2229159bd2 ws curl + http client tls option handling + ca cert processing for mbedtls 2019-09-29 21:13:11 -07:00
89d2606b1d update copyright dates and authors 2019-09-29 20:09:51 -07:00
a7a41c51d9 openssl client: handle TLS options 2019-09-29 20:07:53 -07:00
4de7cb191b most ws command take tls options, no-op for now (contributed by Matt DeBoer) 2019-09-29 18:29:51 -07:00
b3784b4c60 SocketTLSOptions: more methods (contributed by Matt DeBoer) 2019-09-29 17:35:18 -07:00
816c53e3a3 ws transfer + send + receive / improved logging (contributed by Matt DeBoer) 2019-09-29 17:21:52 -07:00
28c4b83ab9 Add ability to use OpenSSL on apple platforms. 2019-09-29 15:34:58 -07:00
3a91894d62 update and change how we build with spdlog 2019-09-29 11:13:24 -07:00
3c8cd6289b ixcobra / fix crash in CobraConnection::publishNext when the queue is empty + handle CobraConnection_PublishMode_Batch in CobraMetricsThreadedPublisher 2019-09-28 10:36:47 -07:00
06297ac756 DNS lookup test works on windows 2019-09-27 14:34:47 -07:00
1b6584ccba mbedtls fixes / the unittest now pass on macOS, and hopefully will on Windows/AppVeyor as well. 2019-09-27 14:07:01 -07:00
0499a80c55 Export port 8008 for Docker + test_ws.sh is /bin/sh compatible 2019-09-26 14:36:14 -07:00
f18980d010 http server unittest + refactoring 2019-09-26 09:45:59 -07:00
2fb0ebb05b http server: in redirect mode, POST request are given a 200 status code and an empty response 2019-09-26 09:27:27 -07:00
7495c9ebb8 Http server: add options to ws https to redirect all requests to a given url. 2019-09-26 09:10:30 -07:00
b26d463bad Stop having ws send subcommand send a binary message in text mode, which would cause error in make ws_test shell script test 2019-09-25 15:39:43 -07:00
f8a581aa69 fix doc 2019-09-24 15:42:28 -07:00
01f3340718 speedup base64 code by reserving memory 2019-09-24 14:17:03 -07:00
a9b8b6decd wrong mutex being used ... 2019-09-24 14:10:41 -07:00
ea83327261 Fix 2 race conditions detected with TSan, one in CobraMetricsPublisher::push and another one in WebSocketTransport::sendData (that one was bad). 2019-09-24 11:46:54 -07:00
39c0fb0072 try to enable more tests on windows 2019-09-23 21:52:32 -07:00
733b414b3b fix tsan errors on macOS when running the unittest 2019-09-23 21:51:55 -07:00
c32067013a fix warning + add redis server logging 2019-09-23 21:14:20 -07:00
fbf80f4ab1 Add simple Redis Server which is only capable of doing publish / subscribe. New ws redis_server sub-command to use it. The server is used in the unittest, so that we can run on CI in environment where redis isn not available like github actions env. 2019-09-23 21:04:01 -07:00
8f8385f8f8 fix linux compilation error, by ordering dependant libraries properly 2019-09-23 12:32:04 -07:00
122118196b move snake code to its own subfolder like ixcobra, ixcrypto, etc... 2019-09-23 11:46:16 -07:00
6f2fe49a7b reformat everything with clang-format 2019-09-23 10:25:23 -07:00
b667c0ad40 fix unittest 2019-09-22 19:40:33 -07:00
283cf83d47 fix unittest compiler warnings 2019-09-22 19:22:48 -07:00
ab1b5cd665 compile fixes 2019-09-22 18:52:57 -07:00
dbf6d00249 add gihub actions 2019-09-22 18:45:30 -07:00
d0963f4af0 compiled fixes on mac and windows 2019-09-22 18:43:57 -07:00
dd01f734c6 WIP: support configurable certificates/keys, and root trust CAs (#114)
* wip: tls options implemented in openssl

* update naming, remove #define guard

* assert compiled with USE_TLS for tls options

* apply autoformatter

* include tls options impl

* style cleanup; auto ssl_err

* ssl_err -> sslErr

* be explicit about SSL_VERIFY_NONE
2019-09-22 18:06:15 -07:00
1769199d32 Fix crash in the Linux unittest in the HTTP client code, in Socket::readBytes. Cobra Metrics Publisher code returns the message id of the message that got published, to be used to validated that it got sent properly when receiving an ack. 2019-09-21 09:23:58 -07:00
8821183aea missing file in ws tool 2019-09-19 12:51:34 -07:00
a7cf151639 In DNS lookup code, make sure the weak pointer we use lives through the expected scope (if branch) 2019-09-19 12:51:11 -07:00
f7a12f52f8 On error while doing a client handshake, additionally display port number next to the host name 2019-09-17 12:08:52 -07:00
1be3b8f4b1 rename test file 2019-09-17 12:07:31 -07:00
0b844d8361 make test target does not try to install anything into /usr/local 2019-09-12 11:45:31 -07:00
57086e28d8 fix unittest warnings + remove trailing spaces 2019-09-12 11:43:52 -07:00
a55d4cdb76 update pre-commit file 2019-09-10 22:18:16 -07:00
40a45717db update clang format file 2019-09-10 22:17:08 -07:00
e853d9ac60 build fixes 2019-09-10 14:05:07 -07:00
4ec0d9b113 update appveyor file to new directory structure 2019-09-10 12:33:47 -07:00
0fde169aa4 restructure project 2019-09-10 12:19:22 -07:00
c09015e870 update ws CLI11 (our command line argument parsing library) to the latest, which fix a compiler bug about optional 2019-09-09 21:25:33 -07:00
7bfa6e8478 improve some websocket error messages + add a utility function with unittest to parse status line and stop using scanf which triggers warnings on Windows 2019-09-09 21:23:57 -07:00
983df2d8f9 improve some websocket error messages + add a utility function with unittest to parse status line and stop using scanf which triggers warnings on Windows 2019-09-09 17:34:36 -07:00
6beba16ca7 websocket and http server: server does not close the bound client socket in many cases 2019-09-09 16:48:26 -07:00
48cefe5525 move poll wrapper on top of select (only used on Windows) to the ix namespace 2019-09-08 11:15:08 -07:00
ae3856c10f Fix Windows CI with appveyor (#110)
Fix windows CI with appveyor + minor tweaks.
2019-09-07 14:07:00 -07:00
260a94d3b0 README: update link to the doc 2019-09-06 10:42:48 -07:00
88c6d6c4cb ci 2019-09-05 22:32:54 -07:00
d5a4931c92 travis linux 2019-09-05 22:29:00 -07:00
11f4e90bc6 ci tweak / install redis 2019-09-05 22:14:55 -07:00
2ce65e7a77 cobra metrics publisher test uses random free port 2019-09-05 22:05:00 -07:00
e81c2c3e5c cobra chat test uses random free port 2019-09-05 22:02:10 -07:00
e40dda7549 add cobra metrics publisher + server unittest 2019-09-05 21:57:05 -07:00
d959d73261 Add new cobra unittest, using server and client 2019-09-05 20:49:58 -07:00
07b7e37a92 snake unsubscription fixes 2019-09-05 20:47:15 -07:00
eb7888347a Fix compiler warning 2019-09-05 20:29:14 -07:00
d8664f4988 ws snake (cobra simple server) add basic support for unsubscription + subscribe send the proper subscription data + redis client subscription can be cancelled 2019-09-05 20:28:34 -07:00
5e94791b13 IXCobraConnection / pdu handlers can crash if they receive json data which is not an object 2019-09-05 20:24:42 -07:00
3e3f7171fc cobra publish fix 2019-09-05 14:31:28 -07:00
308fda0b37 Update README.md 2019-09-05 14:30:51 -07:00
66ed7577b1 all client autobahn test should pass ! last failing one was ...
+- zlib/deflate has a bug with windowsbits == 8, so we silently upgrade it to 9/ (fix autobahn test 13.X which uses 8 for the windows size)
2019-09-04 21:01:30 -07:00
cae23c764f Fragmentation: for sent messages which are compressed, the continuation fragments should not have the rsv1 bit set (fix all autobahn tests for zlib compression 12.X)
Websocket Server / do a case insensitive string search when looking for an Upgrade header whose value is websocket. (some client use WebSocket with some upper-case characters)
2019-09-04 18:23:56 -07:00
f25b2af6eb ws autobahn / use condition variables for stopping test case + add more logging on errors 2019-09-04 12:21:54 -07:00
508d372df1 ws autobahn / report progress with spdlog::info to get timing info 2019-09-04 10:16:32 -07:00
12c3275c36 truncate module 2019-09-03 20:14:35 -07:00
98189c23dc Per message deflate/compression: handle fragmented messages (fix autobahn test: 12.1.X and probably others) 2019-09-03 17:42:48 -07:00
ec55b4a82a Receiving invalid UTF-8 TEXT message should fail and close the connection (fix remaining autobahn test: 6.X UTF-8 Handling) 2019-09-03 16:07:48 -07:00
5d58982f77 IXWebSocketTransport message processing refactoring 2019-09-03 15:48:55 -07:00
57665ca825 Validate close codes. Autobahn 7.9.* 2019-09-03 15:43:16 -07:00
deaa753657 Validate that the close reason is proper utf-8. Autobahn 7.5.1 2019-09-03 14:35:40 -07:00
7c7c877621 Sending invalid UTF-8 TEXT message should fail and close the connection (fix remaining autobahn test: 6.X UTF-8 Handling) 2019-09-03 14:12:40 -07:00
afa71a6b4b Framentation: data and continuation blocks received out of order (fix autobahn test: 5.9 through 5.20 Fragmentation) 2019-09-03 12:02:56 -07:00
172cd39702 Sending invalid UTF-8 TEXT message should fail and close the connection (fix **tons** of autobahn test: 6.X UTF-8 Handling) 2019-09-03 10:30:22 -07:00
82213fd3a5 Message type (TEXT or BINARY) is invalid for received fragmented messages (fix autobahn test: 5.3 through 5.8 Fragmentation) 2019-09-03 09:13:38 -07:00
a32bf885ba bump version 2019-09-02 10:14:15 -07:00
61eb662e5f Ping and Pong messages cannot be fragmented (autobahn test: 5.1 and 5.2 Fragmentation) 2019-09-02 10:13:40 -07:00
2887370666 Close connections when reserved bits are used (autobahn test: 3 Reserved Bits) 2019-09-01 16:23:00 -07:00
8826d62075 changelog 2019-09-01 11:39:00 -07:00
fae284e2e1 readme 2019-09-01 11:38:39 -07:00
2408617ed9 doc 2019-09-01 11:28:27 -07:00
cc10b7f998 compute test case count properly 2019-09-01 11:17:28 -07:00
3c97d5f668 refactoring 2019-09-01 11:10:27 -07:00
0accf24320 condition variable instead of busy looping 2019-09-01 10:50:16 -07:00
8ec2ef345c quiet mode 2019-09-01 10:45:51 -07:00
10dbe2d44d +add utf-8 validation code, not hooked up properly yet
+ws autobahn / Add code to test websocket client compliance with the autobahn test-suite
+Ping received with a payload too large (> 125 bytes) trigger a connection closure
+cobra / add tracking about published messages
+cobra / publish returns a message id, that can be used when
+cobra / new message type in the message received handler when publish/ok is received (can be used to implement an ack system).
2019-08-31 16:47:10 -07:00
6b2cdb6b54 user agent 2019-08-30 12:50:56 -07:00
06bc795133 New option to cap the max wait between reconnection attempts. Still default to 10s. (setMaxWaitBetweenReconnectionRetries) (#108) 2019-08-30 12:46:35 -07:00
239a08ff9b readme 2019-08-26 22:49:40 -07:00
41dd8d2184 readme 2019-08-26 22:29:10 -07:00
57b4b13b65 doc / bring back detailed APIs 2019-08-26 22:11:35 -07:00
a66b116aad one last tweak 2019-08-26 22:02:24 -07:00
5c4102c0be readme tweaks 2019-08-26 21:57:05 -07:00
ebb7318895 new simple readme 2019-08-26 21:55:00 -07:00
b11876096b Add md doc made with mkdocs 2019-08-26 21:25:45 -07:00
d603a74c6f fix #104 - change ZLIB find_package to be optional 2019-08-26 14:51:33 -07:00
95d633e71e tentative gcc build fix 2019-08-26 14:29:16 -07:00
217d0650f4 bump version 2019-08-26 10:20:01 -07:00
45d7bb34d7 ws connect has a new option to send HTTP headers + use WebSocketHttpHeaders instead of unordered_map<string, string> 2019-08-26 10:19:09 -07:00
2e32319236 CobraConnection: sets a unique id field for all messages sent to [cobra](https://github.com/machinezone/cobra).
CobraConnection: sets a counter as a field for each event published.
2019-08-26 09:51:37 -07:00
8eb0d0b7c3 put windows poll in the global namespace, not ix namespace 2019-08-26 09:51:37 -07:00
f18f04c0ee Add client handshake extra headers (#105)
Even though 6455 defines all the necessary headers needed for
client/server handshake, in practice most of the cases websocket servers
expect few more headers. Therefore adding this functionality.
2019-08-26 09:37:40 -07:00
193da820b2 Windows: use select instead of WSAPoll, through a poll wrapper 2019-08-22 10:34:17 -07:00
c6198305d4 add new makefile target to make git tags 2019-08-20 09:21:30 -07:00
c77d6ae3f5 bump version + talk about Windows fix in the changelog 2019-08-20 09:20:02 -07:00
c72b2dbd6b add poll alias to WSAPoll on Windows 2019-08-19 22:26:25 -07:00
835523f77b fix #101 / wrong include in IXSocket.cpp on Windows 2019-08-19 22:19:39 -07:00
ec8a35b587 README tweaks 2019-08-19 20:35:26 -07:00
aca18995d1 README / formatting 2019-08-19 20:33:56 -07:00
f9178f58aa README.md: add reference to WSAStartup to initialize the networking system 2019-08-19 09:47:59 -07:00
2477946e68 (CI) linux: install libmbedtls 2019-08-14 21:49:43 -07:00
7c4d040384 (CI) try to build Linux on Ubuntu Bionic 2019-08-14 21:44:49 -07:00
197cf8ed36 bump version 2019-08-14 21:36:20 -07:00
dd0d7c268f CobraMetricThreadedPublisher _enable flag is an atomic, and CobraMetricsPublisher is enabled by default 2019-08-14 19:54:30 -07:00
b2bfccac0a clang format 2019-08-13 10:59:18 -07:00
8b8b352e61 fix #99 / Connect error descriptions are invalid 2019-08-13 10:49:11 -07:00
0403dd354b update readme 2019-08-06 20:55:44 -07:00
b78b453504 fix #98 2019-08-02 17:11:53 -07:00
f8fef833b8 new options for cobra commands
- ws cobra_subscribe has a new -q (quiet) option
- ws cobra_subscribe knows to and display msg stats (count and # of messages received per second)
- ws cobra_subscribe, cobra_to_statsd and cobra_to_sentry commands have a new option, --filter to restrict the events they want to receive
2019-08-01 15:22:24 -07:00
fc4068f2e5 ws connect command has a new option to send in binary mode (still default to text) 2019-07-25 15:48:45 -07:00
c300866dcc add better line editing capability to ws connect, thanks to linenoise-cpp 2019-07-25 11:54:50 -07:00
18485a74e5 README.md / cosmetic 2019-07-23 14:04:45 -07:00
4dd5950406 fix typo in README 2019-07-23 13:52:16 -07:00
98de54106d README: add reference to conan/vcpk to the build section 2019-07-22 20:41:06 -07:00
4d64272a1a do not update homebrew when installing a package 2019-07-03 14:49:39 -07:00
0ccece908b ci / get mbedtls from homebrew on mac 2019-07-03 14:46:05 -07:00
64cd725060 do not use mbed tls for the unittest 2019-07-03 14:39:46 -07:00
cc2fa55608 add new docker file to run the unittest with tsan on latest Ubuntu 2019-06-30 23:37:25 -07:00
4fb268585c dns / use cancellable instead of blocking 2019-06-30 23:26:14 -07:00
3a2495c456 make IXDNSLookup more robust 2019-06-26 19:12:48 -07:00
1d4d058ed0 simplify IXDNSLookup 2019-06-26 16:25:07 -07:00
15a1347531 use poll instead of select in SocketServer 2019-06-25 17:18:24 -07:00
4cbfa71338 switch from select to poll to deal with Android 9 giving us high socket fds when calling ::connect 2019-06-25 17:11:27 -07:00
705625af0a refactor select code + add protection against large fds (cf Android 9) 2019-06-25 15:41:39 -07:00
01bc6654cb Add extra check in IXWebSocketCloseTest.cpp 2019-06-25 14:10:39 -07:00
eea42bff66 select refactoring IXSocket::select -> IXSocket::poll 2019-06-25 10:16:40 -07:00
06b4762c19 disable CI on Windows 2019-06-25 00:28:11 -07:00
1ee9479009 cmake use_tls fix 2019-06-24 23:34:31 -07:00
73e94ed03a do not build mbedtls on ci 2019-06-24 23:28:35 -07:00
1883519e82 try to disable TLS for unittesting 2019-06-24 23:27:44 -07:00
6f6c1f85ef CI / build zlib and mbedtls locally 2019-06-24 23:17:19 -07:00
c55ff3cb1b CI work 2019-06-24 10:17:57 -07:00
08006ddd97 try to activate CI on windows again 2019-06-23 18:32:18 -07:00
fa4aee6ddc bump docker version 2019-06-23 18:17:24 -07:00
691502d7ad Feature/httpd (#94)
* Stub code for http server

* can send a response, cannot process body yet

* write headers to the response

* remove commented code

* add simple test + set default http handler

* tweak CI + unittest

* add missing file

* rewrite http::trim in a simple way

* doc
2019-06-23 14:54:21 -07:00
43deaba547 IXDNSLookup. Uses weak pointer + smart_ptr + shared_from_this instead of static sets + mutex to handle object going away before dns lookup has resolved 2019-06-19 00:43:59 -07:00
2d02ae0f0c cobra_to_sentry / backtraces are reversed and line number is not extracted correctly 2019-06-13 10:18:40 -07:00
a8879da4fc disable windows on CI for now 2019-06-10 22:10:43 -07:00
5f4a430845 disable building ws on windows on travis 2019-06-10 22:01:19 -07:00
b9231be305 (cmake) missing find_package(Threads) on UNIX 2019-06-10 13:39:22 -07:00
7cb5cc05e4 Add -DUSE_VENDORED_THIRD_PARTY=1 to build ws 2019-06-10 13:26:41 -07:00
750a752ac0 - mbedtls and zlib are searched with find_package, and we use the vendored version if nothing is found 2019-06-10 11:18:27 -07:00
61e5f52286 - travis CI uses g++ on Linux 2019-06-09 14:27:45 -07:00
ce0b716f54 compile error in IXWebSocketMessageQTest 2019-06-09 12:25:36 -07:00
aae8e5ec65 fix IXWebSocketMessageQTest.cpp 2019-06-09 12:08:00 -07:00
2723e8466e fix changelog 2019-06-09 12:02:38 -07:00
f13c610352 update README to reflect the new API 2019-06-09 12:02:02 -07:00
55c65b08bf - WebSocket::send() sends message in TEXT mode by default
- WebSocketMessage sets a new binary field, which tells whether the received incoming message is binary or text
2019-06-09 11:56:47 -07:00
a11aa3e0dd WebSocket::send takes a third arg, binary which default to true (can be text too) 2019-06-09 11:35:31 -07:00
de0bf5ebcd WebSocket callback only take one object, a const ix::WebSocketMessagePtr& msg 2019-06-09 11:33:17 -07:00
15369e1ae9 ... 2019-06-09 10:22:27 -07:00
d4115880b9 Add explicite WebSocket::sendBinary
New headers + WebSocketMessage class to hold message data, still not used across the board
2019-06-09 10:10:33 -07:00
3c80c75e4a Add test/compatibility folder with small servers and clients written in different languages and different libraries to test compatibility. 2019-06-08 09:46:26 -07:00
5cb72dce4c ws echo_server has a -g option to print a greeting message on connect 2019-06-08 09:16:33 -07:00
d2747487e3 IXSocketMbedTLS: better error handling in close and connect 2019-06-06 14:59:22 -07:00
12e664fc61 add a changelog 2019-06-06 13:59:12 -07:00
cbf21b4008 add an option to easily disable per message deflate compression 2019-06-06 13:48:53 -07:00
68c1bf7017 fix Dockerfile link 2019-06-05 19:38:44 -07:00
257c901255 cobra to sentry / more error handling 2019-06-05 19:37:51 -07:00
15d8c663da cobra to sentry fixes 2019-06-05 18:47:48 -07:00
d50125c62d Feature/http async (#90)
* unittest working / uses shared_ptr for a bunch of things 🗿

* fix command line tools

* fix ws + add doc

* add more logging
2019-06-05 17:04:24 -07:00
9262880369 Fix compile error with JSON uint64_t 🚯 2019-06-04 13:45:29 -07:00
2b111e8352 HttpResponse is a struct, not a tuple 🉐 2019-06-03 22:12:52 -07:00
a35cbdfb7c http / PUT fix 🐚 2019-06-03 21:12:39 -07:00
6a41b7389f http client: stop hardcoding Accept header, and use a default value if one is passed in 👭 2019-06-03 14:02:54 -07:00
a187e69650 Add simple HTTP and HTTPS client test ㊙️ 2019-06-03 12:23:35 -07:00
fcacddbd9f (http client) / Add DEL and PUT method, make requests and other utilities public 👐 2019-06-03 11:38:56 -07:00
fa84ade6be Feature/ws windows (#86)
* try to build ws on window on travis 📮

* cmake invocation fixed on windows 🐝

* Can use mbedtls to calculate hmac + no openssl config option

* build only windows on travis 🕢

* run msbuild 💷

* proper command to build 🕛

* some build fixes

* change weird sizeof call 🐙

* warning and missing includes fixes 💮

* ifdef out statsd code on windows 🐍

* logic invertion in ifdef 👄

* bring back makefile 📜

* command line tool is built with mbedtls 🏥
2019-06-02 20:46:20 -07:00
17eaa323ed play with podmena 2019-06-02 11:03:44 -07:00
6177fe7803 add notes about mbedtls CMake 2019-06-01 18:00:25 -07:00
57976cf613 Feature/mbedtls (#84)
* try to import mbedtls and build it

* add stubs socket class

* some boilterplate, read and write function implemented

* more boilterplate / current error in handshake because no CA cert is setup

* add something so skip ca verification, can ws curl https://google.com !

* cleanup / close implemented

* tweak CMakefiles

* typo in include

* update readme

* disable unittests
2019-06-01 17:41:48 -07:00
977e8794ec (clang format) fix indent and make (rarely) accessor/setters in class on a single line 2019-05-31 00:53:14 -07:00
c68848eecc fix cobra to sentry + change ws docker file to use alpine (much smaller footprint) 2019-05-31 00:43:22 -07:00
c6dfb14953 clang format, based on cpprest 2019-05-30 08:46:50 -07:00
5bad02ccae std::chrono::duration is not initialized to 0 units of time 2019-05-26 14:16:15 -07:00
2e379cbf2a do not select on a closed file descriptor (doing so crash on Android) 2019-05-22 18:58:22 -07:00
0e23584751 enable IXWebSocketMessageQTest.cpp on mac and windows 2019-05-22 11:03:13 -07:00
49fd2a9e53 Clean (#82)
Thanks
2019-05-21 12:14:58 -07:00
6264a8b41d Fix ping (#80)
* let poll do his job when closing

* try fix test

* try fix test

* Update IXWebSocketTransport.cpp

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* change state immediately, and send close frame after

* add immediate close test

* disable test for windows

* reenable ping / ping timeout tests

* add time to let windows close client

* reenable ping timeout test

* add 100ms more

* disable test for windows
2019-05-21 09:35:41 -07:00
3990d3bcbf fix close bug and tests : let poll do his job when closing (#79)
* let poll do his job when closing

* try fix test

* try fix test

* Update IXWebSocketTransport.cpp

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* add log to find issue on CI

* change state immediately, and send close frame after

* add immediate close test

* disable test for windows
2019-05-21 09:34:08 -07:00
aa3f201ced one cpu on windows for executing tests 2019-05-17 15:45:31 -07:00
83c261977d add back IXWebSocketMessageQueue, with its unittest disabled 2019-05-16 22:41:39 -07:00
6ca28d96bf Linux build fix: strncpy needs <string.h> 2019-05-16 22:21:15 -07:00
c4a5647b62 Revert "Merge branch 'Dimon4eg-message-queue'"
This reverts commit 13fa325134, reversing
changes made to aecd5e9c94.
2019-05-16 22:15:17 -07:00
720d5593a5 Fix Address Sanitizer heap-buffer-overflow in WebSocketHandshakeKeyGen::generate
=================================================================
==5077==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6070000077e0 at pc 0x00010ba18c54 bp 0x70000dd45b10 sp 0x70000dd45b08
READ of size 1 at 0x6070000077e0 thread T12
    #0 0x10ba18c53 in WebSocketHandshakeKeyGen::generate(char const*, char*) libwshandshake.hpp:113
    #1 0x10ba2065a in ix::WebSocketHandshake::serverHandshake(int, int) IXWebSocketHandshake.cpp:356
    #2 0x10b9c4952 in ix::WebSocketTransport::connectToSocket(int, int) IXWebSocketTransport.cpp:190
    #3 0x10b97e4c2 in ix::WebSocket::connectToSocket(int, int) IXWebSocket.cpp:193
2019-05-16 21:59:03 -07:00
13fa325134 Merge branch 'Dimon4eg-message-queue' 2019-05-16 19:26:45 -07:00
773cbb4907 bring back socket mutex which is needed, some CI failures are happening without it 2019-05-16 19:23:32 -07:00
a696264b48 disable socket mutex usage in WebSocketTransport 2019-05-16 19:23:32 -07:00
b7db5f77fb remove dead code 2019-05-16 19:23:32 -07:00
b11678e636 refactor connect unittest so that it hits a local server instead of a remote server 2019-05-16 19:23:32 -07:00
f746070944 travis makefile fix 2019-05-16 19:23:32 -07:00
3323a51ab5 try to run ws test on linux + macOS on travis 2019-05-16 19:23:32 -07:00
0e59927384 Add constants for closing code and messages 2019-05-16 19:23:32 -07:00
5c4840f129 first socket test hit a local server instead of a remote server / this can help with a windows intermittent failure 2019-05-16 19:23:32 -07:00
9ac02323ad build ws on travis (mac + linux) 2019-05-16 19:23:32 -07:00
cdbed26d1f use a regular mutex instead of a recursive one + stop properly 2019-05-16 19:23:32 -07:00
23f171f34d adding logging to IXWebSocketTestConnectionDisconnection makes it fails reliably 2019-05-16 19:23:32 -07:00
20b625e483 Update README.md 2019-05-16 19:23:32 -07:00
f1604c6460 Update README.md 2019-05-16 19:23:32 -07:00
ba0e007c05 -j option actually work ... 2019-05-16 19:23:32 -07:00
643e1bf20f unittest / add options to set the number of jobs 2019-05-16 19:23:32 -07:00
24a32a0603 enum class HttpErrorCode derives from int 2019-05-16 19:23:32 -07:00
c5caf32b77 try to re-enable some tests 2019-05-16 19:23:32 -07:00
09956d7500 recursive mutex + enable test that was breaking on Ubuntu Xenial + gcc + tsan 2019-05-16 19:23:32 -07:00
d91c896e46 comment failing test 2019-05-16 19:23:32 -07:00
042e6a22b8 comment failing test 2019-05-16 19:23:32 -07:00
14ec12d1f0 do not build ws for now on travis 2019-05-16 19:23:32 -07:00
288b05a048 more protection against socket when closing 2019-05-16 19:23:32 -07:00
5af3096070 fix compile errors with C++ enum class 2019-05-16 19:23:32 -07:00
570fa01c04 close and stop with code and reason + docker = ubuntu xenial 2019-05-16 19:23:32 -07:00
2a69038c4c add isEnabledAutomaticReconnection (#75)
* add isEnabledAutomaticReconnection

* test isEnabledAutomaticReconnection

* rename
2019-05-16 19:23:32 -07:00
0ba127e447 Revert "Revert "fix cast warning caught on windows""
This reverts commit 25eaf730bc.
2019-05-16 19:23:32 -07:00
7714bdf7e0 Revert "fix cast warning caught on windows"
This reverts commit 4edb7447df.
2019-05-16 19:23:32 -07:00
4e5e7ae50a fix cast warning caught on windows 2019-05-16 19:23:32 -07:00
5741b2f6c1 add more time to let client close (#73) 2019-05-16 19:23:32 -07:00
76172f92e9 build with gcc on Linux 2019-05-16 19:23:32 -07:00
f8b547c028 use spdlog for logging in the unittest 2019-05-16 19:23:32 -07:00
7ccd9e1709 fix inverted conditional 2019-05-16 19:23:31 -07:00
9217b27d40 server code / add dedicated thread to close/join terminated connection threads 2019-05-16 19:23:31 -07:00
819e9025b1 travis cmake version on macOS does not know --parallel option 2019-05-16 19:23:31 -07:00
53ceab9f91 build in parallel + stop building linux + clang 2019-05-16 19:23:31 -07:00
a7ed4fe5c3 disable ping tests for now as they are not super reliable 2019-05-16 19:23:31 -07:00
3190cd322d Feature/windows ci (#76)
* close with params

* ...

* different generator

* core size = 1

* disable more tests to get something working on windows

* try to enable another test on windows

* enable all OS

* set proper version of linux

* another try

* try again with just env variables

* Revert "core size = 1"

This reverts commit 29af74bba6.

* add windows and mac

* Revert "close with params"

This reverts commit 6bb00b6788.
2019-05-16 19:23:31 -07:00
dad2b64e15 save timepoints after connect and not in contructor, adjusted tests (#72)
* save timepoints after connect and not in contructor, adjusted tests

* move call into setReadyState

* more time to detect client close in test
2019-05-16 19:20:29 -07:00
e527ab1613 fix for Windows (#69)
* fix for Windows

* fix condition

* make condition only on Windows
2019-05-16 19:20:29 -07:00
d7a0bc212d Fix run.py (#71)
* fix run.py

* run.py: fix Windows support

* fix test listing
2019-05-16 19:20:29 -07:00
aecd5e9c94 bring back socket mutex which is needed, some CI failures are happening without it 2019-05-16 15:58:20 -07:00
e0edca43d5 disable socket mutex usage in WebSocketTransport 2019-05-16 15:46:32 -07:00
ce70d3d728 remove dead code 2019-05-16 15:05:20 -07:00
d9be40a0de refactor connect unittest so that it hits a local server instead of a remote server 2019-05-16 14:25:31 -07:00
e469f04c39 travis makefile fix 2019-05-16 14:02:24 -07:00
11774e6825 try to run ws test on linux + macOS on travis 2019-05-16 13:57:33 -07:00
42bdfb51c3 Add constants for closing code and messages 2019-05-16 12:46:53 -07:00
fd637bf1e1 first socket test hit a local server instead of a remote server / this can help with a windows intermittent failure 2019-05-16 12:24:58 -07:00
8085e1416c build ws on travis (mac + linux) 2019-05-16 07:01:15 -07:00
671c9f805f use a regular mutex instead of a recursive one + stop properly 2019-05-15 19:26:02 -07:00
ace7a7ccae adding logging to IXWebSocketTestConnectionDisconnection makes it fails reliably 2019-05-15 19:26:02 -07:00
9c3bdf1a77 Update README.md 2019-05-15 19:22:05 -07:00
f5242b3102 Update README.md 2019-05-15 18:57:17 -07:00
f1272f059a -j option actually work ... 2019-05-15 18:15:45 -07:00
91595ff4c2 unittest / add options to set the number of jobs 2019-05-15 17:52:03 -07:00
3755d29a45 enum class HttpErrorCode derives from int 2019-05-15 16:50:00 -07:00
c2b75399ae try to re-enable some tests 2019-05-15 16:28:29 -07:00
a33ecd1338 recursive mutex + enable test that was breaking on Ubuntu Xenial + gcc + tsan 2019-05-15 16:01:05 -07:00
a7e29a9f36 comment failing test 2019-05-15 15:44:14 -07:00
02399dfa5c comment failing test 2019-05-15 15:37:30 -07:00
aec2941bac do not build ws for now on travis 2019-05-15 15:26:49 -07:00
9315eb5289 more protection against socket when closing 2019-05-15 15:18:46 -07:00
5b2b2ea7b0 fix compile errors with C++ enum class 2019-05-15 15:18:46 -07:00
d90b634e80 close and stop with code and reason + docker = ubuntu xenial 2019-05-15 15:18:46 -07:00
6dd8cda074 add isEnabledAutomaticReconnection (#75)
* add isEnabledAutomaticReconnection

* test isEnabledAutomaticReconnection

* rename
2019-05-14 11:26:37 -07:00
701be31554 Revert "Revert "fix cast warning caught on windows""
This reverts commit 25eaf730bc.
2019-05-13 22:16:49 -07:00
25eaf730bc Revert "fix cast warning caught on windows"
This reverts commit 4edb7447df.
2019-05-13 21:35:34 -07:00
4edb7447df fix cast warning caught on windows 2019-05-13 21:29:47 -07:00
5f3de60962 add more time to let client close (#73) 2019-05-13 21:26:34 -07:00
79c17aba49 build with gcc on Linux 2019-05-13 17:35:21 -07:00
80a90496d9 use spdlog for logging in the unittest 2019-05-13 17:32:57 -07:00
bbca803840 fix inverted conditional 2019-05-13 17:18:07 -07:00
160d3869a9 server code / add dedicated thread to close/join terminated connection threads 2019-05-13 17:17:35 -07:00
afd8f64da8 travis cmake version on macOS does not know --parallel option 2019-05-13 17:17:35 -07:00
6d2548b823 build in parallel + stop building linux + clang 2019-05-13 17:06:56 -07:00
642356d353 disable ping tests for now as they are not super reliable 2019-05-13 17:01:22 -07:00
ba0fa36c2a Feature/windows ci (#76)
* close with params

* ...

* different generator

* core size = 1

* disable more tests to get something working on windows

* try to enable another test on windows

* enable all OS

* set proper version of linux

* another try

* try again with just env variables

* Revert "core size = 1"

This reverts commit 29af74bba6.

* add windows and mac

* Revert "close with params"

This reverts commit 6bb00b6788.
2019-05-13 16:51:58 -07:00
12f6cd878d save timepoints after connect and not in contructor, adjusted tests (#72)
* save timepoints after connect and not in contructor, adjusted tests

* move call into setReadyState

* more time to detect client close in test
2019-05-13 09:08:46 -07:00
9aacebbbaf fix for Windows (#69)
* fix for Windows

* fix condition

* make condition only on Windows
2019-05-12 22:21:56 -07:00
701c3745c2 Fix run.py (#71)
* fix run.py

* run.py: fix Windows support

* fix test listing
2019-05-12 18:37:22 -07:00
a41d08343c Merge branch 'master' into message-queue 2019-05-12 22:00:10 +03:00
156288b17b all derived class use final keyword 2019-05-12 11:43:21 -07:00
6467f98241 add setOnMessageCallback with r-value 2019-05-12 20:59:18 +03:00
b24e4334f6 correct style 2019-05-12 20:16:02 +03:00
bf8abcbf4a fix warnings 2019-05-12 20:05:28 +03:00
bb484414b1 update comment 2019-05-12 20:00:15 +03:00
fc75b13fae update test 2019-05-12 19:57:31 +03:00
78f59b4207 added message queue test 2019-05-12 01:50:41 +03:00
7c5567db56 Added WebSocketMessageQueue 2019-05-12 01:49:06 +03:00
ed0e23e8a5 bump version to 2.0.0 2019-05-11 14:22:41 -07:00
4c4f99606e use C++11 enums (#67)
* use C++11 enums

* small rename

* update tests

* update tests

* update ws

* update ws

* update README.md
2019-05-11 14:22:06 -07:00
a61586c846 add comment about why a unittest is disabled 2019-05-11 12:25:40 -07:00
d64d50c978 remove irrelevant comment 2019-05-11 12:24:11 -07:00
a64b7b0c4a minor improvements (#66)
* minor improvements

* fix build

* improve tests code
2019-05-11 12:20:58 -07:00
0caeb81327 minor tweaks to have full feature parity before unittest broke 2019-05-11 11:54:21 -07:00
edac7a0171 fix race condition in SelectInteruptPipe, where _fildes are not protected (caught by fedora tsan) 2019-05-11 11:45:26 -07:00
abfadad2e9 remove more iostream includes (#65) 2019-05-11 11:27:58 -07:00
2dc1547bbd rename some variables, minor cleanup 2019-05-11 10:24:28 -07:00
5eb23c9764 uncomment test 2019-05-11 10:15:22 -07:00
9f4b2856b0 fix crash on close 2019-05-11 10:15:22 -07:00
b5fc10326e fix crash on close 2019-05-11 10:12:33 -07:00
8d3a47a873 Fix crash during closing on Windows (#64)
* fix crash on close

* Improve calculateRetryWaitMilliseconds (#63)

* improve calculateRetryWaitMilliseconds

* update comment

* cout -> spdlog

* fix crash on close

* uncomment test

* Revert "uncomment test"

This reverts commit 27df86ee8f.
2019-05-11 09:51:26 -07:00
4df58f3059 fix warning in statsd_client about %m gnu only printf special char 2019-05-11 09:22:29 -07:00
06b8cb8d3b fix overflow warning in msgpack11.cpp 2019-05-10 21:17:05 -07:00
ff81f5b496 add env var to display the ws command typed in 2019-05-10 16:27:23 -07:00
c89f73006e cout -> spdlog 2019-05-10 12:33:34 -07:00
c28951f049 Improve calculateRetryWaitMilliseconds (#63)
* improve calculateRetryWaitMilliseconds

* update comment
2019-05-10 12:31:21 -07:00
dfaaaca223 fix static analyzer thing with un-used variable 2019-05-09 16:57:58 -07:00
c7f0bf3d64 use spdlog for logging in ws + unittest + remove un-needed mutex 2019-05-09 15:30:44 -07:00
234ce4c173 cout -> cerr 2019-05-09 15:06:42 -07:00
f60293b2e7 Fixed pong synchronization issue (#62)
* Fixed pong synchronization issue

* Minor optimization in lock by scoping it to necessary changes.

* Fixing compilation issues
2019-05-09 15:06:05 -07:00
9441095637 tweak unittest sleep duration to fix gcc+linux CI 2019-05-09 11:10:39 -07:00
f82d38f758 Fail test GCC TSAN (#61)
* test that fails on Run 8

* commented the failing test
2019-05-09 09:33:18 -07:00
a7f42f35db warning police 2019-05-09 09:25:56 -07:00
cb1d1bfd85 fix ping, fix send frame close (#49)
* fix ping, fix send frame close

* fixes for data race on _closeCode etc. and fix test

* fixing one TC

* fix waiting forever if no time to change of readyState, and poll never end

* add 1005 code if no status code received

* fixes for 1005 code

* fix test issue

* fix macOS issue

* revert to master tests and renaming
2019-05-09 09:21:05 -07:00
28c3f2ea26 IXCobraMetricsThreadedPublisher.cpp uses a lambda to log instead of std::cerr 2019-05-08 18:53:32 -07:00
7ecaf1f982 rename ptr 2019-05-09 01:05:47 +03:00
d0a41f3894 simplify bindWebsocket 2019-05-09 00:23:16 +03:00
57562b234f use lock_guard 2019-05-09 00:20:26 +03:00
469d127d61 update comments 2019-05-09 00:16:37 +03:00
d6e9b61c8e Rename to WebSocketMessageQueue 2019-05-09 00:09:51 +03:00
8dc132dbd3 change default ports for the ws command line tool 2019-05-08 13:56:42 -07:00
98e2fbca6a ws connect display more accurate messages for incoming messages 2019-05-08 13:56:42 -07:00
fa7f0fadde Remove redundant iostream includes (#60) 2019-05-08 13:33:21 -07:00
7fb1b65ddd qf 2019-05-08 22:24:39 +03:00
77c7fdc636 Added IXWebSocketPoll class 2019-05-08 22:02:56 +03:00
2732dfd0f1 set thread name for Windows (#57) 2019-05-08 07:43:43 -07:00
2e4c4b72b6 update appveyor windows build file 2019-05-06 17:50:55 -07:00
fc21ad519b update README.md (#54)
Yeah !
2019-05-06 15:02:16 -07:00
c65cfd3d26 Use LUrlParser to fix issue of Windows (#53)
LGTM
2019-05-06 14:45:02 -07:00
8955462f73 added tests for IXUrlParser (#52)
* added tests for IXUrlParser

* add me as author
2019-05-06 12:47:15 -07:00
205c8c15bd socket server / used wrong mutex to protect _connectionsThreads 2019-05-06 12:24:20 -07:00
78198a0147 Fix windows (#51)
* More fixes for Windows

* fix tests for windows

* qf for linux

* clean up
2019-05-06 12:22:57 -07:00
d561e1141e Update README.md 2019-05-06 09:22:52 -07:00
753fc845ac Fix for windows (#50) 2019-05-06 09:13:42 -07:00
5dbc00bbfe doc: add reference to the conan file built at https://github.com/Zinnion/conan-IXWebSocket 2019-05-01 21:31:32 -07:00
14ec8522ef remove un-needed _backgroundThreadRunning variable 2019-05-01 11:09:25 -07:00
0c2d1c22bc Make AutomaticReconnection optional (#47)
* unittest pass + commands behave as expected

* cleanup
2019-04-29 21:12:34 -07:00
1d39a9c9a9 build fix 2019-04-29 20:54:00 -07:00
b588ed0fa1 tsan fixes on ubuntu xenial (what travis run) 2019-04-29 20:48:16 -07:00
d9f7a138b8 dns lookup: fix race condition accessing _errMsg 2019-04-29 19:29:27 -07:00
d3e04ff619 tsan linux tentative fix / copy string instead of passing a const reference 2019-04-29 17:27:53 -07:00
372dd24cc7 rename _blocking to _backgroundThreadRunning and invert the naming 2019-04-29 16:54:08 -07:00
a9422cf34d fix data race on _thread 2019-04-29 16:46:16 -07:00
c7e52e6fcd fix data race on _useMask 2019-04-29 16:41:34 -07:00
705e0823cb ws connect mode / add a flag to disable automatic reconnection, not hooked up yet 2019-04-29 14:31:29 -07:00
8e4cf74974 enable tsan on travis for all configs 2019-04-29 09:11:16 -07:00
0a7157655b initialize netSystem (aka winsock on windows) explicitely 2019-04-25 16:38:15 -07:00
58d65926bb Fixes for windows (#45)
* init Net system on Windows

* propagate DNS error

* Add zlib 1.2.11 sources

* link zlib statically for windows

* remove not implemented function declaration

* fix connect on Windows
2019-04-25 16:26:53 -07:00
b178ba16af fix indentation of greatestCommonDivisor 2019-04-25 16:21:36 -07:00
e4c09284b5 Remove commented code 2019-04-25 16:16:52 -07:00
9367a1feff Fix data race in WebSocket where _url is accessed without protection in setThreadName
Also fix with url usage + docker container uses fedora and works with tsan
2019-04-25 16:11:46 -07:00
d37ed300e2 disable failing unittest temporarily 2019-04-25 09:04:35 -07:00
3207ce37b6 Speedup build for Windows (#43)
* Speedup build for Windows

* add space :)
2019-04-25 07:41:01 -07:00
d036ad7138 tsan fix for the IXWebSocketServerTest test, where there's a data race for connectionId 2019-04-24 22:11:14 -07:00
4fe07579b9 Fix data races in DNSLookup (tsan) 2019-04-24 21:53:31 -07:00
f563d14134 better server termination / another try at preventing thread join failures 2019-04-24 09:45:53 -07:00
f1b3ecc738 compiler warning police 2019-04-24 09:45:03 -07:00
8387f89115 Fix #38 Add some docker doc in the README 2019-04-23 20:51:58 -07:00
773f92347f ws cobra publish stress mode fix 2019-04-23 20:51:58 -07:00
8ff1339b80 add boolean and add missing protocol error close constant (#41) 2019-04-23 04:31:55 -07:00
c85d5da111 add example websocket C++ server snake which supports basic cobra ops (publish and subscribe without stream sql 2019-04-22 17:33:45 -07:00
9ab7bc652a (server) attempt to fix broken macOS unittest on travis CI 2019-04-22 09:36:16 -07:00
e5c724eb05 Expand build section in the main README 2019-04-21 21:11:08 -07:00
e0300903d9 Merge branch 'dhruvkakadiya-readme/fix' 2019-04-21 16:14:35 -07:00
1ef38afcf7 For #39, fixed setOnMessageCallback() in README. 2019-04-21 14:56:02 -07:00
210d19c8a0 doc cobra 2019-04-21 11:52:38 -07:00
6d24cc44b2 new target to uninstall files 2019-04-21 11:47:57 -07:00
768e8eb074 Fix #37 / add directives to install headers and library 2019-04-21 11:42:37 -07:00
3dd902e1f9 move cobra files to their own subfolder 2019-04-21 11:20:17 -07:00
f85c5002b7 add cobra metrics publisher 2019-04-21 11:16:33 -07:00
d48bf9249b indentation / comestic changes 2019-04-19 16:57:38 -07:00
0dfc66f1c7 (test) / use a random number generator to get a free port, when the bind to port 0 strategy does not work out 2019-04-19 16:50:04 -07:00
4564173b75 (socket server) wait for all connections threads to be terminated before exiting stop method 2019-04-19 16:31:33 -07:00
b60e5aaf1f default sanitizer choice 2019-04-19 15:13:59 -07:00
da67f4cb9a disable clang sanitizers in CI on any platforms but Darwin 2019-04-19 15:09:01 -07:00
b041042473 fix Linux cast warning 2019-04-19 15:03:49 -07:00
f83263d6a1 (unittest) upgrade to Catch2 version 2.7.1 2019-04-19 14:41:03 -07:00
b0139c2217 add locks around Socket::send and Socket::recv to see if it helps with thread sanitizer error in Linux CI 2019-04-19 14:28:51 -07:00
0ba2e2ce96 uses sh syntax to capture output 2019-04-19 12:40:39 -07:00
4a91ad80c8 (ci) verbose mode to figure out Linux build problems on travis 2019-04-19 12:10:43 -07:00
4cc715b13d Windows nmake does not have a -j flag 2019-04-19 11:58:02 -07:00
0dfd7cd543 Windows + unittest python script fixes 2019-04-19 11:54:58 -07:00
56f164ce2b fix warning / ws_cobra_subscribe does not need a verbose flag 2019-04-19 11:45:42 -07:00
65db8c9b00 (test) build dir is an absolute path 2019-04-19 11:45:02 -07:00
4c4137d9f2 (ws) fix compiler warnings 2019-04-19 09:48:46 -07:00
e433e8b5e9 fix test execution on travis which was broken / unify running test locally and on travis 2019-04-19 09:46:17 -07:00
bb442021cf fix bad merge in IXWebSocketTransport.cpp ... 2019-04-19 09:41:16 -07:00
91106b7456 Socket::Poll does not need a callback 2019-04-19 09:32:49 -07:00
309b5ee1b3 Ping timeout use constant (#36)
* use constant for ping timeout

* change close code types
2019-04-19 09:16:25 -07:00
4eded01841 Link zlib statically for windows (#35)
* Add zlib 1.2.11 sources

* link zlib statically for windows
2019-04-19 09:14:03 -07:00
e3d0c899d3 fix close code/reason issue (#34)
* fix close code/reason issue

* added code 1006 for abnormal closure
2019-04-18 10:02:31 -07:00
d7595b0dd0 Real ping (#32)
* close method change and fix code

* missing mutex

* wip

* renaming and fixes

* renaming, fixes

* added enablePong/disablePong, add tests

* added new test cases

* add 1 test case

* fix gcd name to greatestCommonDivisor

* move ping and ping timeout checks into socket poll, local var in test cases and indent fixes

* indent issue
2019-04-18 09:24:16 -07:00
f0375e59fa docker container works with SSL + fix compiler warnings in statsd third_party module 2019-04-18 09:11:12 -07:00
c367435073 docker + linux build fix 2019-04-17 22:52:03 -07:00
dc812c384e setter method does not need to return anything, make it void 2019-04-17 20:36:26 -07:00
10b2d10dbd (doc) Add more doc to SocketServer 2019-04-17 20:36:26 -07:00
f96babc6a6 websocket server: closed connection threads are joined properly 2019-04-17 20:36:26 -07:00
4e2e14fb22 Bug/30 server connection problem (#31)
* use threads instead of std::async, need to cleanup threads

* less buggy server connection per thread system
2019-04-16 22:19:44 -07:00
bcf2fc1812 make closeWireSize a default parameter of WebSocketTransport::close 2019-04-16 09:55:12 -07:00
935e6791a3 close method change and fix code (#28)
* close method change and fix code

* missing mutex
2019-04-16 08:58:34 -07:00
fbb7c012a3 fix windows build (#29)
* fix windows build

* fix for Unix

* Fix build if TLS is OFF

* add OpenSSL req to ws

* Fix build on Mac

* fix tests for windows
2019-04-16 08:51:57 -07:00
dac18fcabf move security framework linking to ixwebsocket (#26) 2019-04-14 17:13:24 -07:00
d8e83caffc fix warning 2019-04-13 21:16:04 -07:00
fbf80b9f50 ws: new command to subscribe to a cobra server and send an event to a sentry server 2019-04-11 16:03:05 -07:00
c2a9139d41 (ws) add subcommands: cobra subscribe, and cobra subscribe to statsd bridge 2019-04-08 21:56:01 -07:00
6e3dff149a linux ci tentative fix 2019-04-03 22:02:10 -07:00
1bacbe38f4 better unittest runner / can run through lldb and produce a junit XML artifact 2019-03-29 15:54:05 -07:00
2e9c610ac9 Bump sleep time in test shell script 2019-03-29 09:36:56 -07:00
eb063ec60a (redis_subscribe) in verbose mode, received message gets printed with a 'received: ' header 2019-03-29 09:35:19 -07:00
37fb14646d Add clarification notice about third party modules 2019-03-29 09:34:17 -07:00
ae543518d3 offline version of remark-latest 2019-03-28 16:06:43 -07:00
c865d64608 redis conf slides 2019-03-28 14:17:19 -07:00
3004422cb6 slides 2019-03-27 16:27:52 -07:00
0c46a17443 add redis-conf slides 2019-03-27 15:53:55 -07:00
497373d976 ws redis command improvements + test script 2019-03-27 13:41:46 -07:00
91198aca0d (ws) redis_subscribe and redis_publish can take a password + display subscribe response 2019-03-26 09:33:22 -07:00
b17a5e5f0b update doc 2019-03-24 21:48:14 -07:00
3f0ef59f65 remove Formula folder
Homebrew stuff is at https://github.com/bsergean/homebrew-IXWebSocket
2019-03-24 21:43:38 -07:00
1e96edc293 (server) fix masking bug 2019-03-22 15:33:04 -07:00
0afb77393b can send TEXT message (we only support BINARY messages now) 2019-03-22 14:24:22 -07:00
7614b642bb unmasked code is broken 2019-03-22 14:24:15 -07:00
bc89580dfe remove printf + unittest fix 2019-03-22 09:56:28 -07:00
358ae13a88 (server) server should not mask data when sending to client (some python client libraries enforce that and assert) 2019-03-22 09:53:56 -07:00
ccf9dcba70 (server) HTTP response is malformed 2019-03-22 09:52:19 -07:00
94604fad61 minor cleanup 2019-03-21 13:51:25 -07:00
5c4cc7c50d HTTP/1.1 response should contains a reason (websocket server)
Fix compatibility problem with websockets python library, where the response does not contains a reason

File "/.../lib/python3.7/site-packages/websockets/http.py", line 126, in read_response
version, status_code, reason = status_line[:-2].split(b' ', 2)
ValueError: not enough values to unpack (expected 3, got 2)

The above exception was the direct cause of the following exception:

websockets.exceptions.InvalidMessage: Malformed HTTP message
2019-03-21 13:43:47 -07:00
9ed961ec06 cleanup, remove dead method 2019-03-21 10:06:59 -07:00
e6bd8cc8c4 (cmake) add a warning about 32/64 conversion problems. 2019-03-20 21:51:38 -07:00
ee25bd0f92 Feature/connection state (#25)
* (cmake) add a warning about 32/64 conversion problems.

* fix typo

* New connection state for server code + fix OpenSSL double init bug

* update README
2019-03-20 18:34:24 -07:00
e77b9176f3 Feature/redis (#23)
* Fix warning

* (cmake) add a warning about 32/64 conversion problems.

* simple redis clients

* can publish to redis

* redis subscribe

* display messages received per second

* verbose flag

* (cmake) use clang only compile option -Wshorten-64-to-32 when compiling with clang
2019-03-20 14:29:02 -07:00
afe8b966ad Fixed heartbeat typos (#22) 2019-03-19 21:31:43 -07:00
310724c961 make PollResultType an enum class 2019-03-19 09:29:57 -07:00
ceba8ae620 fix bug with isReadyToWrite 2019-03-18 22:05:04 -07:00
fead661ab7 workaround bug in Socket::isReadyToWrite 2019-03-18 20:37:33 -07:00
9c8c17f577 use milliseconds 2019-03-18 20:17:44 -07:00
a04f83930f ws / log subcommand name 2019-03-18 17:54:06 -07:00
c421d19800 disable sigpipe on osx when writing/reading into a dead pipe 2019-03-18 17:52:01 -07:00
521f02c90e edit homebrew install steps 2019-03-18 15:45:33 -07:00
c86b6074f2 add an install target 2019-03-18 15:11:08 -07:00
d5d1a2c5f4 no default parameters for isReadyToWrite and isReadyToRead 2019-03-18 14:31:21 -07:00
2a90e3f478 when trying to flush the send buffer, use select to wait until it is possible instead of using sleep to retry at a given frequency 2019-03-18 14:25:27 -07:00
1d49ba41ea Fix typo (#19) 2019-03-17 16:08:28 -07:00
e1de1f6682 remove unused gitmodule file 2019-03-17 10:38:48 -07:00
47ed5e4d4d remove unused folder 2019-03-17 10:38:19 -07:00
d77f6f5659 linux hangs when closing 2019-03-16 11:38:23 -07:00
05f0045d5d edit README 2019-03-16 11:32:46 -07:00
c4afb84f6e use pipe to abort select on Linux as well as macOS 2019-03-15 17:46:40 -07:00
b0b2f9b6d2 missing assert include on Linux 2019-03-15 11:43:27 -07:00
ee37feb489 cleanup 2019-03-15 11:41:57 -07:00
6b8337596f unittest fix 2019-03-14 18:58:16 -07:00
250665b92e linux compile fix 2019-03-14 18:55:33 -07:00
86b83c889e linux fixes 2019-03-14 18:54:47 -07:00
c9c657c07b build fix 2019-03-14 18:53:21 -07:00
4f2babaf54 select interrupt cleanup 2019-03-14 18:37:38 -07:00
1b03bf4555 linux build fix 2019-03-14 15:17:17 -07:00
977b995af9 replace uint8_t with uint64_t for the send/close requests types / use named variable to index into the _fildes array 2019-03-14 15:03:57 -07:00
310ab990bd set a default close reason string 2019-03-14 14:52:51 -07:00
d6b49b54d4 do not busy loop while sending 2019-03-14 14:48:08 -07:00
f00cf39462 remove docker folder 2019-03-14 14:48:02 -07:00
18550cf1cb send optimization + ws file transfer test 2019-03-14 14:47:53 -07:00
168918f807 Update README.md
Stop lying about Windows support ...
2019-03-13 23:10:40 -07:00
2750df8aa7 send can fail silently when sending would block (EWOULDBLOCK return for send) (#18)
* try to use a pipe for communication

* flush send buffer on the background thread

* cleanup

* linux fix / linux still use event fd for now

* cleanup
2019-03-13 23:09:45 -07:00
d6597d9f52 websocket send: make sure all data in the kernel buffer is sent 2019-03-11 22:16:55 -07:00
892ea375e3 add new message type when receiving message fragments 2019-03-11 11:12:43 -07:00
03abe77b5f ws broacast_server / can set serving hostname 2019-03-10 16:36:44 -07:00
e46eb8aa49 debian 9 unittest build fix 2019-03-10 16:07:48 -07:00
2c4862e0f1 asan test suite fix 2019-03-09 10:45:40 -08:00
fd69efa45c unittest + warning fix 2019-03-09 10:37:14 -08:00
e8aa15917f add ability to run with asan on macOS 2019-03-05 17:07:28 -08:00
b3d77f8902 fix compiler warnings in ws command line tool 2019-03-04 13:56:30 -08:00
9c3b0b08ec Socket code refactoring, plus stop polling with a 1s timeout in readBytes while we only want to poll with a 1ms timeout 2019-03-04 13:40:15 -08:00
fe7d94194c readBytes does not read bytes one by one but in chunks 2019-03-02 21:11:16 -08:00
d6c26d6aa8 create a blocking + cancellable Socket::readBytes method 2019-03-02 15:16:46 -08:00
8a74ddcd13 create a blocking + cancellable Socket::readBytes method 2019-03-02 11:01:51 -08:00
18e7189a07 more ws doc 2019-02-28 22:07:45 -08:00
785dd42c84 more ws doc 2019-02-28 22:03:48 -08:00
0cff5065d9 Feature/http (#16)
* add skeleton and broken http client code.

GET returns "Resource temporarily unavailable" errors...

* linux compile fix

* can GET some pages

* Update formatting in README.md

* unittest for sending large messages

* document bug

* Feature/send large message (#14)

* introduce send fragment

* can pass a fin frame

* can send messages which are a perfect multiple of the chunk size

* set fin only for last fragment

* cleanup

* last fragment should be of type CONTINUATION

* Add simple send and receive programs

* speedups receiving + better way to wait for thing

* receive speedup by using linked list of chunks instead of large array

* document bug

* use chunks to receive data

* trailing spaces

* Update README.md

Add note about message fragmentation.

* Feature/ws cli (#15)

* New command line tool for transfering files / still very beta.

* add readme

* use cli11 for argument parsing

* json -> msgpack

* stop using base64 and use binary which can be stored in message pack

* add target for building with homebrew

* all CMakeLists are referenced by the top level one

* add ws_chat and ws_connect sub commands to ws

* cleanup

* add echo and broadcast server as ws sub-commands

* add gitignore

* comments

* ping pong added to ws

* mv cobra_publisher under ws folder

* Update README.md

* linux build fix

* linux build fix

* move http_client to a ws sub-command

* simple HTTP post support (urlencode parameters)

* can specify extra headers

* chunk encoding / simple redirect support / -I option

* follow redirects is optional

* make README vim markdown plugin friendly

* cleanup argument parsing + add socket creation factory

* add missing file

* http gzip compression

* cleanup

* doc

* Feature/send large message (#14)

* introduce send fragment

* can pass a fin frame

* can send messages which are a perfect multiple of the chunk size

* set fin only for last fragment

* cleanup

* last fragment should be of type CONTINUATION

* Add simple send and receive programs

* speedups receiving + better way to wait for thing

* receive speedup by using linked list of chunks instead of large array

* document bug

* use chunks to receive data

* trailing spaces
2019-02-28 21:54:03 -08:00
e881b82511 Update README.md 2019-02-22 21:53:29 -08:00
d5551e5d68 mv cobra_publisher under ws folder 2019-02-22 21:51:03 -08:00
e8583000b8 ping pong added to ws 2019-02-22 21:47:57 -08:00
d642ef1a89 comments 2019-02-22 21:27:49 -08:00
2df118022d add gitignore 2019-02-22 21:26:25 -08:00
95457c8f4c add echo and broadcast server as ws sub-commands 2019-02-22 21:25:56 -08:00
0a45b7787f cleanup 2019-02-22 20:51:22 -08:00
b8c397e180 add ws_chat and ws_connect sub commands to ws 2019-02-22 20:49:26 -08:00
90105fa2b3 all CMakeLists are referenced by the top level one 2019-02-21 22:21:29 -08:00
24859fef8a add target for building with homebrew 2019-02-21 22:05:30 -08:00
73d7280723 Feature/ws cli (#15)
* New command line tool for transfering files / still very beta.

* add readme

* use cli11 for argument parsing

* json -> msgpack

* stop using base64 and use binary which can be stored in message pack
2019-02-21 21:24:53 -08:00
262de49c3c Update README.md
Add note about message fragmentation.
2019-02-21 14:08:27 -08:00
3a77e96a05 Feature/send large message (#14)
* introduce send fragment

* can pass a fin frame

* can send messages which are a perfect multiple of the chunk size

* set fin only for last fragment

* cleanup

* last fragment should be of type CONTINUATION

* Add simple send and receive programs

* speedups receiving + better way to wait for thing

* receive speedup by using linked list of chunks instead of large array

* document bug

* use chunks to receive data

* trailing spaces
2019-02-20 18:59:07 -08:00
505dd6d50f document bug 2019-02-16 10:33:37 -08:00
3f8027b65c unittest for sending large messages 2019-02-16 10:32:02 -08:00
0f2c765f45 Update formatting in README.md 2019-02-05 23:04:45 -08:00
49077f8f44 more conf in CI 2019-01-29 17:50:19 -08:00
6a23b8530f get free port that can be used by non root users (> 1024) 2019-01-28 15:24:19 -08:00
ae841af91a use dynamically generated port number to configure servers in unittest 2019-01-28 15:24:19 -08:00
44f38849b2 Merge pull request #13 from machinezone/user/bsergeant/poll
User/bsergeant/poll
2019-01-27 10:47:38 -08:00
ee12fbdb5f windows build fix 2019-01-27 10:46:02 -08:00
316c630830 constexpr to declare number of fds 2019-01-26 21:01:36 -08:00
1ea5db6110 linux fix 2019-01-26 20:57:48 -08:00
986d9a00c0 remove shutdown call 2019-01-26 20:54:23 -08:00
7a05a11014 rebase poll branch 2019-01-26 20:50:25 -08:00
f09434263c insensitive string compare when validating server connection header 2019-01-25 16:17:51 -08:00
335f594165 Merge pull request #12 from machinezone/user/bsergeant/heart-beat
Add an optional heartbeat
2019-01-25 16:14:28 -08:00
fa7ef06f4d heartbeat correct 2019-01-25 16:11:39 -08:00
3c9ec0aed0 close server socket on exit 2019-01-24 21:16:32 -08:00
c665d65cba unittest fix 2019-01-24 19:54:10 -08:00
5d4e897cc4 add an heartbeat test 2019-01-24 18:50:07 -08:00
05033714bf hearbeat 2019-01-24 12:42:49 -08:00
a02bd3f25c Update README.md 2019-01-15 09:36:43 -08:00
fdbd213fa2 check and validate the Connection: Upgrade header in client/server 2019-01-15 09:31:37 -08:00
da64d349c8 Merge pull request #10 from tonylin0826/master
Fix missing "Upgrade" header error
2019-01-15 09:22:11 -08:00
17b01a8c66 Fix missing upgrade header error 2019-01-15 15:35:37 +08:00
79dd766fab C++14 + use make_unique and make_shared to make shared pointers 2019-01-11 21:25:06 -08:00
8375b28747 add travis badge 2019-01-08 10:13:23 -08:00
e12551f309 travis -> osx 2019-01-08 10:04:47 -08:00
6102f81710 Revert "Revert "try asan on Linux"" [Back to asan on Linux]
This reverts commit 02a704a8c7.
2019-01-07 21:13:48 -08:00
9f678e5962 travis-ci: try to use clang on Linux 2019-01-07 20:49:03 -08:00
02a704a8c7 Revert "try asan on Linux"
This reverts commit dd2360ed70.
2019-01-07 20:47:25 -08:00
dd2360ed70 try asan on Linux 2019-01-07 18:29:44 -08:00
c4ab996470 build with osx on travis 2019-01-07 18:16:29 -08:00
6c54b07d92 fix simple compile error in test/IXTest.h 2019-01-07 18:08:11 -08:00
7f9bef3b8d add a travis file for real 2019-01-07 18:05:55 -08:00
12d1c5d956 add a travis file 2019-01-07 18:04:28 -08:00
e9a4bd5617 update test remote ws url 2019-01-07 11:28:53 -08:00
f34ccbfdb5 remove cmake sanitizer submodule 2019-01-07 11:26:23 -08:00
1fa75d7fb2 check select errors better 2019-01-07 11:18:00 -08:00
39140ef98c sanitizer cmake stuff 2019-01-06 18:54:16 -08:00
e30ef4a87c DNSLookup _id member does not need to be an atomic 2019-01-06 18:32:19 -08:00
9fc94f0487 DNSLookup: fix #8 2019-01-06 18:27:26 -08:00
121acdab6f DNSLookup: copy hostname and port instead of accessing member 2019-01-06 18:17:12 -08:00
6deaa03114 return false -> return -1 2019-01-06 18:10:39 -08:00
f4f30686c5 add new unittest 2019-01-06 15:14:13 -08:00
a21aae521f remove dead file 2019-01-06 14:26:11 -08:00
aed2356fc1 remove openssl testing bits for apple build 2019-01-06 14:21:49 -08:00
a478f734f6 gcc linux compile fix 2019-01-06 12:12:39 -08:00
98c579da03 make a class hierarchy for server code (IXWebSocketServer <- IXSocketServer) 2019-01-06 12:09:31 -08:00
e80def0cd0 add log 2019-01-05 21:16:13 -08:00
cc8a9e883e unittest + compiler warnings 2019-01-05 21:10:08 -08:00
4d587e35d8 windows compile fix 2019-01-05 21:02:55 -08:00
50f4fd1115 int -> ssize_t for socker recv and send 2019-01-05 20:53:50 -08:00
06d2b68696 header refactoring 2019-01-05 20:38:43 -08:00
bf6f057777 windows connect (compile fix) 2019-01-05 17:35:50 -08:00
b57c1d69f2 windows connect potential fix 2019-01-05 17:32:21 -08:00
ff265d83f9 more accurate description of errors 2019-01-05 17:18:43 -08:00
5b1c97b774 SocketTest / more debug info 2019-01-05 17:10:01 -08:00
c8c81366f7 windows (compile) fix 2019-01-05 17:04:09 -08:00
9a37fd56d1 windows fix 2019-01-05 17:02:39 -08:00
7ecaff8c5d test failure is not noticed 2019-01-05 16:30:22 -08:00
e4b0286a25 fix gcc warning 2019-01-05 16:26:11 -08:00
7ae6972306 makefile tweak 2019-01-05 14:43:21 -08:00
59cea0372b add dns lookup test 2019-01-05 14:40:17 -08:00
78d88a8520 openssl cleanup 2019-01-05 11:42:25 -08:00
273af25d57 Merge pull request #7 from bsergean/user/bsergeant/appveyor_first
unittest on appveyor
2019-01-04 17:29:23 -08:00
46d00360a8 unittest on appveyor 2019-01-04 17:28:13 -08:00
3f5935a284 windows fixes 2019-01-04 15:23:57 -08:00
c236ff66e9 Merge pull request #6 from machinezone/user/bsergeant/server
Add support for writing websocket servers (IXWebSocketServer)
2019-01-03 18:47:30 -08:00
af3df5e519 Socket::readLine works with arbitrary long lines 2019-01-03 18:47:01 -08:00
d75753ec98 timeout is configurable 2019-01-03 18:33:08 -08:00
332bb87231 remove useless FIXME comment 2019-01-03 18:02:03 -08:00
8adbcab441 new doc 2019-01-03 18:00:48 -08:00
9bc2e95196 capture path/uri when connecting, and pass it back through callbacks in the openInfo member 2019-01-03 17:44:10 -08:00
30a0aa0a0f implement a max connections (default = 32) settings 2019-01-03 17:05:44 -08:00
8622ea5cb2 correct validation of the request (request line + headers) 2019-01-03 13:41:06 -08:00
ed3a50d9b5 cancellation refactoring 2019-01-03 12:53:44 -08:00
df6a17dcc2 rename test file 2019-01-02 21:59:06 -08:00
474985e784 split handshake code into its own files, so that Transport file is less massive 2019-01-02 20:07:54 -08:00
cb904416c3 server unittest for validating client request / new timeout cancellation handling (need refactoring) 2019-01-02 16:08:32 -08:00
3e064ec63e add new broadcast server example 2019-01-02 08:17:03 -08:00
b004769552 server per message deflate support 2019-01-02 08:12:29 -08:00
17270de621 echo server example is a real echo server, not a broadcast server 2019-01-02 08:10:39 -08:00
239b5bc02c refactoring + cancellation was buggy during http upgrade 2019-01-02 07:45:07 -08:00
6bfabd5493 use select to detect new incoming connections 2019-01-01 22:21:07 -08:00
0b90f7df1b add a way to run in blocking more, which is useful for server mode to have N*thread instead of 2N*thread for N connections 2019-01-01 21:25:15 -08:00
00ca7c8fb0 more named constants 2019-01-01 19:23:27 -08:00
a11952fe22 gitignore stuff 2019-01-01 17:14:31 -08:00
06b9b2e649 linux fix + unittest works with Linux 2019-01-01 17:13:26 -08:00
dcfdcc3e1b unittest starts a server 2019-01-01 16:34:05 -08:00
b13fee16c1 crash when server failed to start 2019-01-01 16:14:46 -08:00
9a7767ecb1 thread accepting connections can be cancelled/stopped externally 2019-01-01 16:11:27 -08:00
9b82a33aff listen job run in its own thread, non blocking 2019-01-01 14:52:14 -08:00
70ef77a5d5 (nitpick) reformat 2019-01-01 14:29:57 -08:00
77903e9d90 cleanup / remove printf, add mutex, remove hardcoded values, can pass in a binding host 2019-01-01 14:28:41 -08:00
de66a87a7c use shared_ptr 2019-01-01 13:53:13 -08:00
5ea2028c22 unittest pass 2019-01-01 13:47:25 -08:00
58a68ec0be record workers in a map instead of a vector 2018-12-31 14:52:59 -08:00
a39278f7be add a print statement when the connection is closed / still need to terminate server thread 2018-12-31 12:47:42 -08:00
f8373dc666 more cleanup to propagate server connection error and let onOpen callback execute 2018-12-31 12:43:47 -08:00
3febc2431d only bind to localhost 2018-12-31 11:48:49 -08:00
0bf736831a server code has a callback that takes a websocket 2018-12-30 22:12:13 -08:00
7710bf793f cleanup / use a websocket instead of raw websockettransport 2018-12-30 22:00:49 -08:00
a6a43bd361 can accept multiple connection / server can send data back to client 2018-12-30 21:16:05 -08:00
a39209a895 proof of concept server implementation 2018-12-29 23:15:27 -08:00
24c9e0abc3 can create a socket from a fd 2018-12-29 21:53:33 -08:00
9cc324d78d add simple unittest 2018-12-29 18:34:08 -08:00
8574beceb1 add missing src files (IXSetThreadName.{cpp,h}) ... 2018-12-23 14:19:30 -08:00
0349b7f1c7 fix warning: field '_eventCallback' will be initialized after field '_publishMode' 2018-12-23 14:18:53 -08:00
ce1ba20db5 Fix warning: field '_done' will be initialized after field '_wait' [-Wreorder] _done(false), 2018-12-23 14:17:30 -08:00
395d823f41 set thread name / rename example 2018-12-23 14:14:38 -08:00
6884f9f74f async dns lookup fix 2018-12-14 17:49:42 -08:00
b34eccd749 non blocking dns lookup 2018-12-14 16:28:17 -08:00
50b638f7fd add cancellation support while connecting, to speed up WebSocket::stop 2018-12-09 17:56:20 -08:00
5bf1b91528 http upgrade and connections use non blocking sockets 2018-12-09 14:07:40 -08:00
f77ececc92 threading race condition fixes, detected by TSAN 2018-12-06 08:27:28 -08:00
58cccbdcf9 cleanup 2018-11-14 15:52:28 -08:00
5710ffba6a per-message deflate compression fixes 2018-11-13 17:46:05 -08:00
ccd4522b8f move files around 2018-11-12 17:56:59 -08:00
28f29b7385 update readme / remove reference to missing compression support now that it is supported ... 2018-11-12 09:01:42 -08:00
a7a422d6ed tweaks doc / license + send proper error code when closing the connecion 2018-11-12 09:00:55 -08:00
43fcf93584 per message deflate support (with zlib) 2018-11-09 18:42:09 -08:00
32f4c8305e (satori_publisher) better error handling 2018-11-07 14:54:44 -08:00
3cf44c8078 Add some example shell scripts to build on Linux 2018-11-07 12:33:33 -08:00
9e899fde2f Add new example folder for publishing events to satori, with a minimal satori sdk 2018-11-07 12:26:32 -08:00
ffd4f1d322 Add missing files ... 2018-11-07 12:25:38 -08:00
10dd13deb3 Add DockerFile + parse rsv1 field 2018-11-07 11:45:17 -08:00
c1ed83a005 stopping connection on Linux does not close the socket, which can create problem when re-starting the connection 2018-11-01 17:02:49 -07:00
7117c74142 add stop and start directives to ws_connect + display close info 2018-10-31 10:27:17 -07:00
dd06a3fb25 update readme.md 2018-10-27 11:46:11 -07:00
45b579447e Handle Sec-WebSocket-Accept correctly 2018-10-27 10:24:48 -07:00
bb0b1836cd capture an error code and a reason when the server closes the connection 2018-10-25 18:51:19 -07:00
d5c8815438 add doc about ping/pong 2018-10-25 15:14:31 -07:00
ac500ed079 ping pong example: more error handling 2018-10-25 14:46:23 -07:00
2bc38acbb1 ping / pong support / fix bug in dispatching received message type 2018-10-25 14:43:35 -07:00
977feae1d6 Better ping/pong support 2018-10-25 14:43:35 -07:00
9c872fcc3e New ws_connect example. Close to wscat node.js tool. 2018-10-25 14:43:35 -07:00
ec1ca3c55e Update README.md 2018-10-08 21:50:55 -07:00
16805759d3 Windows support (no TLS yet) 2018-10-08 21:44:54 -07:00
88c2e1f6de make TLS support optional 2018-10-08 15:24:36 -07:00
1dc9b559e9 move examples around 2018-10-08 15:24:36 -07:00
d31ecfc64e Update IXWebSocket.h
Remove dead code
2018-10-07 15:49:07 -07:00
4813a40f2a Update README.md
Advanced usage -> API
2018-10-07 15:47:38 -07:00
ea81470f4a more ssl peer validation stuff 2018-10-05 18:45:44 -07:00
2a6b1d5f15 Update README.md 2018-10-05 14:35:09 -07:00
95 changed files with 1125 additions and 4159 deletions

View File

@ -2,7 +2,6 @@ name: C/C++ CI
on: [push]
# fake comment to trigger an action 1
jobs:
linux:
runs-on: ubuntu-latest
@ -17,16 +16,16 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: install redis
run: brew install redis
- name: start redis server
run: brew services start redis
- name: make test
run: make test
# We don't need to have redis running anymore, as we have our fake limited one
# - name: install redis
# run: brew install redis
#
# - name: start redis server
# run: brew services start redis
# # Windows does not work yet, I'm stuck at getting CMake to run + finding vcpkg
# win:
# runs-on: windows-2016

View File

@ -113,24 +113,22 @@ else()
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSelectInterruptEventFd.h)
endif()
option(USE_TLS "Enable TLS support" FALSE)
if (WIN32)
set(USE_MBED_TLS TRUE)
endif()
if (USE_TLS)
if (WIN32)
option(USE_MBED_TLS "Use Mbed TLS" ON)
else()
option(USE_MBED_TLS "Use Mbed TLS" OFF)
endif()
option(USE_OPEN_SSL "Use OpenSSL" OFF)
if (USE_MBED_TLS)
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketMbedTLS.h)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketMbedTLS.cpp)
elseif (APPLE AND NOT USE_OPEN_SSL)
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketAppleSSL.h)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketAppleSSL.cpp)
elseif (WIN32)
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketSChannel.h)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketSChannel.cpp)
else()
set(USE_OPEN_SSL ON)
set(USE_OPEN_SSL TRUE)
list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketOpenSSL.h)
list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketOpenSSL.cpp)
endif()
@ -147,15 +145,19 @@ if (USE_TLS)
target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_MBED_TLS)
elseif (USE_OPEN_SSL)
target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_OPEN_SSL)
elseif (APPLE)
elseif (WIN32)
else()
target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_OPEN_SSL)
endif()
endif()
if (APPLE AND USE_TLS AND NOT USE_MBED_TLS AND NOT USE_OPEN_SSL)
if (APPLE AND USE_TLS AND NOT USE_MBED_TLS)
target_link_libraries(ixwebsocket "-framework foundation" "-framework security")
endif()
if (WIN32)
target_link_libraries(ixwebsocket wsock32 ws2_32 shlwapi)
target_link_libraries(ixwebsocket wsock32 ws2_32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
@ -172,9 +174,7 @@ if (USE_TLS AND USE_OPEN_SSL)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/opt/openssl/include)
endif()
if(NOT OPENSSL_FOUND)
find_package(OpenSSL REQUIRED)
endif()
find_package(OpenSSL REQUIRED)
add_definitions(${OPENSSL_DEFINITIONS})
message(STATUS "OpenSSL: " ${OPENSSL_VERSION})
include_directories(${OPENSSL_INCLUDE_DIR})
@ -207,7 +207,7 @@ else()
endif()
set( IXWEBSOCKET_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
.
)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")

View File

@ -1 +0,0 @@
docker/Dockerfile.centos

35
Dockerfile Normal file
View File

@ -0,0 +1,35 @@
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
RUN apk add --no-cache zlib-dev
RUN addgroup -S app && adduser -S -G app app
RUN chown -R app:app /opt
RUN chown -R app:app /usr/local
# There is a bug in CMake where we cannot build from the root top folder
# So we build from /opt
COPY --chown=app:app . /opt
WORKDIR /opt
USER app
RUN [ "make", "ws_install" ]
FROM alpine:3.11 as runtime
RUN apk add --no-cache libstdc++
RUN apk add --no-cache strace
RUN addgroup -S app && adduser -S -G app app
COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws
RUN chmod +x /usr/local/bin/ws
RUN ldd /usr/local/bin/ws
# Now run in usermode
USER app
WORKDIR /home/app
ENTRYPOINT ["ws"]
EXPOSE 8008
CMD ["--help"]

View File

@ -38,10 +38,4 @@ Interested? Go read the [docs](https://machinezone.github.io/IXWebSocket/)! If t
IXWebSocket is actively being developed, check out the [changelog](https://machinezone.github.io/IXWebSocket/CHANGELOG/) to know what's cooking. If you are looking for a real time messaging service (the chat-like 'server' your websocket code will talk to) with many features such as history, backed by Redis, look at [cobra](https://github.com/machinezone/cobra).
IXWebSocket client code is autobahn compliant beginning with the 6.0.0 version. See the current [test results](https://bsergean.github.io/autobahn/reports/clients/index.html). Some tests are still failing in the server code.
## Users
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)
IXWebSocket client code is autobahn compliant beginning with the 6.0.0 version. See the current [test results](https://bsergean.github.io/IXWebSocket/autobahn/index.html). Some tests are still failing in the server code.

View File

@ -1,4 +1,4 @@
FROM alpine:3.11 as build
FROM alpine as build
RUN apk add --no-cache gcc g++ musl-dev linux-headers cmake openssl-dev
RUN apk add --no-cache make
@ -15,25 +15,20 @@ WORKDIR /opt
USER app
RUN [ "make", "ws_install" ]
RUN [ "rm", "-rf", "build" ]
FROM alpine:3.11 as runtime
FROM alpine as runtime
RUN apk add --no-cache libstdc++
RUN apk add --no-cache strace
RUN apk add --no-cache gdb
RUN addgroup -S app && adduser -S -G app app
COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws
RUN chmod +x /usr/local/bin/ws
RUN ldd /usr/local/bin/ws
# Copy source code for gcc
COPY --chown=app:app --from=build /opt /opt
# Now run in usermode
USER app
WORKDIR /home/app
ENTRYPOINT ["ws"]
EXPOSE 8008
CMD ["--help"]

View File

@ -1,35 +0,0 @@
FROM centos:8 as build
RUN yum install -y gcc-c++ make cmake zlib-devel openssl-devel redhat-rpm-config
RUN groupadd app && useradd -g app app
RUN chown -R app:app /opt
RUN chown -R app:app /usr/local
# There is a bug in CMake where we cannot build from the root top folder
# So we build from /opt
COPY --chown=app:app . /opt
WORKDIR /opt
USER app
RUN [ "make", "ws_install" ]
RUN [ "rm", "-rf", "build" ]
FROM centos:8 as runtime
RUN yum install -y gdb strace
RUN groupadd app && useradd -g app app
COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws
RUN chmod +x /usr/local/bin/ws
RUN ldd /usr/local/bin/ws
# Copy source code for gcc
COPY --chown=app:app --from=build /opt /opt
# Now run in usermode
USER app
WORKDIR /home/app
ENTRYPOINT ["ws"]
EXPOSE 8008

View File

@ -1,129 +1,13 @@
# Changelog
All changes to this project will be documented in this file.
## [8.1.3] - 2020-02-21
(client + server) Fix #155 / http header parser should treat the space(s) after the : delimiter as optional. Fixing this bug made us discover that websocket sub-protocols are not properly serialiazed, but start with a ,
## [8.1.2] - 2020-02-18
(WebSocketServer) add option to disable deflate compression, exposed with the -x option to ws echo_server
## [8.1.1] - 2020-02-18
(ws cobra to statsd and sentry sender) exit if no messages are received for one minute, which is a sign that something goes wrong on the server side. That should be changed to be configurable in the future
## [8.1.0] - 2020-02-13
(http client + sentry minidump upload) Multipart stream closing boundary is invalid + mark some options as mandatory in the command line tools
## [8.0.7] - 2020-02-12
(build) remove the unused subtree which was causing some way of installing to break
## [8.0.6] - 2020-01-31
(snake) add an option to disable answering pongs as response to pings, to test cobra client behavior with hanged connections
## [8.0.5] - 2020-01-31
(IXCobraConnection) set a ping timeout of 90 seconds. If no pong messages are received as responses to ping for a while, give up and close the connection
## [8.0.4] - 2020-01-31
(cobra to sentry) remove noisy logging
## [8.0.3] - 2020-01-30
(ixcobra) check if we are authenticated in publishNext before trying to publish a message
## [8.0.2] - 2020-01-28
Extract severity level when emitting messages to sentry
## [8.0.1] - 2020-01-28
Fix bug #151 - If a socket connection is interrupted, calling stop() on the IXWebSocket object blocks until the next retry
## [8.0.0] - 2020-01-26
(SocketServer) add ability to bind on an ipv6 address
## [7.9.6] - 2020-01-22
(ws) add a dnslookup sub-command, to get the ip address of a remote host
## [7.9.5] - 2020-01-14
(windows) fix #144, get rid of stubbed/un-implemented windows schannel ssl backend
## [7.9.4] - 2020-01-12
(openssl + mbedssl) fix #140, can send large files with ws send over ssl / still broken with apple ssl
## [7.9.3] - 2020-01-10
(apple ssl) model write method after the OpenSSL one for consistency
## [7.9.2] - 2020-01-06
(apple ssl) unify read and write ssl utility code
## [7.9.1] - 2020-01-06
(websocket client) better error propagation when errors are detected while sending data
(ws send) detect failures to send big files, terminate in those cases and report error
## [7.9.0] - 2020-01-04
(ws send) add option (-x) to disable per message deflate compression
## [7.8.9] - 2020-01-04
(ws send + receive) handle all message types (ping + pong + fragment) / investigate #140
## [7.8.8] - 2019-12-28
(mbedtls) fix related to private key file parsing and initialization
## [7.8.6] - 2019-12-28
(ws cobra to sentry/statsd) fix for handling null events properly for empty queues + use queue to send data to statsd
## [7.8.5] - 2019-12-28
(ws cobra to sentry) handle null events for empty queues
## [7.8.4] - 2019-12-27
(ws cobra to sentry) game is picked in a fair manner, so that all games get the same share of sent events
## [7.8.3] - 2019-12-27
(ws cobra to sentry) refactor queue related code into a class
## [7.8.2] - 2019-12-25
(ws cobra to sentry) bound the queue size used to hold up cobra messages before they are sent to sentry. Default queue size is a 100 messages. Without such limit the program runs out of memory when a subscriber receive a lot of messages that cannot make it to sentry
## [7.8.1] - 2019-12-25
(ws client) use correct compilation defines so that spdlog is not used as a header only library (reduce binary size and increase compilation speed)
## [7.8.0] - 2019-12-24
(ws client) all commands use spdlog instead of std::cerr or std::cout for logging
## [7.6.5] - 2019-12-24
(cobra client) send a websocket ping every 30s to keep the connection opened
## [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

View File

@ -23,16 +23,6 @@ Options for building:
If you are on Windows, look at the [appveyor](https://github.com/machinezone/IXWebSocket/blob/master/appveyor.yml) file that has instructions for building dependencies.
It is also possible to externally include the project, so that everything is fetched over the wire when you build like so:
```
ExternalProject_Add(
IXWebSocket
GIT_REPOSITORY https://github.com/machinezone/IXWebSocket.git
...
)
```
### vcpkg
It is possible to get IXWebSocket through Microsoft [vcpkg](https://github.com/microsoft/vcpkg).
@ -43,16 +33,11 @@ vcpkg install ixwebsocket
### Conan
[ ![Download](https://api.bintray.com/packages/conan/conan-center/ixwebsocket%3A_/images/download.svg) ](https://bintray.com/conan/conan-center/ixwebsocket%3A_/_latestVersion)
Support for building with conan was contributed by Olivia Zoe (thanks!). The package name to reference is `IXWebSocket/5.0.0@LunarWatcher/stable`, and a list of the uploaded versions is available on [Bintray](https://bintray.com/oliviazoe0/conan-packages/IXWebSocket%3ALunarWatcher). The package is in the process to be published to the official conan package repo, but in the meantime, it can be accessed by adding a new remote
Conan is currently supported through a recipe in [Conan Center](https://github.com/conan-io/conan-center-index/tree/master/recipes/ixwebsocket) ([Bintray entry](https://bintray.com/conan/conan-center/ixwebsocket%3A_)).
Package reference
* Conan 1.21.0 and up: `ixwebsocket/7.9.2`
* Earlier versions: `ixwebsocket/7.9.2@_/_`
Note that the version listed here might not be the latest one. See Bintray or the recipe itself for the latest version. If you're migrating from the previous, custom Bintray remote, note that the package reference _has_ to be lower-case.
```
conan remote add remote_name_here https://api.bintray.com/conan/oliviazoe0/conan-packages
```
### Docker

View File

@ -24,7 +24,6 @@ namespace ix
PublishTrackerCallback CobraConnection::_publishTrackerCallback = nullptr;
constexpr size_t CobraConnection::kQueueMaxSize;
constexpr CobraConnection::MsgId CobraConnection::kInvalidMsgId;
constexpr int CobraConnection::kPingIntervalSecs;
CobraConnection::CobraConnection() :
_webSocket(new WebSocket()),
@ -229,10 +228,6 @@ namespace ix
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
invokeErrorCallback(ss.str(), std::string());
}
else if (msg->type == ix::WebSocketMessageType::Pong)
{
invokeEventCallback(ix::CobraConnection_EventType_Pong);
}
});
}
@ -265,15 +260,6 @@ namespace ix
_webSocket->setUrl(url);
_webSocket->setPerMessageDeflateOptions(webSocketPerMessageDeflateOptions);
_webSocket->setTLSOptions(socketTLSOptions);
// Send a websocket ping every N seconds (N = 30) now
// This should keep the connection open and prevent some load balancers such as
// the Amazon one from shutting it down
_webSocket->setPingInterval(kPingIntervalSecs);
// If we don't receive a pong back, declare loss after 3 * N seconds
// (will be 90s now), and close and restart the connection
_webSocket->setPingTimeout(3 * kPingIntervalSecs);
}
//
@ -514,7 +500,7 @@ namespace ix
if (_messageQueue.empty()) return true;
auto&& msg = _messageQueue.back();
if (!_authenticated || !publishMessage(msg))
if (!publishMessage(msg))
{
return false;
}

View File

@ -30,8 +30,7 @@ namespace ix
CobraConnection_EventType_Closed = 3,
CobraConnection_EventType_Subscribed = 4,
CobraConnection_EventType_UnSubscribed = 5,
CobraConnection_EventType_Published = 6,
CobraConnection_EventType_Pong = 7
CobraConnection_EventType_Published = 6
};
enum CobraConnectionPublishMode
@ -216,9 +215,6 @@ namespace ix
// Each pdu sent should have an incremental unique id
std::atomic<uint64_t> _id;
// Frequency at which we send a websocket ping to the backing cobra connection
static constexpr int kPingIntervalSecs = 30;
};
} // namespace ix

View File

@ -65,10 +65,6 @@ namespace ix
{
ss << "Published message " << msgId << " acked";
}
else if (eventType == ix::CobraConnection_EventType_Pong)
{
ss << "Received websocket pong";
}
ix::IXCoreLogger::Log(ss.str().c_str());
});

View File

@ -166,17 +166,6 @@ namespace ix
tags.append(tag);
}
}
if (msg["data"]["info"].isMember("level_str"))
{
// https://docs.sentry.io/enriching-error-data/context/?platform=python#setting-the-level
std::string level = msg["data"]["info"]["level_str"].asString();
if (level == "critical")
{
level = "fatal";
}
payload["level"] = level;
}
}
else
{

View File

@ -32,7 +32,6 @@ namespace snake
// Misc
bool verbose;
bool disablePong;
};
bool isAppKeyValid(const AppConfig& appConfig, std::string appkey);

View File

@ -17,8 +17,8 @@
namespace ix
{
RedisServer::RedisServer(int port, const std::string& host, int backlog, size_t maxConnections, int addressFamily)
: SocketServer(port, host, backlog, maxConnections, addressFamily)
RedisServer::RedisServer(int port, const std::string& host, int backlog, size_t maxConnections)
: SocketServer(port, host, backlog, maxConnections)
, _connectedClientsCount(0)
, _stopHandlingConnections(false)
{

View File

@ -25,8 +25,7 @@ namespace ix
RedisServer(int port = SocketServer::kDefaultPort,
const std::string& host = SocketServer::kDefaultHost,
int backlog = SocketServer::kDefaultTcpBacklog,
size_t maxConnections = SocketServer::kDefaultMaxConnections,
int addressFamily = SocketServer::kDefaultAddressFamily);
size_t maxConnections = SocketServer::kDefaultMaxConnections);
virtual ~RedisServer();
virtual void stop() final;

View File

@ -21,15 +21,6 @@ namespace snake
, _server(appConfig.port, appConfig.hostname)
{
_server.setTLSOptions(appConfig.socketTLSOptions);
if (appConfig.disablePong)
{
_server.disablePong();
}
std::stringstream ss;
ss << "Listening on " << appConfig.hostname << ":" << appConfig.port;
ix::IXCoreLogger::Log(ss.str().c_str());
}
//

View File

@ -648,7 +648,7 @@ namespace ix
<< it.second << "\r\n";
}
ss << "--" << multipartBoundary << "--\r\n";
ss << "--" << multipartBoundary << "\r\n";
return ss.str();
}

View File

@ -10,6 +10,7 @@
#include "IXSocketConnect.h"
#include "IXUserAgent.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
@ -42,9 +43,8 @@ namespace
namespace ix
{
HttpServer::HttpServer(
int port, const std::string& host, int backlog, size_t maxConnections, int addressFamily)
: SocketServer(port, host, backlog, maxConnections, addressFamily)
HttpServer::HttpServer(int port, const std::string& host, int backlog, size_t maxConnections)
: SocketServer(port, host, backlog, maxConnections)
, _connectedClientsCount(0)
{
setDefaultConnectionCallback();

View File

@ -28,8 +28,7 @@ namespace ix
HttpServer(int port = SocketServer::kDefaultPort,
const std::string& host = SocketServer::kDefaultHost,
int backlog = SocketServer::kDefaultTcpBacklog,
size_t maxConnections = SocketServer::kDefaultMaxConnections,
int addressFamily = SocketServer::kDefaultAddressFamily);
size_t maxConnections = SocketServer::kDefaultMaxConnections);
virtual ~HttpServer();
virtual void stop() final;

View File

@ -7,9 +7,9 @@
#include "IXSelectInterruptFactory.h"
#if defined(__linux__) || defined(__APPLE__)
#include "IXSelectInterruptPipe.h"
#include <ixwebsocket/IXSelectInterruptPipe.h>
#else
#include "IXSelectInterrupt.h"
#include <ixwebsocket/IXSelectInterrupt.h>
#endif
namespace ix

View File

@ -54,17 +54,14 @@ namespace ix
// to ::poll does fix that.
//
// However poll isn't as portable as select and has bugs on Windows, so we
// have a shim to fallback to select on those platforms. See
// should write a shim to fallback to select on those platforms. See
// https://github.com/mpv-player/mpv/pull/5203/files for such a select wrapper.
//
nfds_t nfds = 1;
struct pollfd fds[2];
memset(fds, 0, sizeof(fds));
fds[0].fd = sockfd;
fds[0].events = (readyToRead) ? POLLIN : POLLOUT;
// this is ignored by poll, but our select based poll wrapper on Windows needs it
fds[0].events |= POLLERR;
// File descriptor used to interrupt select when needed
@ -135,11 +132,6 @@ namespace ix
}
#endif
}
else if (sockfd != -1 && (fds[0].revents & POLLERR || fds[0].revents & POLLHUP ||
fds[0].revents & POLLNVAL))
{
pollResult = PollResultType::Error;
}
return pollResult;
}

View File

@ -73,7 +73,7 @@ namespace ix
virtual void close();
virtual ssize_t send(char* buffer, size_t length);
ssize_t send(const std::string& buffer);
virtual ssize_t send(const std::string& buffer);
virtual ssize_t recv(void* buffer, size_t length);
// Blocking and cancellable versions, working with socket that can be set

View File

@ -24,22 +24,88 @@
#include <Security/SecureTransport.h>
namespace ix
namespace
{
SocketAppleSSL::SocketAppleSSL(const SocketTLSOptions& tlsOptions, int fd)
: Socket(fd)
, _sslContext(nullptr)
, _tlsOptions(tlsOptions)
OSStatus read_from_socket(SSLConnectionRef connection, void* data, size_t* len)
{
;
int fd = (int) (long) connection;
if (fd < 0) return errSSLInternal;
assert(data != nullptr);
assert(len != nullptr);
size_t requested_sz = *len;
ssize_t status = read(fd, data, requested_sz);
if (status > 0)
{
*len = (size_t) status;
if (requested_sz > *len)
return errSSLWouldBlock;
else
return noErr;
}
else if (0 == status)
{
*len = 0;
return errSSLClosedGraceful;
}
else
{
*len = 0;
switch (errno)
{
case ENOENT: return errSSLClosedGraceful;
case EAGAIN: return errSSLWouldBlock;
case ECONNRESET: return errSSLClosedAbort;
default: return errSecIO;
}
}
}
SocketAppleSSL::~SocketAppleSSL()
OSStatus write_to_socket(SSLConnectionRef connection, const void* data, size_t* len)
{
SocketAppleSSL::close();
int fd = (int) (long) connection;
if (fd < 0) return errSSLInternal;
assert(data != nullptr);
assert(len != nullptr);
size_t to_write_sz = *len;
ssize_t status = write(fd, data, to_write_sz);
if (status > 0)
{
*len = (size_t) status;
if (to_write_sz > *len)
return errSSLWouldBlock;
else
return noErr;
}
else if (0 == status)
{
*len = 0;
return errSSLClosedGraceful;
}
else
{
*len = 0;
if (EAGAIN == errno)
{
return errSSLWouldBlock;
}
else
{
return errSecIO;
}
}
}
std::string SocketAppleSSL::getSSLErrorDescription(OSStatus status)
std::string getSSLErrorDescription(OSStatus status)
{
std::string errMsg("Unknown SSL error.");
@ -64,99 +130,120 @@ namespace ix
return errMsg;
}
OSStatus SocketAppleSSL::readFromSocket(SSLConnectionRef connection, void* data, size_t* len)
#undef CURL_BUILD_IOS
OSStatus CopyIdentityFromPKCS12File(
const char *cPath,
const char *cPassword,
SecIdentityRef *out_cert_and_key)
{
int fd = (int) (long) connection;
if (fd < 0) return errSSLInternal;
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;
assert(data != nullptr);
assert(len != nullptr);
/* 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;
size_t requested_sz = *len;
/* 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);
ssize_t status = read(fd, data, requested_sz);
if (status > 0)
{
*len = (size_t) status;
if (requested_sz > *len)
{
return errSSLWouldBlock;
if (options != NULL) {
status = SecPKCS12Import(pkcs_data, options, &items);
CFRelease(options);
}
else
/* 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))
{
return noErr;
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;
}
}
}
}
else if (status == 0)
{
*len = 0;
return errSSLClosedGraceful;
}
else
{
*len = 0;
switch (errno)
{
case ENOENT: return errSSLClosedGraceful;
case EAGAIN: return errSSLWouldBlock; // EWOULDBLOCK is a define for EAGAIN on osx
case EINPROGRESS: return errSSLWouldBlock;
case ECONNRESET: return errSSLClosedAbort;
default: return errSecIO;
}
if (items) CFRelease(items);
CFRelease(pkcs_data);
}
if (password) CFRelease(password);
CFRelease(pkcs_url);
return status;
}
OSStatus SocketAppleSSL::writeToSocket(SSLConnectionRef connection,
const void* data,
size_t* len)
} // anonymous namespace
namespace ix
{
SocketAppleSSL::SocketAppleSSL(const SocketTLSOptions& tlsOptions, int fd)
: Socket(fd)
, _sslContext(nullptr)
, _tlsOptions(tlsOptions)
{
int fd = (int) (long) connection;
if (fd < 0) return errSSLInternal;
assert(data != nullptr);
assert(len != nullptr);
size_t to_write_sz = *len;
ssize_t status = write(fd, data, to_write_sz);
if (status > 0)
{
*len = (size_t) status;
if (to_write_sz > *len)
{
return errSSLWouldBlock;
}
else
{
return noErr;
}
}
else if (status == 0)
{
*len = 0;
return errSSLClosedGraceful;
}
else
{
*len = 0;
switch (errno)
{
case ENOENT: return errSSLClosedGraceful;
case EAGAIN: return errSSLWouldBlock; // EWOULDBLOCK is a define for EAGAIN on osx
case EINPROGRESS: return errSSLWouldBlock;
case ECONNRESET: return errSSLClosedAbort;
default: return errSecIO;
}
}
;
}
SocketAppleSSL::~SocketAppleSSL()
{
SocketAppleSSL::close();
}
bool SocketAppleSSL::accept(std::string& errMsg)
{
@ -164,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,
@ -179,12 +323,13 @@ namespace ix
_sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
SSLSetIOFuncs(
_sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket);
SSLSetIOFuncs(_sslContext, read_from_socket, write_to_socket);
SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd);
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);
@ -193,7 +338,7 @@ namespace ix
do
{
status = SSLHandshake(_sslContext);
} while (status == errSSLWouldBlock || status == errSSLServerAuthCompleted);
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
if (status == errSSLServerAuthCompleted)
{
@ -201,7 +346,7 @@ namespace ix
do
{
status = SSLHandshake(_sslContext);
} while (status == errSSLWouldBlock || status == errSSLServerAuthCompleted);
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
}
}
else
@ -209,11 +354,11 @@ namespace ix
do
{
status = SSLHandshake(_sslContext);
} while (status == errSSLWouldBlock || status == errSSLServerAuthCompleted);
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
}
}
if (status != noErr)
if (noErr != status)
{
errMsg = getSSLErrorDescription(status);
close();
@ -238,38 +383,32 @@ namespace ix
ssize_t SocketAppleSSL::send(char* buf, size_t nbyte)
{
OSStatus status = errSSLWouldBlock;
while (status == errSSLWouldBlock)
ssize_t ret = 0;
OSStatus status;
do
{
size_t processed = 0;
std::lock_guard<std::mutex> lock(_mutex);
status = SSLWrite(_sslContext, buf, nbyte, &processed);
ret += processed;
buf += processed;
nbyte -= processed;
} while (nbyte > 0 && errSSLWouldBlock == status);
if (processed > 0) return (ssize_t) processed;
if (ret == 0 && errSSLClosedAbort != status) ret = -1;
return ret;
}
// The connection was reset, inform the caller that this
// Socket should close
if (status == errSSLClosedGraceful || status == errSSLClosedNoNotify ||
status == errSSLClosedAbort)
{
errno = ECONNRESET;
return -1;
}
if (status == errSSLWouldBlock)
{
errno = EWOULDBLOCK;
return -1;
}
}
return -1;
ssize_t SocketAppleSSL::send(const std::string& buffer)
{
return send((char*) &buffer[0], buffer.size());
}
// No wait support
ssize_t SocketAppleSSL::recv(void* buf, size_t nbyte)
{
OSStatus status = errSSLWouldBlock;
while (status == errSSLWouldBlock)
while (errSSLWouldBlock == status)
{
size_t processed = 0;
std::lock_guard<std::mutex> lock(_mutex);

View File

@ -30,12 +30,11 @@ namespace ix
virtual void close() final;
virtual ssize_t send(char* buffer, size_t length) final;
virtual ssize_t send(const std::string& buffer) final;
virtual ssize_t recv(void* buffer, size_t length) final;
private:
static std::string getSSLErrorDescription(OSStatus status);
static OSStatus writeToSocket(SSLConnectionRef connection, const void* data, size_t* len);
static OSStatus readFromSocket(SSLConnectionRef connection, void* data, size_t* len);
bool handleTLSOptions(std::string& errMsg);
SSLContextRef _sslContext;
mutable std::mutex _mutex; // AppleSSL routines are not thread-safe

View File

@ -9,16 +9,18 @@
#ifdef IXWEBSOCKET_USE_TLS
#ifdef IXWEBSOCKET_USE_MBED_TLS
#include "IXSocketMbedTLS.h"
#include <ixwebsocket/IXSocketMbedTLS.h>
#elif defined(_WIN32)
#include <ixwebsocket/IXSocketSChannel.h>
#elif defined(IXWEBSOCKET_USE_OPEN_SSL)
#include "IXSocketOpenSSL.h"
#include <ixwebsocket/IXSocketOpenSSL.h>
#elif __APPLE__
#include "IXSocketAppleSSL.h"
#include <ixwebsocket/IXSocketAppleSSL.h>
#endif
#else
#include "IXSocket.h"
#include <ixwebsocket/IXSocket.h>
#endif
@ -44,6 +46,8 @@ namespace ix
socket = std::make_shared<SocketMbedTLS>(tlsOptions, fd);
#elif defined(IXWEBSOCKET_USE_OPEN_SSL)
socket = std::make_shared<SocketOpenSSL>(tlsOptions, fd);
#elif defined(_WIN32)
socket = std::make_shared<SocketSChannel>(tlsOptions, fd);
#elif defined(__APPLE__)
socket = std::make_shared<SocketAppleSSL>(tlsOptions, fd);
#endif

View File

@ -39,7 +39,6 @@ namespace ix
mbedtls_entropy_init(&_entropy);
mbedtls_x509_crt_init(&_cacert);
mbedtls_x509_crt_init(&_cert);
mbedtls_pk_init(&_pkey);
}
bool SocketMbedTLS::init(const std::string& host, bool isClient, std::string& errMsg)
@ -82,11 +81,6 @@ namespace ix
errMsg = "Cannot parse key file '" + _tlsOptions.keyFile + "'";
return false;
}
if (mbedtls_ssl_conf_own_cert(&_conf, &_cert, &_pkey) < 0)
{
errMsg = "Problem configuring cert '" + _tlsOptions.certFile + "'";
return false;
}
}
if (_tlsOptions.isPeerVerifyDisabled())
@ -110,6 +104,11 @@ namespace ix
}
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)
@ -230,23 +229,35 @@ namespace ix
ssize_t SocketMbedTLS::send(char* buf, size_t nbyte)
{
std::lock_guard<std::mutex> lock(_mutex);
ssize_t sent = 0;
ssize_t res = mbedtls_ssl_write(&_ssl, (unsigned char*) buf, nbyte);
while (nbyte > 0)
{
std::lock_guard<std::mutex> lock(_mutex);
if (res > 0)
{
return res;
}
else if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE)
{
errno = EWOULDBLOCK;
return -1;
}
else
{
return -1;
ssize_t res = mbedtls_ssl_write(&_ssl, (unsigned char*) buf, nbyte);
if (res > 0)
{
nbyte -= res;
sent += res;
}
else if (res == MBEDTLS_ERR_SSL_WANT_READ || res == MBEDTLS_ERR_SSL_WANT_WRITE)
{
errno = EWOULDBLOCK;
return -1;
}
else
{
return -1;
}
}
return sent;
}
ssize_t SocketMbedTLS::send(const std::string& buffer)
{
return send((char*) &buffer[0], buffer.size());
}
ssize_t SocketMbedTLS::recv(void* buf, size_t nbyte)

View File

@ -35,6 +35,7 @@ namespace ix
virtual void close() final;
virtual ssize_t send(char* buffer, size_t length) final;
virtual ssize_t send(const std::string& buffer) final;
virtual ssize_t recv(void* buffer, size_t length) final;
private:

View File

@ -11,14 +11,8 @@
#include "IXSocketConnect.h"
#include <cassert>
#include <errno.h>
#ifdef _WIN32
#include <Shlwapi.h>
#else
#include <fnmatch.h>
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#include <openssl/x509v3.h>
#endif
#define socketerrno errno
namespace ix
@ -142,11 +136,7 @@ namespace ix
*/
bool SocketOpenSSL::checkHost(const std::string& host, const char* pattern)
{
#ifdef _WIN32
return PathMatchSpecA(host.c_str(), pattern);
#else
return fnmatch(pattern, host.c_str(), 0) != FNM_NOMATCH;
#endif
}
bool SocketOpenSSL::openSSLCheckServerCert(SSL* ssl,
@ -603,30 +593,42 @@ namespace ix
ssize_t SocketOpenSSL::send(char* buf, size_t nbyte)
{
std::lock_guard<std::mutex> lock(_mutex);
ssize_t sent = 0;
if (_ssl_connection == nullptr || _ssl_context == nullptr)
while (nbyte > 0)
{
return 0;
}
std::lock_guard<std::mutex> lock(_mutex);
ERR_clear_error();
ssize_t write_result = SSL_write(_ssl_connection, buf, (int) nbyte);
int reason = SSL_get_error(_ssl_connection, (int) write_result);
if (_ssl_connection == nullptr || _ssl_context == nullptr)
{
return 0;
}
if (reason == SSL_ERROR_NONE)
{
return write_result;
}
else if (reason == SSL_ERROR_WANT_READ || reason == SSL_ERROR_WANT_WRITE)
{
errno = EWOULDBLOCK;
return -1;
}
else
{
return -1;
ERR_clear_error();
ssize_t write_result = SSL_write(_ssl_connection, buf + sent, (int) nbyte);
int reason = SSL_get_error(_ssl_connection, (int) write_result);
if (reason == SSL_ERROR_NONE)
{
nbyte -= write_result;
sent += write_result;
}
else if (reason == SSL_ERROR_WANT_READ || reason == SSL_ERROR_WANT_WRITE)
{
errno = EWOULDBLOCK;
return -1;
}
else
{
return -1;
}
}
return sent;
}
ssize_t SocketOpenSSL::send(const std::string& buffer)
{
return send((char*) &buffer[0], buffer.size());
}
ssize_t SocketOpenSSL::recv(void* buf, size_t nbyte)

View File

@ -33,6 +33,7 @@ namespace ix
virtual void close() final;
virtual ssize_t send(char* buffer, size_t length) final;
virtual ssize_t send(const std::string& buffer) final;
virtual ssize_t recv(void* buffer, size_t length) final;
private:

View File

@ -0,0 +1,103 @@
/*
* IXSocketSChannel.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*
* See https://docs.microsoft.com/en-us/windows/desktop/WinSock/using-secure-socket-extensions
*
* https://github.com/pauldotknopf/WindowsSDK7-Samples/blob/master/netds/winsock/securesocket/stcpclient/tcpclient.c
*
* This is the right example to look at:
* https://www.codeproject.com/Articles/1000189/A-Working-TCP-Client-and-Server-With-SSL
*
* Similar code is available from this git repo
* https://github.com/david-maw/StreamSSL
*/
#include "IXSocketSChannel.h"
#ifdef _WIN32
#include <WS2tcpip.h>
#include <WinSock2.h>
#include <basetsd.h>
#include <io.h>
#include <schannel.h>
#include <ws2def.h>
#define WIN32_LEAN_AND_MEAN
#ifndef UNICODE
#define UNICODE
#endif
#include <mstcpip.h>
#include <ntdsapi.h>
#include <rpc.h>
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#define RECV_DATA_BUF_SIZE 256
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
// link with fwpuclnt.lib for Winsock secure socket extensions
#pragma comment(lib, "fwpuclnt.lib")
// link with ntdsapi.lib for DsMakeSpn function
#pragma comment(lib, "ntdsapi.lib")
// The following function assumes that Winsock
// has already been initialized
#else
#error("This file should only be built on Windows")
#endif
namespace ix
{
SocketSChannel::SocketSChannel()
{
;
}
SocketSChannel::~SocketSChannel()
{
}
bool SocketSChannel::connect(const std::string& host, int port, std::string& errMsg)
{
return Socket::connect(host, port, errMsg, nullptr);
}
void SocketSChannel::secureSocket()
{
// there will be a lot to do here ...
}
void SocketSChannel::close()
{
Socket::close();
}
ssize_t SocketSChannel::send(char* buf, size_t nbyte)
{
return Socket::send(buf, nbyte);
}
ssize_t SocketSChannel::send(const std::string& buffer)
{
return Socket::send(buffer);
}
ssize_t SocketSChannel::recv(void* buf, size_t nbyte)
{
return Socket::recv(buf, nbyte);
}
} // namespace ix

View File

@ -0,0 +1,32 @@
/*
* IXSocketSChannel.h
* Author: Benjamin Sergeant
* Copyright (c) 2017-2018 Machine Zone, Inc. All rights reserved.
*/
#pragma once
#include "IXSocket.h"
namespace ix
{
class SocketSChannel final : public Socket
{
public:
SocketSChannel();
~SocketSChannel();
virtual bool connect(const std::string& host, int port, std::string& errMsg) final;
virtual void close() final;
// The important override
virtual void secureSocket() final;
virtual ssize_t send(char* buffer, size_t length) final;
virtual ssize_t send(const std::string& buffer) final;
virtual ssize_t recv(void* buffer, size_t length) final;
private:
};
} // namespace ix

View File

@ -11,8 +11,8 @@
#include "IXSocketConnect.h"
#include "IXSocketFactory.h"
#include <assert.h>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
namespace ix
@ -21,15 +21,15 @@ namespace ix
const std::string SocketServer::kDefaultHost("127.0.0.1");
const int SocketServer::kDefaultTcpBacklog(5);
const size_t SocketServer::kDefaultMaxConnections(32);
const int SocketServer::kDefaultAddressFamily(AF_INET);
SocketServer::SocketServer(
int port, const std::string& host, int backlog, size_t maxConnections, int addressFamily)
SocketServer::SocketServer(int port,
const std::string& host,
int backlog,
size_t maxConnections)
: _port(port)
, _host(host)
, _backlog(backlog)
, _maxConnections(maxConnections)
, _addressFamily(addressFamily)
, _serverFd(-1)
, _stop(false)
, _stopGc(false)
@ -45,26 +45,21 @@ namespace ix
void SocketServer::logError(const std::string& str)
{
std::lock_guard<std::mutex> lock(_logMutex);
fprintf(stderr, "%s\n", str.c_str());
std::cerr << str << std::endl;
}
void SocketServer::logInfo(const std::string& str)
{
std::lock_guard<std::mutex> lock(_logMutex);
fprintf(stdout, "%s\n", str.c_str());
std::cout << str << std::endl;
}
std::pair<bool, std::string> SocketServer::listen()
{
if (_addressFamily != AF_INET && _addressFamily != AF_INET6)
{
std::string errMsg("SocketServer::listen() AF_INET and AF_INET6 are currently "
"the only supported address families");
return std::make_pair(false, errMsg);
}
struct sockaddr_in server; // server address information
// Get a socket for accepting connections.
if ((_serverFd = socket(_addressFamily, SOCK_STREAM, 0)) < 0)
if ((_serverFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
std::stringstream ss;
ss << "SocketServer::listen() error creating socket): " << strerror(Socket::getErrno());
@ -84,63 +79,27 @@ namespace ix
return std::make_pair(false, ss.str());
}
if (_addressFamily == AF_INET)
// Bind the socket to the server address.
server.sin_family = AF_INET;
server.sin_port = htons(_port);
// Using INADDR_ANY trigger a pop-up box as binding to any address is detected
// by the osx firewall. We need to codesign the binary with a self-signed cert
// to allow that, but this is a bit of a pain. (this is what node or python would do).
//
// Using INADDR_LOOPBACK also does not work ... while it should.
// We default to 127.0.0.1 (localhost)
//
server.sin_addr.s_addr = inet_addr(_host.c_str());
if (bind(_serverFd, (struct sockaddr*) &server, sizeof(server)) < 0)
{
struct sockaddr_in server;
server.sin_family = _addressFamily;
server.sin_port = htons(_port);
std::stringstream ss;
ss << "SocketServer::listen() error calling bind "
<< "at address " << _host << ":" << _port << " : " << strerror(Socket::getErrno());
if (inet_pton(_addressFamily, _host.c_str(), &server.sin_addr.s_addr) <= 0)
{
std::stringstream ss;
ss << "SocketServer::listen() error calling inet_pton "
<< "at address " << _host << ":" << _port << " : "
<< strerror(Socket::getErrno());
Socket::closeSocket(_serverFd);
return std::make_pair(false, ss.str());
}
// Bind the socket to the server address.
if (bind(_serverFd, (struct sockaddr*) &server, sizeof(server)) < 0)
{
std::stringstream ss;
ss << "SocketServer::listen() error calling bind "
<< "at address " << _host << ":" << _port << " : "
<< strerror(Socket::getErrno());
Socket::closeSocket(_serverFd);
return std::make_pair(false, ss.str());
}
}
else // AF_INET6
{
struct sockaddr_in6 server;
server.sin6_family = _addressFamily;
server.sin6_port = htons(_port);
if (inet_pton(_addressFamily, _host.c_str(), &server.sin6_addr) <= 0)
{
std::stringstream ss;
ss << "SocketServer::listen() error calling inet_pton "
<< "at address " << _host << ":" << _port << " : "
<< strerror(Socket::getErrno());
Socket::closeSocket(_serverFd);
return std::make_pair(false, ss.str());
}
// Bind the socket to the server address.
if (bind(_serverFd, (struct sockaddr*) &server, sizeof(server)) < 0)
{
std::stringstream ss;
ss << "SocketServer::listen() error calling bind "
<< "at address " << _host << ":" << _port << " : "
<< strerror(Socket::getErrno());
Socket::closeSocket(_serverFd);
return std::make_pair(false, ss.str());
}
Socket::closeSocket(_serverFd);
return std::make_pair(false, ss.str());
}
//

View File

@ -36,8 +36,7 @@ namespace ix
SocketServer(int port = SocketServer::kDefaultPort,
const std::string& host = SocketServer::kDefaultHost,
int backlog = SocketServer::kDefaultTcpBacklog,
size_t maxConnections = SocketServer::kDefaultMaxConnections,
int addressFamily = SocketServer::kDefaultAddressFamily);
size_t maxConnections = SocketServer::kDefaultMaxConnections);
virtual ~SocketServer();
virtual void stop();
@ -50,7 +49,6 @@ namespace ix
const static std::string kDefaultHost;
const static int kDefaultTcpBacklog;
const static size_t kDefaultMaxConnections;
const static int kDefaultAddressFamily;
void start();
std::pair<bool, std::string> listen();
@ -71,7 +69,6 @@ namespace ix
std::string _host;
int _backlog;
size_t _maxConnections;
int _addressFamily;
// socket for accepting connections
int _serverFd;

View File

@ -169,7 +169,6 @@ namespace ix
// wait until working thread will exit
// it will exit after close operation is finished
_stop = true;
_sleepCondition.notify_one();
_thread.join();
_stop = false;
}
@ -191,19 +190,9 @@ namespace ix
auto subProtocols = getSubProtocols();
if (!subProtocols.empty())
{
//
// Sub Protocol strings are comma separated.
// Python code to do that is:
// >>> ','.join(['json', 'msgpack'])
// 'json,msgpack'
//
int i = 0;
for (auto subProtocol : subProtocols)
{
if (i++ != 0)
{
subProtocolsHeader += ",";
}
subProtocolsHeader += ",";
subProtocolsHeader += subProtocol;
}
headers["Sec-WebSocket-Protocol"] = subProtocolsHeader;
@ -293,13 +282,8 @@ namespace ix
// Only sleep if we are retrying
if (duration.count() > 0)
{
std::unique_lock<std::mutex> lock(_sleepMutex);
_sleepCondition.wait_for(lock, duration);
}
if (_stop)
{
break;
// to do: make sleeping conditional
std::this_thread::sleep_for(duration);
}
// Try to connect synchronously

View File

@ -19,7 +19,6 @@
#include "IXWebSocketSendInfo.h"
#include "IXWebSocketTransport.h"
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
@ -141,10 +140,6 @@ namespace ix
static const uint32_t kDefaultMaxWaitBetweenReconnectionRetries;
uint32_t _maxWaitBetweenReconnectionRetries;
// Make the sleeping in the automatic reconnection cancellable
std::mutex _sleepMutex;
std::condition_variable _sleepCondition;
std::atomic<int> _handshakeTimeoutSecs;
static const int kDefaultHandShakeTimeoutSecs;

View File

@ -12,7 +12,6 @@
#include "IXUserAgent.h"
#include "libwshandshake.hpp"
#include <algorithm>
#include <iostream>
#include <random>
#include <sstream>
@ -336,9 +335,8 @@ namespace ix
std::string header = headers["sec-websocket-extensions"];
WebSocketPerMessageDeflateOptions webSocketPerMessageDeflateOptions(header);
// If the client has requested that extension,
// and the server does not prevent it, enable it.
if (_enablePerMessageDeflate && webSocketPerMessageDeflateOptions.enabled())
// If the client has requested that extension, enable it.
if (webSocketPerMessageDeflateOptions.enabled())
{
_enablePerMessageDeflate = true;

View File

@ -66,23 +66,12 @@ namespace ix
{
line[i] = '\0';
std::string lineStr(line);
// colon is ':', usually colon+1 is ' ', and colon+2 is the start of the value.
// some webservers do not put a space after the colon character, so
// the start of the value might be farther than colon+2.
// The spec says that space after the : should be discarded.
// colon is ':', colon+1 is ' ', colon+2 is the start of the value.
// i is end of string (\0), i-colon is length of string minus key;
// subtract 1 for '\0', 1 for '\n', 1 for '\r',
// 1 for the ' ' after the ':', and total is -4
// since we use an std::string later on and don't account for '\0',
// plus the optional first space, total is -2
int start = colon + 1;
while (lineStr[start] == ' ')
{
start++;
}
std::string name(lineStr.substr(0, colon));
std::string value(lineStr.substr(start, lineStr.size() - start - 2));
std::string value(lineStr.substr(colon + 2, i - colon - 4));
headers[name] = value;
}

View File

@ -23,12 +23,10 @@ namespace ix
const std::string& host,
int backlog,
size_t maxConnections,
int handshakeTimeoutSecs,
int addressFamily)
: SocketServer(port, host, backlog, maxConnections, addressFamily)
int handshakeTimeoutSecs)
: SocketServer(port, host, backlog, maxConnections)
, _handshakeTimeoutSecs(handshakeTimeoutSecs)
, _enablePong(kDefaultEnablePong)
, _enablePerMessageDeflate(true)
{
}
@ -60,11 +58,6 @@ namespace ix
_enablePong = false;
}
void WebSocketServer::disablePerMessageDeflate()
{
_enablePerMessageDeflate = false;
}
void WebSocketServer::setOnConnectionCallback(const OnConnectionCallback& callback)
{
_onConnectionCallback = callback;
@ -79,18 +72,9 @@ namespace ix
webSocket->disableAutomaticReconnection();
if (_enablePong)
{
webSocket->enablePong();
}
else
{
webSocket->disablePong();
}
if (!_enablePerMessageDeflate)
{
webSocket->disablePerMessageDeflate();
}
// Add this client to our client set
{
@ -122,6 +106,7 @@ namespace ix
}
}
logInfo("WebSocketServer::handleConnection() done");
connectionState->setTerminated();
}

View File

@ -29,33 +29,29 @@ namespace ix
const std::string& host = SocketServer::kDefaultHost,
int backlog = SocketServer::kDefaultTcpBacklog,
size_t maxConnections = SocketServer::kDefaultMaxConnections,
int handshakeTimeoutSecs = WebSocketServer::kDefaultHandShakeTimeoutSecs,
int addressFamily = SocketServer::kDefaultAddressFamily);
int handshakeTimeoutSecs = WebSocketServer::kDefaultHandShakeTimeoutSecs);
virtual ~WebSocketServer();
virtual void stop() final;
void enablePong();
void disablePong();
void disablePerMessageDeflate();
void setOnConnectionCallback(const OnConnectionCallback& callback);
// Get all the connected clients
std::set<std::shared_ptr<WebSocket>> getClients();
const static int kDefaultHandShakeTimeoutSecs;
private:
// Member variables
int _handshakeTimeoutSecs;
bool _enablePong;
bool _enablePerMessageDeflate;
OnConnectionCallback _onConnectionCallback;
std::mutex _clientsMutex;
std::set<std::shared_ptr<WebSocket>> _clients;
const static int kDefaultHandShakeTimeoutSecs;
const static bool kDefaultEnablePong;
// Methods

View File

@ -350,9 +350,28 @@ namespace ix
}
else if (pollResult == PollResultType::ReadyForRead)
{
if (!receiveFromSocket())
while (true)
{
return PollResult::AbnormalClose;
ssize_t ret = _socket->recv((char*) &_readbuf[0], _readbuf.size());
if (ret < 0 && Socket::isWaitNeeded())
{
break;
}
else if (ret <= 0)
{
// if there are received data pending to be processed, then delay the abnormal
// closure to after dispatch (other close code/reason could be read from the
// buffer)
closeSocket();
return PollResult::AbnormalClose;
}
else
{
_rxbuf.insert(_rxbuf.end(), _readbuf.begin(), _readbuf.begin() + ret);
}
}
}
else if (pollResult == PollResultType::Error)
@ -720,7 +739,7 @@ namespace ix
// if an abnormal closure was raised in poll, and nothing else triggered a CLOSED state in
// the received and processed data then close the connection
if (pollResult != PollResult::Succeeded)
if (pollResult == PollResult::AbnormalClose)
{
_rxbuf.clear();
@ -846,12 +865,10 @@ namespace ix
_txbuf.reserve(wireSize);
}
bool success = true;
// Common case for most message. No fragmentation required.
if (wireSize < kChunkSize)
{
success = sendFragment(type, true, message_begin, message_end, compress);
sendFragment(type, true, message_begin, message_end, compress);
}
else
{
@ -887,10 +904,7 @@ namespace ix
}
// Send message
if (!sendFragment(opcodeType, fin, begin, end, compress))
{
return WebSocketSendInfo(false);
}
sendFragment(opcodeType, fin, begin, end, compress);
if (onProgressCallback && !onProgressCallback((int) i, (int) steps))
{
@ -901,6 +915,8 @@ namespace ix
}
}
bool success = true;
// Request to flush the send buffer on the background thread if it isn't empty
if (!isSendBufferEmpty())
{
@ -916,7 +932,7 @@ namespace ix
return WebSocketSendInfo(success, compressionError, payloadSize, wireSize);
}
bool WebSocketTransport::sendFragment(wsheader_type::opcode_type type,
void WebSocketTransport::sendFragment(wsheader_type::opcode_type type,
bool fin,
std::string::const_iterator message_begin,
std::string::const_iterator message_end,
@ -1001,7 +1017,7 @@ namespace ix
appendToSendBuffer(header, message_begin, message_end, message_size, masking_key);
// Now actually send this data
return sendOnSocket();
sendOnSocket();
}
WebSocketSendInfo WebSocketTransport::sendPing(const std::string& message)
@ -1034,17 +1050,19 @@ namespace ix
wsheader_type::TEXT_FRAME, message, _enablePerMessageDeflate, onProgressCallback);
}
bool WebSocketTransport::sendOnSocket()
ssize_t WebSocketTransport::send()
{
std::lock_guard<std::mutex> lock(_socketMutex);
return _socket->send((char*) &_txbuf[0], _txbuf.size());
}
void WebSocketTransport::sendOnSocket()
{
std::lock_guard<std::mutex> lock(_txbufMutex);
while (_txbuf.size())
{
ssize_t ret = 0;
{
std::lock_guard<std::mutex> lock(_socketMutex);
ret = _socket->send((char*) &_txbuf[0], _txbuf.size());
}
ssize_t ret = send();
if (ret < 0 && Socket::isWaitNeeded())
{
@ -1054,43 +1072,13 @@ namespace ix
{
closeSocket();
setReadyState(ReadyState::CLOSED);
return false;
break;
}
else
{
_txbuf.erase(_txbuf.begin(), _txbuf.begin() + ret);
}
}
return true;
}
bool WebSocketTransport::receiveFromSocket()
{
while (true)
{
ssize_t ret = _socket->recv((char*) &_readbuf[0], _readbuf.size());
if (ret < 0 && Socket::isWaitNeeded())
{
break;
}
else if (ret <= 0)
{
// if there are received data pending to be processed, then delay the abnormal
// closure to after dispatch (other close code/reason could be read from the
// buffer)
closeSocket();
return false;
}
else
{
_rxbuf.insert(_rxbuf.end(), _readbuf.begin(), _readbuf.begin() + ret);
}
}
return true;
}
void WebSocketTransport::sendCloseFrame(uint16_t code, const std::string& reason)
@ -1195,10 +1183,7 @@ namespace ix
}
else if (result == PollResultType::ReadyForWrite)
{
if (!sendOnSocket())
{
return false;
}
sendOnSocket();
}
}

View File

@ -99,6 +99,7 @@ namespace ix
bool remote = false);
void closeSocket();
ssize_t send();
ReadyState getReadyState() const;
void setReadyState(ReadyState readyState);
@ -243,15 +244,13 @@ namespace ix
bool remote);
bool flushSendBuffer();
bool sendOnSocket();
bool receiveFromSocket();
void sendOnSocket();
WebSocketSendInfo sendData(wsheader_type::opcode_type type,
const std::string& message,
bool compress,
const OnProgressCallback& onProgressCallback = nullptr);
bool sendFragment(wsheader_type::opcode_type type,
void sendFragment(wsheader_type::opcode_type type,
bool fin,
std::string::const_iterator begin,
std::string::const_iterator end,

View File

@ -6,4 +6,4 @@
#pragma once
#define IX_WEBSOCKET_VERSION "8.1.3"
#define IX_WEBSOCKET_VERSION "7.6.4"

View File

@ -49,9 +49,6 @@ BUILD := ${NAME}:build
print_version:
@echo 'IXWebSocket version =>' ${TAG}
set_version:
sh tools/update_version.sh ${VERSION}
docker_test:
docker build -f docker/Dockerfile.debian -t bsergean/ixwebsocket_test:build .

View File

@ -23,8 +23,6 @@ include_directories(
../ws
)
add_definitions(-DSPDLOG_COMPILED_LIB=1)
find_package(JsonCpp)
if (NOT JSONCPP_FOUND)
include_directories(../third_party/jsoncpp)
@ -55,12 +53,12 @@ set (SOURCES
IXDNSLookupTest.cpp
IXWebSocketSubProtocolTest.cpp
IXSentryClientTest.cpp
IXWebSocketChatTest.cpp
)
# Some unittest don't work on windows yet
if (UNIX)
list(APPEND SOURCES
IXWebSocketChatTest.cpp
IXWebSocketCloseTest.cpp
)
endif()
@ -100,6 +98,4 @@ target_link_libraries(ixwebsocket_unittest ixcrypto)
target_link_libraries(ixwebsocket_unittest ixcore)
target_link_libraries(ixwebsocket_unittest ixsentry)
target_link_libraries(ixwebsocket_unittest spdlog)
install(TARGETS ixwebsocket_unittest DESTINATION bin)

View File

@ -37,7 +37,9 @@ namespace
class CobraChat
{
public:
CobraChat(const std::string& user, const std::string& session, const std::string& endpoint);
CobraChat(const std::string& user,
const std::string& session,
const std::string& endpoint);
void subscribe(const std::string& channel);
void start();

View File

@ -59,14 +59,10 @@ TEST_CASE("http server", "[httpd]")
REQUIRE(response->errorCode == HttpErrorCode::Ok);
REQUIRE(response->statusCode == 200);
REQUIRE(response->headers["Accept-Encoding"] == "gzip");
server.stop();
}
}
TEST_CASE("http server redirection", "[httpd_redirect]")
{
SECTION("Connect to a local HTTP server, with redirection enabled")
{
int port = getFreePort();

File diff suppressed because one or more lines are too long

View File

@ -1,36 +0,0 @@
from websocket import *
import random
import string
import ssl
def randomString(stringLength=10):
"""Generate a random string of fixed length """
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
st = randomString(32768)
with open('generated_file', 'w') as f:
f.write(st)
ws = create_connection("wss://echo.websocket.org/",
sslopt={"cert_reqs": ssl.CERT_NONE})
print("Sending")
frame = ABNF.create_frame(st, ABNF.OPCODE_TEXT, 0)
ws.send_frame(frame)
cont_frame = ABNF.create_frame(st, ABNF.OPCODE_CONT, 0)
ws.send_frame(cont_frame)
cont_frame = ABNF.create_frame(st, ABNF.OPCODE_CONT, 1)
ws.send_frame(cont_frame)
print("Sent")
print("Receiving...")
result = ws.recv()
if st+st+st == result:
print("Received ")
else:
print("Error")
ws.close()

View File

@ -1,17 +1,8 @@
FROM python:3.8.0-alpine3.10
RUN pip install websockets
COPY ws_proxy.py /usr/bin
RUN chmod +x /usr/bin/ws_proxy.py
COPY vendor/protocol.py /usr/local/lib/python3.8/site-packages/websockets/protocol.py
COPY *.py /usr/bin/
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/*.py
RUN mkdir /certs
COPY *.pem /certs/
WORKDIR /certs
EXPOSE 8765 8766
CMD ["sh", "/usr/bin/entrypoint.sh"]
EXPOSE 8765
CMD ["python", "/usr/bin/ws_proxy.py"]

View File

@ -1,3 +0,0 @@
nginx: nginx -p . -c nginx.conf
websocket_server: python echo_server.py
send: sleep 1 ; ws send -x --verify_none wss://localhost:8765 /usr/local/bin/ws

View File

@ -28,819 +28,3 @@ connected (press CTRL+C to quit)
< > Welcome !
disconnected (code: 1006)
```
# Server
```
$ honcho start
15:29:52 system | nginx.1 started (pid=75372)
15:29:52 system | send.1 started (pid=75373)
15:29:52 system | websocket_server.1 started (pid=75374)
15:29:53 send.1 | [2020-01-05 15:29:53.414] [info] ws_send: Connecting to url: wss://localhost:8765
15:29:53 send.1 | [2020-01-05 15:29:53.415] [info] ws_send: Connecting...
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] ws_send: connected
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] ws_send: Sending...
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Uri: /
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Headers:
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Connection: upgrade
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Date: Sun, 05 Jan 2020 23:29:53 GMT
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Sec-WebSocket-Accept: 2+7DV7Q0Ib3fxynZwaNTtsAepIk=
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Server: nginx/1.15.9
15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Upgrade: websocket
15:29:53 send.1 | [2020-01-05 15:29:53.633] [info] load file from disk completed in 197
15:29:54 send.1 | [2020-01-05 15:29:54.267] [info] ws_send: Step 0 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.269] [info] ws_send: Step 1 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.271] [info] ws_send: Step 2 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.273] [info] ws_send: Step 3 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.275] [info] ws_send: Step 4 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.277] [info] ws_send: Step 5 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.278] [info] ws_send: Step 6 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.280] [info] ws_send: Step 7 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.282] [info] ws_send: Step 8 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.284] [info] ws_send: Step 9 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.286] [info] ws_send: Step 10 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.288] [info] ws_send: Step 11 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.289] [info] ws_send: Step 12 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.291] [info] ws_send: Step 13 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.293] [info] ws_send: Step 14 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.295] [info] ws_send: Step 15 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.297] [info] ws_send: Step 16 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.298] [info] ws_send: Step 17 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.300] [info] ws_send: Step 18 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.302] [info] ws_send: Step 19 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.304] [info] ws_send: Step 20 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.306] [info] ws_send: Step 21 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.308] [info] ws_send: Step 22 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.309] [info] ws_send: Step 23 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.311] [info] ws_send: Step 24 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.313] [info] ws_send: Step 25 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.315] [info] ws_send: Step 26 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.317] [info] ws_send: Step 27 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.319] [info] ws_send: Step 28 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.320] [info] ws_send: Step 29 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.322] [info] ws_send: Step 30 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.324] [info] ws_send: Step 31 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.326] [info] ws_send: Step 32 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.328] [info] ws_send: Step 33 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.329] [info] ws_send: Step 34 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.331] [info] ws_send: Step 35 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.333] [info] ws_send: Step 36 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.335] [info] ws_send: Step 37 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.337] [info] ws_send: Step 38 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.339] [info] ws_send: Step 39 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.340] [info] ws_send: Step 40 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.342] [info] ws_send: Step 41 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.344] [info] ws_send: Step 42 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.346] [info] ws_send: Step 43 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.348] [info] ws_send: Step 44 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.350] [info] ws_send: Step 45 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.351] [info] ws_send: Step 46 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.353] [info] ws_send: Step 47 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.355] [info] ws_send: Step 48 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.357] [info] ws_send: Step 49 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.359] [info] ws_send: Step 50 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.361] [info] ws_send: Step 51 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.362] [info] ws_send: Step 52 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.364] [info] ws_send: Step 53 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.366] [info] ws_send: Step 54 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.368] [info] ws_send: Step 55 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.370] [info] ws_send: Step 56 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.372] [info] ws_send: Step 57 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.373] [info] ws_send: Step 58 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.375] [info] ws_send: Step 59 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.377] [info] ws_send: Step 60 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.379] [info] ws_send: Step 61 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.381] [info] ws_send: Step 62 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.383] [info] ws_send: Step 63 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.384] [info] ws_send: Step 64 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.386] [info] ws_send: Step 65 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.388] [info] ws_send: Step 66 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.390] [info] ws_send: Step 67 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.392] [info] ws_send: Step 68 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.394] [info] ws_send: Step 69 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.395] [info] ws_send: Step 70 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.397] [info] ws_send: Step 71 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.399] [info] ws_send: Step 72 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.401] [info] ws_send: Step 73 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.403] [info] ws_send: Step 74 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.405] [info] ws_send: Step 75 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.407] [info] ws_send: Step 76 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.409] [info] ws_send: Step 77 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.411] [info] ws_send: Step 78 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.412] [info] ws_send: Step 79 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.414] [info] ws_send: Step 80 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.416] [info] ws_send: Step 81 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.418] [info] ws_send: Step 82 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.420] [info] ws_send: Step 83 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.421] [info] ws_send: Step 84 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.423] [info] ws_send: Step 85 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.425] [info] ws_send: Step 86 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.427] [info] ws_send: Step 87 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.429] [info] ws_send: Step 88 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.431] [info] ws_send: Step 89 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.432] [info] ws_send: Step 90 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.434] [info] ws_send: Step 91 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.436] [info] ws_send: Step 92 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.438] [info] ws_send: Step 93 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.440] [info] ws_send: Step 94 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.442] [info] ws_send: Step 95 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.444] [info] ws_send: Step 96 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.445] [info] ws_send: Step 97 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.447] [info] ws_send: Step 98 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.449] [info] ws_send: Step 99 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.451] [info] ws_send: Step 100 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.453] [info] ws_send: Step 101 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.454] [info] ws_send: Step 102 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.456] [info] ws_send: Step 103 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.458] [info] ws_send: Step 104 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.460] [info] ws_send: Step 105 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.462] [info] ws_send: Step 106 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.464] [info] ws_send: Step 107 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.465] [info] ws_send: Step 108 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.467] [info] ws_send: Step 109 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.469] [info] ws_send: Step 110 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.471] [info] ws_send: Step 111 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.473] [info] ws_send: Step 112 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.475] [info] ws_send: Step 113 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.476] [info] ws_send: Step 114 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.478] [info] ws_send: Step 115 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.480] [info] ws_send: Step 116 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.482] [info] ws_send: Step 117 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.484] [info] ws_send: Step 118 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.486] [info] ws_send: Step 119 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.488] [info] ws_send: Step 120 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.489] [info] ws_send: Step 121 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.491] [info] ws_send: Step 122 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.493] [info] ws_send: Step 123 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.495] [info] ws_send: Step 124 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.497] [info] ws_send: Step 125 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.499] [info] ws_send: Step 126 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.500] [info] ws_send: Step 127 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.502] [info] ws_send: Step 128 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.504] [info] ws_send: Step 129 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.506] [info] ws_send: Step 130 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.508] [info] ws_send: Step 131 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.509] [info] ws_send: Step 132 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.511] [info] ws_send: Step 133 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.513] [info] ws_send: Step 134 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.515] [info] ws_send: Step 135 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.517] [info] ws_send: Step 136 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.519] [info] ws_send: Step 137 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.520] [info] ws_send: Step 138 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.522] [info] ws_send: Step 139 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.524] [info] ws_send: Step 140 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.526] [info] ws_send: Step 141 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.528] [info] ws_send: Step 142 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.530] [info] ws_send: Step 143 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.531] [info] ws_send: Step 144 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.533] [info] ws_send: Step 145 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.535] [info] ws_send: Step 146 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.537] [info] ws_send: Step 147 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.539] [info] ws_send: Step 148 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.541] [info] ws_send: Step 149 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.542] [info] ws_send: Step 150 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.544] [info] ws_send: Step 151 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.546] [info] ws_send: Step 152 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.548] [info] ws_send: Step 153 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.550] [info] ws_send: Step 154 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.551] [info] ws_send: Step 155 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.553] [info] ws_send: Step 156 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.555] [info] ws_send: Step 157 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.557] [info] ws_send: Step 158 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.559] [info] ws_send: Step 159 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.561] [info] ws_send: Step 160 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.562] [info] ws_send: Step 161 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.564] [info] ws_send: Step 162 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.566] [info] ws_send: Step 163 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.568] [info] ws_send: Step 164 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.570] [info] ws_send: Step 165 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.571] [info] ws_send: Step 166 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.573] [info] ws_send: Step 167 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.575] [info] ws_send: Step 168 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.577] [info] ws_send: Step 169 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.579] [info] ws_send: Step 170 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.581] [info] ws_send: Step 171 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.582] [info] ws_send: Step 172 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.584] [info] ws_send: Step 173 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.586] [info] ws_send: Step 174 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.588] [info] ws_send: Step 175 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.590] [info] ws_send: Step 176 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.592] [info] ws_send: Step 177 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.593] [info] ws_send: Step 178 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.595] [info] ws_send: Step 179 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.597] [info] ws_send: Step 180 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.599] [info] ws_send: Step 181 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.601] [info] ws_send: Step 182 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.602] [info] ws_send: Step 183 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.604] [info] ws_send: Step 184 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.606] [info] ws_send: Step 185 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.608] [info] ws_send: Step 186 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.610] [info] ws_send: Step 187 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.612] [info] ws_send: Step 188 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.613] [info] ws_send: Step 189 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.615] [info] ws_send: Step 190 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.617] [info] ws_send: Step 191 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.619] [info] ws_send: Step 192 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.621] [info] ws_send: Step 193 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.622] [info] ws_send: Step 194 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.624] [info] ws_send: Step 195 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.626] [info] ws_send: Step 196 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.628] [info] ws_send: Step 197 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.630] [info] ws_send: Step 198 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.632] [info] ws_send: Step 199 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.633] [info] ws_send: Step 200 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.635] [info] ws_send: Step 201 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.637] [info] ws_send: Step 202 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.639] [info] ws_send: Step 203 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.641] [info] ws_send: Step 204 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.642] [info] ws_send: Step 205 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.644] [info] ws_send: Step 206 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.646] [info] ws_send: Step 207 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.648] [info] ws_send: Step 208 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.650] [info] ws_send: Step 209 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.652] [info] ws_send: Step 210 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.653] [info] ws_send: Step 211 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.655] [info] ws_send: Step 212 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.657] [info] ws_send: Step 213 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.659] [info] ws_send: Step 214 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.661] [info] ws_send: Step 215 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.663] [info] ws_send: Step 216 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.664] [info] ws_send: Step 217 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.666] [info] ws_send: Step 218 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.668] [info] ws_send: Step 219 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.670] [info] ws_send: Step 220 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.672] [info] ws_send: Step 221 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.674] [info] ws_send: Step 222 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.675] [info] ws_send: Step 223 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.677] [info] ws_send: Step 224 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.679] [info] ws_send: Step 225 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.681] [info] ws_send: Step 226 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.683] [info] ws_send: Step 227 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.685] [info] ws_send: Step 228 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.686] [info] ws_send: Step 229 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.688] [info] ws_send: Step 230 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.690] [info] ws_send: Step 231 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.692] [info] ws_send: Step 232 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.694] [info] ws_send: Step 233 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.695] [info] ws_send: Step 234 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.697] [info] ws_send: Step 235 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.699] [info] ws_send: Step 236 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.701] [info] ws_send: Step 237 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.703] [info] ws_send: Step 238 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.705] [info] ws_send: Step 239 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.707] [info] ws_send: Step 240 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.708] [info] ws_send: Step 241 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.710] [info] ws_send: Step 242 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.712] [info] ws_send: Step 243 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.714] [info] ws_send: Step 244 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.716] [info] ws_send: Step 245 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.718] [info] ws_send: Step 246 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.719] [info] ws_send: Step 247 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.721] [info] ws_send: Step 248 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.723] [info] ws_send: Step 249 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.725] [info] ws_send: Step 250 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.727] [info] ws_send: Step 251 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.729] [info] ws_send: Step 252 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.730] [info] ws_send: Step 253 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.732] [info] ws_send: Step 254 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.734] [info] ws_send: Step 255 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.736] [info] ws_send: Step 256 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.738] [info] ws_send: Step 257 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.740] [info] ws_send: Step 258 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.742] [info] ws_send: Step 259 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.743] [info] ws_send: Step 260 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.745] [info] ws_send: Step 261 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.747] [info] ws_send: Step 262 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.749] [info] ws_send: Step 263 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.751] [info] ws_send: Step 264 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.752] [info] ws_send: Step 265 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.754] [info] ws_send: Step 266 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.756] [info] ws_send: Step 267 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.758] [info] ws_send: Step 268 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.760] [info] ws_send: Step 269 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.762] [info] ws_send: Step 270 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.763] [info] ws_send: Step 271 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.765] [info] ws_send: Step 272 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.767] [info] ws_send: Step 273 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.769] [info] ws_send: Step 274 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.771] [info] ws_send: Step 275 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.772] [info] ws_send: Step 276 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.774] [info] ws_send: Step 277 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.776] [info] ws_send: Step 278 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.778] [info] ws_send: Step 279 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.780] [info] ws_send: Step 280 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.782] [info] ws_send: Step 281 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.783] [info] ws_send: Step 282 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.785] [info] ws_send: Step 283 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.787] [info] ws_send: Step 284 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.789] [info] ws_send: Step 285 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.791] [info] ws_send: Step 286 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.793] [info] ws_send: Step 287 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.794] [info] ws_send: Step 288 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.796] [info] ws_send: Step 289 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.798] [info] ws_send: Step 290 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.800] [info] ws_send: Step 291 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.802] [info] ws_send: Step 292 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.804] [info] ws_send: Step 293 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.805] [info] ws_send: Step 294 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.807] [info] ws_send: Step 295 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.809] [info] ws_send: Step 296 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.811] [info] ws_send: Step 297 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.813] [info] ws_send: Step 298 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.814] [info] ws_send: Step 299 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.816] [info] ws_send: Step 300 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.818] [info] ws_send: Step 301 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.820] [info] ws_send: Step 302 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.822] [info] ws_send: Step 303 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.824] [info] ws_send: Step 304 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.825] [info] ws_send: Step 305 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.827] [info] ws_send: Step 306 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.829] [info] ws_send: Step 307 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.831] [info] ws_send: Step 308 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.833] [info] ws_send: Step 309 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.835] [info] ws_send: Step 310 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.836] [info] ws_send: Step 311 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.838] [info] ws_send: Step 312 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.840] [info] ws_send: Step 313 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.842] [info] ws_send: Step 314 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.844] [info] ws_send: Step 315 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.845] [info] ws_send: Step 316 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.847] [info] ws_send: Step 317 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.849] [info] ws_send: Step 318 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.851] [info] ws_send: Step 319 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.853] [info] ws_send: Step 320 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.855] [info] ws_send: Step 321 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.856] [info] ws_send: Step 322 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.858] [info] ws_send: Step 323 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.860] [info] ws_send: Step 324 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.862] [info] ws_send: Step 325 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.864] [info] ws_send: Step 326 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.866] [info] ws_send: Step 327 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.867] [info] ws_send: Step 328 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.869] [info] ws_send: Step 329 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.871] [info] ws_send: Step 330 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.873] [info] ws_send: Step 331 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.875] [info] ws_send: Step 332 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.876] [info] ws_send: Step 333 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.878] [info] ws_send: Step 334 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.880] [info] ws_send: Step 335 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.882] [info] ws_send: Step 336 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.884] [info] ws_send: Step 337 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.886] [info] ws_send: Step 338 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.888] [info] ws_send: Step 339 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.889] [info] ws_send: Step 340 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.891] [info] ws_send: Step 341 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.893] [info] ws_send: Step 342 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.895] [info] ws_send: Step 343 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.897] [info] ws_send: Step 344 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.899] [info] ws_send: Step 345 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.900] [info] ws_send: Step 346 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.902] [info] ws_send: Step 347 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.904] [info] ws_send: Step 348 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.906] [info] ws_send: Step 349 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.908] [info] ws_send: Step 350 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.910] [info] ws_send: Step 351 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.911] [info] ws_send: Step 352 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.913] [info] ws_send: Step 353 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.915] [info] ws_send: Step 354 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.917] [info] ws_send: Step 355 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.919] [info] ws_send: Step 356 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.920] [info] ws_send: Step 357 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.922] [info] ws_send: Step 358 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.924] [info] ws_send: Step 359 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.926] [info] ws_send: Step 360 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.928] [info] ws_send: Step 361 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.930] [info] ws_send: Step 362 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.932] [info] ws_send: Step 363 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.933] [info] ws_send: Step 364 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.935] [info] ws_send: Step 365 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.937] [info] ws_send: Step 366 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.939] [info] ws_send: Step 367 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.941] [info] ws_send: Step 368 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.943] [info] ws_send: Step 369 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.944] [info] ws_send: Step 370 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.946] [info] ws_send: Step 371 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.948] [info] ws_send: Step 372 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.950] [info] ws_send: Step 373 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.952] [info] ws_send: Step 374 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.954] [info] ws_send: Step 375 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.955] [info] ws_send: Step 376 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.957] [info] ws_send: Step 377 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.959] [info] ws_send: Step 378 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.961] [info] ws_send: Step 379 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.963] [info] ws_send: Step 380 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.965] [info] ws_send: Step 381 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.966] [info] ws_send: Step 382 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.968] [info] ws_send: Step 383 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.970] [info] ws_send: Step 384 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.972] [info] ws_send: Step 385 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.974] [info] ws_send: Step 386 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.976] [info] ws_send: Step 387 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.977] [info] ws_send: Step 388 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.979] [info] ws_send: Step 389 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.981] [info] ws_send: Step 390 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.983] [info] ws_send: Step 391 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.985] [info] ws_send: Step 392 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.986] [info] ws_send: Step 393 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.988] [info] ws_send: Step 394 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.990] [info] ws_send: Step 395 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.992] [info] ws_send: Step 396 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.994] [info] ws_send: Step 397 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.996] [info] ws_send: Step 398 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.997] [info] ws_send: Step 399 out of 768
15:29:54 send.1 | [2020-01-05 15:29:54.999] [info] ws_send: Step 400 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.001] [info] ws_send: Step 401 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.003] [info] ws_send: Step 402 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.005] [info] ws_send: Step 403 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.007] [info] ws_send: Step 404 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.009] [info] ws_send: Step 405 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.010] [info] ws_send: Step 406 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.012] [info] ws_send: Step 407 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.014] [info] ws_send: Step 408 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.016] [info] ws_send: Step 409 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.018] [info] ws_send: Step 410 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.020] [info] ws_send: Step 411 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.021] [info] ws_send: Step 412 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.023] [info] ws_send: Step 413 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.025] [info] ws_send: Step 414 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.027] [info] ws_send: Step 415 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.029] [info] ws_send: Step 416 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.030] [info] ws_send: Step 417 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.032] [info] ws_send: Step 418 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.034] [info] ws_send: Step 419 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.036] [info] ws_send: Step 420 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.038] [info] ws_send: Step 421 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.040] [info] ws_send: Step 422 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.041] [info] ws_send: Step 423 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.043] [info] ws_send: Step 424 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.045] [info] ws_send: Step 425 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.047] [info] ws_send: Step 426 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.049] [info] ws_send: Step 427 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.051] [info] ws_send: Step 428 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.052] [info] ws_send: Step 429 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.054] [info] ws_send: Step 430 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.056] [info] ws_send: Step 431 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.058] [info] ws_send: Step 432 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.060] [info] ws_send: Step 433 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.062] [info] ws_send: Step 434 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.063] [info] ws_send: Step 435 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.065] [info] ws_send: Step 436 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.067] [info] ws_send: Step 437 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.069] [info] ws_send: Step 438 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.071] [info] ws_send: Step 439 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.073] [info] ws_send: Step 440 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.075] [info] ws_send: Step 441 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.077] [info] ws_send: Step 442 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.078] [info] ws_send: Step 443 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.080] [info] ws_send: Step 444 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.082] [info] ws_send: Step 445 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.084] [info] ws_send: Step 446 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.086] [info] ws_send: Step 447 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.088] [info] ws_send: Step 448 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.090] [info] ws_send: Step 449 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.091] [info] ws_send: Step 450 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.093] [info] ws_send: Step 451 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.095] [info] ws_send: Step 452 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.097] [info] ws_send: Step 453 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.099] [info] ws_send: Step 454 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.101] [info] ws_send: Step 455 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.102] [info] ws_send: Step 456 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.104] [info] ws_send: Step 457 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.106] [info] ws_send: Step 458 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.108] [info] ws_send: Step 459 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.110] [info] ws_send: Step 460 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.112] [info] ws_send: Step 461 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.113] [info] ws_send: Step 462 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.115] [info] ws_send: Step 463 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.117] [info] ws_send: Step 464 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.119] [info] ws_send: Step 465 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.121] [info] ws_send: Step 466 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.123] [info] ws_send: Step 467 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.124] [info] ws_send: Step 468 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.126] [info] ws_send: Step 469 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.128] [info] ws_send: Step 470 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.130] [info] ws_send: Step 471 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.132] [info] ws_send: Step 472 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.134] [info] ws_send: Step 473 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.135] [info] ws_send: Step 474 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.137] [info] ws_send: Step 475 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.139] [info] ws_send: Step 476 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.141] [info] ws_send: Step 477 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.143] [info] ws_send: Step 478 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.145] [info] ws_send: Step 479 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.146] [info] ws_send: Step 480 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.148] [info] ws_send: Step 481 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.150] [info] ws_send: Step 482 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.152] [info] ws_send: Step 483 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.154] [info] ws_send: Step 484 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.155] [info] ws_send: Step 485 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.157] [info] ws_send: Step 486 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.159] [info] ws_send: Step 487 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.161] [info] ws_send: Step 488 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.163] [info] ws_send: Step 489 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.165] [info] ws_send: Step 490 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.166] [info] ws_send: Step 491 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.168] [info] ws_send: Step 492 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.170] [info] ws_send: Step 493 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.172] [info] ws_send: Step 494 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.174] [info] ws_send: Step 495 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.176] [info] ws_send: Step 496 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.177] [info] ws_send: Step 497 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.179] [info] ws_send: Step 498 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.181] [info] ws_send: Step 499 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.183] [info] ws_send: Step 500 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.185] [info] ws_send: Step 501 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.186] [info] ws_send: Step 502 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.188] [info] ws_send: Step 503 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.190] [info] ws_send: Step 504 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.192] [info] ws_send: Step 505 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.194] [info] ws_send: Step 506 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.196] [info] ws_send: Step 507 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.198] [info] ws_send: Step 508 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.199] [info] ws_send: Step 509 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.201] [info] ws_send: Step 510 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.203] [info] ws_send: Step 511 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.205] [info] ws_send: Step 512 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.207] [info] ws_send: Step 513 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.209] [info] ws_send: Step 514 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.210] [info] ws_send: Step 515 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.212] [info] ws_send: Step 516 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.214] [info] ws_send: Step 517 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.216] [info] ws_send: Step 518 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.218] [info] ws_send: Step 519 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.220] [info] ws_send: Step 520 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.221] [info] ws_send: Step 521 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.223] [info] ws_send: Step 522 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.225] [info] ws_send: Step 523 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.227] [info] ws_send: Step 524 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.229] [info] ws_send: Step 525 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.230] [info] ws_send: Step 526 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.232] [info] ws_send: Step 527 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.234] [info] ws_send: Step 528 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.236] [info] ws_send: Step 529 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.238] [info] ws_send: Step 530 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.240] [info] ws_send: Step 531 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.241] [info] ws_send: Step 532 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.243] [info] ws_send: Step 533 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.245] [info] ws_send: Step 534 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.247] [info] ws_send: Step 535 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.249] [info] ws_send: Step 536 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.250] [info] ws_send: Step 537 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.252] [info] ws_send: Step 538 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.254] [info] ws_send: Step 539 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.256] [info] ws_send: Step 540 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.258] [info] ws_send: Step 541 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.260] [info] ws_send: Step 542 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.261] [info] ws_send: Step 543 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.263] [info] ws_send: Step 544 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.265] [info] ws_send: Step 545 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.267] [info] ws_send: Step 546 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.269] [info] ws_send: Step 547 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.271] [info] ws_send: Step 548 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.272] [info] ws_send: Step 549 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.274] [info] ws_send: Step 550 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.276] [info] ws_send: Step 551 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.278] [info] ws_send: Step 552 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.280] [info] ws_send: Step 553 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.282] [info] ws_send: Step 554 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.283] [info] ws_send: Step 555 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.285] [info] ws_send: Step 556 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.287] [info] ws_send: Step 557 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.289] [info] ws_send: Step 558 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.291] [info] ws_send: Step 559 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.293] [info] ws_send: Step 560 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.294] [info] ws_send: Step 561 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.296] [info] ws_send: Step 562 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.298] [info] ws_send: Step 563 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.300] [info] ws_send: Step 564 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.302] [info] ws_send: Step 565 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.304] [info] ws_send: Step 566 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.305] [info] ws_send: Step 567 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.307] [info] ws_send: Step 568 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.309] [info] ws_send: Step 569 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.311] [info] ws_send: Step 570 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.313] [info] ws_send: Step 571 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.315] [info] ws_send: Step 572 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.316] [info] ws_send: Step 573 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.318] [info] ws_send: Step 574 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.320] [info] ws_send: Step 575 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.322] [info] ws_send: Step 576 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.324] [info] ws_send: Step 577 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.326] [info] ws_send: Step 578 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.327] [info] ws_send: Step 579 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.329] [info] ws_send: Step 580 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.331] [info] ws_send: Step 581 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.333] [info] ws_send: Step 582 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.335] [info] ws_send: Step 583 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.337] [info] ws_send: Step 584 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.338] [info] ws_send: Step 585 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.340] [info] ws_send: Step 586 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.342] [info] ws_send: Step 587 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.344] [info] ws_send: Step 588 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.346] [info] ws_send: Step 589 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.347] [info] ws_send: Step 590 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.349] [info] ws_send: Step 591 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.351] [info] ws_send: Step 592 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.353] [info] ws_send: Step 593 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.355] [info] ws_send: Step 594 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.357] [info] ws_send: Step 595 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.359] [info] ws_send: Step 596 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.360] [info] ws_send: Step 597 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.362] [info] ws_send: Step 598 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.364] [info] ws_send: Step 599 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.366] [info] ws_send: Step 600 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.368] [info] ws_send: Step 601 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.370] [info] ws_send: Step 602 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.371] [info] ws_send: Step 603 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.373] [info] ws_send: Step 604 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.375] [info] ws_send: Step 605 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.377] [info] ws_send: Step 606 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.379] [info] ws_send: Step 607 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.381] [info] ws_send: Step 608 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.382] [info] ws_send: Step 609 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.384] [info] ws_send: Step 610 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.386] [info] ws_send: Step 611 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.388] [info] ws_send: Step 612 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.390] [info] ws_send: Step 613 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.392] [info] ws_send: Step 614 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.393] [info] ws_send: Step 615 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.395] [info] ws_send: Step 616 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.397] [info] ws_send: Step 617 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.399] [info] ws_send: Step 618 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.401] [info] ws_send: Step 619 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.403] [info] ws_send: Step 620 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.404] [info] ws_send: Step 621 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.406] [info] ws_send: Step 622 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.408] [info] ws_send: Step 623 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.410] [info] ws_send: Step 624 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.412] [info] ws_send: Step 625 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.414] [info] ws_send: Step 626 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.415] [info] ws_send: Step 627 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.417] [info] ws_send: Step 628 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.419] [info] ws_send: Step 629 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.421] [info] ws_send: Step 630 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.423] [info] ws_send: Step 631 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.425] [info] ws_send: Step 632 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.427] [info] ws_send: Step 633 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.428] [info] ws_send: Step 634 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.430] [info] ws_send: Step 635 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.432] [info] ws_send: Step 636 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.434] [info] ws_send: Step 637 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.436] [info] ws_send: Step 638 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.438] [info] ws_send: Step 639 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.439] [info] ws_send: Step 640 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.441] [info] ws_send: Step 641 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.443] [info] ws_send: Step 642 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.445] [info] ws_send: Step 643 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.447] [info] ws_send: Step 644 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.449] [info] ws_send: Step 645 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.450] [info] ws_send: Step 646 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.452] [info] ws_send: Step 647 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.454] [info] ws_send: Step 648 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.456] [info] ws_send: Step 649 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.458] [info] ws_send: Step 650 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.460] [info] ws_send: Step 651 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.461] [info] ws_send: Step 652 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.463] [info] ws_send: Step 653 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.465] [info] ws_send: Step 654 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.467] [info] ws_send: Step 655 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.469] [info] ws_send: Step 656 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.471] [info] ws_send: Step 657 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.472] [info] ws_send: Step 658 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.474] [info] ws_send: Step 659 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.476] [info] ws_send: Step 660 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.478] [info] ws_send: Step 661 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.480] [info] ws_send: Step 662 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.482] [info] ws_send: Step 663 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.483] [info] ws_send: Step 664 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.485] [info] ws_send: Step 665 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.487] [info] ws_send: Step 666 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.489] [info] ws_send: Step 667 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.491] [info] ws_send: Step 668 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.493] [info] ws_send: Step 669 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.494] [info] ws_send: Step 670 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.496] [info] ws_send: Step 671 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.498] [info] ws_send: Step 672 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.500] [info] ws_send: Step 673 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.502] [info] ws_send: Step 674 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.503] [info] ws_send: Step 675 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.505] [info] ws_send: Step 676 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.507] [info] ws_send: Step 677 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.509] [info] ws_send: Step 678 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.511] [info] ws_send: Step 679 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.513] [info] ws_send: Step 680 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.514] [info] ws_send: Step 681 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.516] [info] ws_send: Step 682 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.518] [info] ws_send: Step 683 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.520] [info] ws_send: Step 684 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.522] [info] ws_send: Step 685 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.524] [info] ws_send: Step 686 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.525] [info] ws_send: Step 687 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.527] [info] ws_send: Step 688 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.529] [info] ws_send: Step 689 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.531] [info] ws_send: Step 690 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.533] [info] ws_send: Step 691 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.535] [info] ws_send: Step 692 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.536] [info] ws_send: Step 693 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.538] [info] ws_send: Step 694 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.540] [info] ws_send: Step 695 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.542] [info] ws_send: Step 696 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.544] [info] ws_send: Step 697 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.545] [info] ws_send: Step 698 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.547] [info] ws_send: Step 699 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.549] [info] ws_send: Step 700 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.551] [info] ws_send: Step 701 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.553] [info] ws_send: Step 702 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.555] [info] ws_send: Step 703 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.556] [info] ws_send: Step 704 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.558] [info] ws_send: Step 705 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.560] [info] ws_send: Step 706 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.562] [info] ws_send: Step 707 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.564] [info] ws_send: Step 708 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.566] [info] ws_send: Step 709 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.567] [info] ws_send: Step 710 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.569] [info] ws_send: Step 711 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.571] [info] ws_send: Step 712 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.573] [info] ws_send: Step 713 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.575] [info] ws_send: Step 714 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.576] [info] ws_send: Step 715 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.578] [info] ws_send: Step 716 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.580] [info] ws_send: Step 717 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.582] [info] ws_send: Step 718 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.584] [info] ws_send: Step 719 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.586] [info] ws_send: Step 720 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.587] [info] ws_send: Step 721 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.589] [info] ws_send: Step 722 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.591] [info] ws_send: Step 723 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.593] [info] ws_send: Step 724 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.595] [info] ws_send: Step 725 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.597] [info] ws_send: Step 726 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.598] [info] ws_send: Step 727 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.600] [info] ws_send: Step 728 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.602] [info] ws_send: Step 729 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.604] [info] ws_send: Step 730 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.606] [info] ws_send: Step 731 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.607] [info] ws_send: Step 732 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.609] [info] ws_send: Step 733 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.611] [info] ws_send: Step 734 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.613] [info] ws_send: Step 735 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.615] [info] ws_send: Step 736 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.617] [info] ws_send: Step 737 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.618] [info] ws_send: Step 738 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.620] [info] ws_send: Step 739 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.622] [info] ws_send: Step 740 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.624] [info] ws_send: Step 741 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.626] [info] ws_send: Step 742 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.628] [info] ws_send: Step 743 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.630] [info] ws_send: Step 744 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.632] [info] ws_send: Step 745 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.633] [info] ws_send: Step 746 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.635] [info] ws_send: Step 747 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.637] [info] ws_send: Step 748 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.639] [info] ws_send: Step 749 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.641] [info] ws_send: Step 750 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.642] [info] ws_send: Step 751 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.644] [info] ws_send: Step 752 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.646] [info] ws_send: Step 753 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.648] [info] ws_send: Step 754 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.650] [info] ws_send: Step 755 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.652] [info] ws_send: Step 756 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.653] [info] ws_send: Step 757 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.655] [info] ws_send: Step 758 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.657] [info] ws_send: Step 759 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.659] [info] ws_send: Step 760 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.661] [info] ws_send: Step 761 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.662] [info] ws_send: Step 762 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.664] [info] ws_send: Step 763 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.666] [info] ws_send: Step 764 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.668] [info] ws_send: Step 765 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.670] [info] ws_send: Step 766 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.673] [info] ws_send: Step 767 out of 768
15:29:55 send.1 | [2020-01-05 15:29:55.676] [info] ws_send: 0 bytes left to be sent
15:29:55 send.1 | [2020-01-05 15:29:55.689] [info] Sending file through websocket completed in 1801
15:29:55 send.1 | [2020-01-05 15:29:55.689] [info] ws_send: Send transfer rate: 13 MB/s
15:29:56 send.1 | [2020-01-05 15:29:56.142] [info] ws_send: Waiting for ack...
15:29:57 send.1 | [2020-01-05 15:29:57.399] [info] ws_send: received message (25183026 bytes)
15:29:57 send.1 | [2020-01-05 15:29:57.399] [info] ws_send: Done !
15:29:59 send.1 | [2020-01-05 15:29:59.233] [info] ws_send: connection closed: code 1000 reason Normal closure
15:29:59 send.1 |
15:29:59 system | send.1 stopped (rc=0)
15:29:59 system | sending SIGTERM to nginx.1 (pid 75372)
15:29:59 system | sending SIGTERM to websocket_server.1 (pid 75374)
15:29:59 system | nginx.1 stopped (rc=0)
15:29:59 system | websocket_server.1 stopped (rc=-15)
```
## Sending large files over SSL
Running inside docker
```
$ make docker && make server_ssl
```
On the client
```
$ make ws_mbedtls && cp build/ws/ws /usr/local/bin/ws && ws send --verify_none wss://localhost:8766 /tmp/big_file
```

View File

@ -1,36 +0,0 @@
#!/usr/bin/env python
# WS server example
import asyncio
import os
import websockets
clients = set()
async def echo(websocket, path):
clients.add(websocket)
try:
while True:
msg = await websocket.recv()
for ws in clients:
if ws != websocket:
print(f'Sending {len(msg)} bytes to {ws}')
await ws.send(msg)
except websockets.exceptions.ConnectionClosedOK:
print('Client terminating')
clients.remove(websocket)
host = os.getenv('BIND_HOST', 'localhost')
print(f'Serving on {host}:8766')
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -1,43 +0,0 @@
#!/usr/bin/env python
# WS server example
import asyncio
import os
import pathlib
import ssl
import websockets
clients = set()
async def echo(websocket, path):
clients.add(websocket)
try:
while True:
msg = await websocket.recv()
for ws in clients:
if ws != websocket:
print(f'Sending {len(msg)} bytes to {ws}')
await ws.send(msg)
except websockets.exceptions.ConnectionClosedOK:
print('Client terminating')
clients.remove(websocket)
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('trusted-server-crt.pem',
'trusted-server-key.pem')
host = os.getenv('BIND_HOST', 'localhost')
print(f'Serving on {host}:8766')
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30, ssl=ssl_context)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -3,19 +3,20 @@
# WS server example
import asyncio
import os
import websockets
async def hello(websocket, path):
await websocket.send(f"> Welcome !")
async def echo(websocket, path):
msg = await websocket.recv()
print(f'Received {len(msg)} bytes')
await websocket.send(msg)
name = await websocket.recv()
print(f"< {name}")
host = os.getenv('BIND_HOST', 'localhost')
print(f'Serving on {host}:8766')
greeting = f"Hello {name}!"
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30)
await websocket.send(greeting)
print(f"> {greeting}")
start_server = websockets.serve(hello, 'localhost', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python
# WS server example
import asyncio
import websockets
async def hello(websocket, path):
await websocket.send(f"> Welcome !")
name = await websocket.recv()
print(f"< {name}")
greeting = f"Hello {name}!"
await websocket.send(greeting)
print(f"> {greeting}")
async def echo(websocket, path):
msg = await websocket.recv()
print(f'Received {len(msg)} bytes')
await websocket.send(msg)
print('Serving on localhost:8766')
start_server = websockets.serve(echo, 'localhost', 8766)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -1,27 +0,0 @@
#!/usr/bin/env python
# WS server example
import asyncio
import os
import pathlib
import ssl
import websockets
async def echo(websocket, path):
msg = await websocket.recv()
print(f'Received {len(msg)} bytes')
await websocket.send(msg)
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('trusted-server-crt.pem',
'trusted-server-key.pem')
host = os.getenv('BIND_HOST', 'localhost')
print(f'Serving on {host}:8766')
start_server = websockets.serve(echo, host, 8766, max_size=2 ** 30, ssl=ssl_context)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -1,16 +0,0 @@
#!/bin/sh
case $MODE in
echo_server)
python /usr/bin/echo_server.py
;;
echo_server_ssl)
python /usr/bin/echo_server_ssl.py
;;
broadcast_server)
python /usr/bin/broadcast_server.py
;;
broadcast_server_ssl)
python /usr/bin/broadcast_server_ssl.py
;;
esac

View File

@ -1 +0,0 @@
trusted-client-crt.pem

View File

@ -1,9 +1,6 @@
all:
honcho start # install honcho (pip install honcho) or procman (the original ruby script)
.PHONY: docker
NAME := bsergean/echo_server
NAME := bsergean/ws_proxy
TAG := $(shell cat DOCKER_VERSION)
IMG := ${NAME}:${TAG}
LATEST := ${NAME}:latest
@ -21,15 +18,3 @@ docker_push:
docker tag ${IMG} ${LATEST}
docker push ${LATEST}
docker push ${IMG}
echo_server:
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=echo_server -it --rm bsergean/echo_server:build
echo_server_ssl:
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=echo_server_ssl -it --rm bsergean/echo_server:build
broadcast_server:
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=broadcast_server -it --rm bsergean/echo_server:build
broadcast_server_ssl:
docker run -p 8766:8766 -e BIND_HOST=0.0.0.0 -e MODE=broadcast_server_ssl -it --rm bsergean/echo_server:build

View File

@ -1,36 +0,0 @@
error_log stderr warn;
daemon off;
events {
worker_connections 32;
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server localhost:8766;
}
server {
listen 8765 ssl;
ssl_certificate trusted-client-crt.pem;
ssl_certificate_key trusted-client-key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}

View File

@ -1 +0,0 @@
not much in here

View File

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDLDCCAhSgAwIBAgIJALyEpMxNH62gMA0GCSqGSIb3DQEBCwUAMEExFDASBgNV
BAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDETMBEGA1UEAwwK
dHJ1c3RlZC1jYTAeFw0xOTEyMjQwMDM3MzVaFw0yMDEyMjMwMDM3MzVaMEUxFDAS
BgNVBAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDEXMBUGA1UE
AwwOdHJ1c3RlZC1jbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDFCipQ6OIJX15n2okHxuSkviuzcHzoYEzPhF6QXzKFbKhuzp4g0mMOXPvDKQE+
+dycGm6l1yg1pUuNKNxYjDWcSqOIqvDaOv9DkJCCNXpAGbh1CUmGdmp4HvwrzSIn
+3s/enC+zatcnwhrOyJk8k/9VqKlt+vB1++UAQV1eSX7adb/BemoyMguAQ8edAls
IiVSRrHRRyHy98j97jxX5lIdoC1FMv7Tj4suJA7wvTHlq3clpLL8t6dw1DAmBybK
ShUg9SC/T07WJ2cOo8wka+p7S/blh8qZwIy7kTgCI+SYgRfEOA94u9A9mDqp295h
DCghN2UdU3hh1k7SChI/owLpAgMBAAGjIzAhMB8GA1UdEQQYMBaCCWxvY2FsaG9z
dIIJMTI3LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4IBAQAtsbBGLUxABNH5yoRbk0o3
sGFMVkNDKkCE24BVkUfNyKUxLQWMknw3B4bmhrC8ZQPRk069ERV0ZR6eB2/9EG9s
Pzy4JbMwWrP5c0UIMJRk3w8ev9FXrsKwG6VhIPnvAdbJEis+7eDmYgpvmsbsYRmG
cqJcWvDKffki52Gbr9WgxLpqCGc2XMGr1Y1jU73Y4zmOeNLiU6HRKimNtGjqx/Tx
QoGVTNwki4TQTwQIyJ+HOj0c49IDJ93GbW5aymOT/e1IXDe07e9yg1r80bdFn23X
9bmRagT1/qu8lXfOpQA0foYeSJRSN7gITPmo7G2ogGVr6dZwhAHDYYy2pwW32j7o
-----END CERTIFICATE-----

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxQoqUOjiCV9eZ9qJB8bkpL4rs3B86GBMz4RekF8yhWyobs6e
INJjDlz7wykBPvncnBpupdcoNaVLjSjcWIw1nEqjiKrw2jr/Q5CQgjV6QBm4dQlJ
hnZqeB78K80iJ/t7P3pwvs2rXJ8IazsiZPJP/VaipbfrwdfvlAEFdXkl+2nW/wXp
qMjILgEPHnQJbCIlUkax0Uch8vfI/e48V+ZSHaAtRTL+04+LLiQO8L0x5at3JaSy
/LencNQwJgcmykoVIPUgv09O1idnDqPMJGvqe0v25YfKmcCMu5E4AiPkmIEXxDgP
eLvQPZg6qdveYQwoITdlHVN4YdZO0goSP6MC6QIDAQABAoIBAGMCJ58+Vg5FmKdw
vThmLY/GaykgVfNiKFaB+g5rd3Rp0/zR3804SkP2Xx+CpDijzsG12nGEupSyOVN1
+7qWwX2GV8QduSa/THMD2klDW+mHwxM0Fnj1WayATVApJIeYqyaLfMmziO7ijpVr
Qm4dACqZdOL2lwVxXtYs6TRNKtO4SIzmeVS39hmV2zeGmhUzI4hbirLOWBtbsPpl
qi5wyVkHoEVLnY376TOFc8u5+636yh6G2yqa/zsv9BBXG77DKWl659Fsd4DaUcRG
sk6CTH+I99aE0wrzSUuQmDR/IflxT+DP2ceNrCIc1h1oFzrBKh3fpFR3+D6SSGMn
r9Nk7LECgYEA/8CHrh2LLjqsLbqBoMUXthPwPrVGlK+KGb14+S8Pbfa2hDFWhoif
/FBWAD7GSXedjL3kxFSfmFxsDGPSyqqLRuZNaNs8Ar7vage6FYT6Vfh/8TYOToNr
8AHmhgQCg4luC8VGedCeEDVmUgkdJd/baoY8r3LKXaqsLxyBQN1Hzi0CgYEAxTsQ
jMFwACIdZHJKgUAdEA6PJM0HCS45F4116yqum99S4H10O1VdWK/vKeb13PK//25X
liXhjNHqcVLX08meqs561nKBWhbA72UU3oBAF4RNLHkbZMh1HtZGfBCfJ/Kmq12/
ZmGCwggUHhwnKD02hIGdffc+0eLTeCQL8HKi+S0CgYEA59+MpAXRHDbByCviPvqy
hrgJBzGfLksAsFmihnluScp2q993jT3tnvrPHiXL7OvwAZxg/seicqbIp2sRwAFj
iQJgiILMI8kskzsyMTSBKtTEWtMhoXlxsQZoFHUqOkutZCqVvPexdwyTGil9LcuJ
yUivWHqAku+ccJItdbup0HkCgYEAswkZzdvucoCFU+AX19o+R4wfzpU7FM9bzhCA
gTgehqojzlqzfwTPlqkmHlBk0Oue9BzS7x5172HCQpqkBsGYAY8rnK0W1JOhEe8d
EZk0FOTpNTy+bC83egWiuA5Sm22+dALGswZDLyUsNeTyeqmOapxKPcWJxfb0ZbO7
DsrRPAUCgYAzJm79VvEeRtwKhm0AcDSikJgNKojm6T6BIi/9QJyMTYlvGpBEwPBt
iqmqCqXGmUYafFApTUPyzmyDUsLfeHRwylvPn4UtYXPJ1UKGCVY3SWiJQi2CHSvC
gGSIifjzyeSjhw1cqzS2jHfu4lu6p2GBv/fyXLRVS7x6xY7OBinmvg==
-----END RSA PRIVATE KEY-----

View File

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDLDCCAhSgAwIBAgIJALyEpMxNH62fMA0GCSqGSIb3DQEBCwUAMEExFDASBgNV
BAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDETMBEGA1UEAwwK
dHJ1c3RlZC1jYTAeFw0xOTEyMjQwMDM3MzVaFw0yMDEyMjMwMDM3MzVaMEUxFDAS
BgNVBAoMC21hY2hpbmV6b25lMRQwEgYDVQQKDAtJWFdlYlNvY2tldDEXMBUGA1UE
AwwOdHJ1c3RlZC1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCv0T68TZZ7nab+UWPhssGLrInE0egzWn1AF20RkJv1ePIyU0rQbDxuuP+HQbXD
FzF6vo2j+5p+VxxvUOfko9V6xad3cB4T3AoFrT5sYI8gQX1uby6pjqVX16TK5t+c
i56aNhUXdmcWhuUzlIMIauvueohd+pNj6E6weWqCf8QFD6KYPgK3wWCR4VfWA5QY
RJUhv2aI9HrC9P4Mg0mut8LYURRQvGxOhtbAw76FJ6IgBujpgI5GLHgVK5Q1GlXK
8W7RlNKNmxX+mzK2D6nHixCUGvrFk9nZgZiaHI/h5x0IGXu0sbwlTPjqQ4Axpofw
G1FDi/er4FaGCzU4CKmc7rxRAgMBAAGjIzAhMB8GA1UdEQQYMBaCCWxvY2FsaG9z
dIIJMTI3LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4IBAQBkUB6smmApnBfr2eDwKJew
GQUMUAa7TlyANYlwQ6EjbAH7H6oNf7Sm63Go2Y72JjZPw3OvZl3QcvvS14QxYJ71
kRdvJ1mhEbIaA2QkdZCuDmcQGLfVEyo0j5q03amQKt9QtSv9MsX1Ok2HqGL17Tf1
QiUqlkzGCqMIsU20X8QzqwYCGzYZeTFtwLYi75za15Uo/6tE2KwzU7oUhuIebOaS
Sa+s2Y1TjpbWyw9usnuQWQ0k1FJR78F1mKJGghmPBoySBHJdLkLYOMhE1u2shgk5
N0muMcDRTeHLxm1aBPLHtkRbW3QscEQB6GkT2Dt4U66qNV2CY7Gk0F5xxOrGBC/9
-----END CERTIFICATE-----

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAr9E+vE2We52m/lFj4bLBi6yJxNHoM1p9QBdtEZCb9XjyMlNK
0Gw8brj/h0G1wxcxer6No/uaflccb1Dn5KPVesWnd3AeE9wKBa0+bGCPIEF9bm8u
qY6lV9ekyubfnIuemjYVF3ZnFoblM5SDCGrr7nqIXfqTY+hOsHlqgn/EBQ+imD4C
t8FgkeFX1gOUGESVIb9miPR6wvT+DINJrrfC2FEUULxsTobWwMO+hSeiIAbo6YCO
Rix4FSuUNRpVyvFu0ZTSjZsV/psytg+px4sQlBr6xZPZ2YGYmhyP4ecdCBl7tLG8
JUz46kOAMaaH8BtRQ4v3q+BWhgs1OAipnO68UQIDAQABAoIBAG/bIR2uAyJMT7UX
VQN/tbFGKTRmE2Owm2UOQl7dcMvAkd5AraViZyROYIvN23TuKZWc7AI7DbR5eWa8
w3vsW+JLI9tSImCiKmIoMUHEQOrVn5aF99r6HOmBEZ/hOLyg+1vDMrIFq1pioimp
v5+4XrgPjvizddgnMQEHjiLOZIiOtin+alixN/W41Ij0jOtRycM5wq3Xr/0RAs5A
ziNeQvWdvDwqa6L9upHZpFfYqP/+KflJPlHLfEkBHZtZQF3uy5tQ1VusfVMO3Xvb
Ljk6RBnD9dKayreD9NVzotr36zYEy/V1oGJcP/8AD1xmDA0/2Kb+bfm+WQHG5wp6
o09zsZECgYEA5Y3d79Nrfi6InVaZ0r5Y+XXqSZFTsgFnxRseVEbuK4jvrh7eC9jW
pWoaXDh8W6RoT59BPSCKtbQ9mjdECh+aJ6MOeCzCiGSppJboOhC1iVFqFuQLDRO7
w+2NgkhOvNnJJJYmdTwfokTLmaRUiNqwWAtBm+h7py9e5eXujzqt4+UCgYEAxBKL
OO8CWRb0yGlwKoCwYgGCsVauvbZHaELOAKJUB6H+YhZ+SJqd915u8aYs5nbcMyne
5kuewzd+32WpkykI0Fz4SrGvDETKB5/Yynblp9m69LNdgYoVWgQqQocXVw0nD/nA
KQdFSBZZRExXC/aUAa55txFJitMC4FjgTENgR/0CgYAS/OonxVg15sl8Ika1DPO1
JtDLZw8CQWWBA1494GQhC8GvqHP7jOMsaZtml3GJ7w6Fz4mI8eEnaJJT6FBjefu5
XZ57yFALEjCKIcVx0CIECsz4ucJEQaadbU/wP+TrcCRYN2dU+TUwqfohaltnupct
oTi7Gb7otF1oLN3P0S3DFQKBgEnVjdXPszunOGBrzBBFS6ZsWTG8qarJBFTPq1Fz
z17ccrWvMLjYeJnZVr/qyseyhLNDlit02IE82ar4VoYTEr2b9Ofzxy5AjS+X0wRT
B6JQjGVvUcvhGq8+GEfbJT/jtQ0ACIuqsD04JT9h2/mmTg/gCveUK/R6B4BCF5zA
VnZlAoGBANOG5T7KsOH+Hbb//dEmfZYMQmkO/+1Pac9eP4uDFNAVF00M6XHf5LrR
gRp5t46drDtLgxdufN0oUItp8y74EuMa9FHlBQVZRaSqYF4bCgf2PieGApbKWG2n
QhnxYfZqf9S2oVK95EHiJxmtumOFBL7YI9NdzNEeoJExS5Bw6kUn
-----END RSA PRIVATE KEY-----

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python3
# websocket send client
import argparse
import asyncio
import websockets
async def send(url, path):
async with websockets.connect(url, ping_timeout=None, ping_interval=None) as ws:
with open(path, 'rb') as f:
message = f.read()
print('Sending message...')
await ws.send(message)
print('Message sent.')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='websocket proxy.')
parser.add_argument('--path', help='Path to the file to send.',
default='small_file')
parser.add_argument('--url', help='Remote websocket url',
default='wss://echo.websocket.org')
args = parser.parse_args()
asyncio.get_event_loop().run_until_complete(send(args.url, args.path))

View File

@ -1,45 +0,0 @@
#/bin/sh
ver_gt() {
[ "$1" != "$2" ] && [ "$2" == "$(echo "$1\n$2" | sort -V | head -n1)" ]
}
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$(dirname ${SCRIPT_DIR})"
CUR_VSN=$(bash $SCRIPT_DIR/extract_version.sh)
NEW_VSN="$1"
check_ver() {
if [[ $NEW_VSN =~ ^[0-9.]+$ ]]; then
:
else
echo "Invalid version '$NEW_VSN'"
exit 1
fi
}
check_ver_increase() {
if ! ver_gt $NEW_VSN $CUR_VSN; then
echo "Invalid version '$NEW_VSN'. Must be greater than current version $CUR_VSN"
exit 1
fi
}
check_changelog() {
if ! egrep "\b$NEW_VSN\b" $PROJECT_ROOT/docs/CHANGELOG.md >/dev/null; then
echo "Invalid version '$NEW_VSN'. Missing entry in CHANGELOG.md"
exit 1
fi
}
set_version() {
sed -i '' "s/$CUR_VSN/$NEW_VSN/g" $PROJECT_ROOT/ixwebsocket/IXWebSocketVersion.h
echo "Set version to '$NEW_VSN'"
exit 0
}
check_ver
check_ver_increase
check_changelog
set_version

View File

@ -25,8 +25,6 @@ include_directories(ws ../third_party/statsd-client-cpp/src)
include_directories(ws ../third_party/spdlog/include)
include_directories(ws ../third_party/cpp-linenoise)
add_definitions(-DSPDLOG_COMPILED_LIB=1)
if (UNIX)
set( STATSD_CLIENT_SOURCES ../third_party/statsd-client-cpp/src/statsd_client.cpp)
endif()
@ -65,7 +63,6 @@ add_executable(ws
ws_autobahn.cpp
ws_proxy_server.cpp
ws_sentry_minidump_upload.cpp
ws_dns_lookup.cpp
ws.cpp)
target_link_libraries(ws ixsnake)
@ -75,8 +72,6 @@ target_link_libraries(ws ixcrypto)
target_link_libraries(ws ixcore)
target_link_libraries(ws ixsentry)
target_link_libraries(ws spdlog)
if(NOT APPLE AND NOT USE_MBED_TLS)
find_package(OpenSSL REQUIRED)
add_definitions(${OPENSSL_DEFINITIONS})

View File

@ -11,6 +11,7 @@
#include <cli11/CLI11.hpp>
#include <fstream>
#include <iostream>
#include <ixcore/utils/IXCoreLogger.h>
#include <ixwebsocket/IXNetSystem.h>
#include <ixwebsocket/IXSocket.h>
@ -21,9 +22,6 @@
#ifndef _WIN32
#include <signal.h>
#else
#include <process.h>
#define getpid _getpid
#endif
@ -41,13 +39,12 @@ int main(int argc, char** argv)
// Display command.
if (getenv("DEBUG"))
{
std::stringstream ss;
ss << "Command: ";
std::cout << "Command: ";
for (int i = 0; i < argc; ++i)
{
ss << argv[i] << " ";
std::cout << argv[i] << " ";
}
spdlog::info(ss.str());
std::cout << std::endl;
}
CLI::App app {"ws is a websocket tool"};
@ -94,12 +91,10 @@ int main(int argc, char** argv)
bool disableAutomaticReconnection = false;
bool disablePerMessageDeflate = false;
bool greetings = false;
bool ipv6 = false;
bool binaryMode = false;
bool redirect = false;
bool version = false;
bool verifyNone = false;
bool disablePong = false;
int port = 8008;
int redisPort = 6379;
int statsdPort = 8125;
@ -110,7 +105,6 @@ int main(int argc, char** argv)
int count = 1;
int jobs = 4;
uint32_t maxWaitBetweenReconnectionRetries;
size_t maxQueueSize = 100;
auto addTLSOptions = [&tlsOptions, &verifyNone](CLI::App* app) {
app->add_option(
@ -127,7 +121,7 @@ int main(int argc, char** argv)
app->add_flag("--verify_none", verifyNone, "Disable peer cert verification");
};
app.add_flag("--version", version, "Print ws version");
app.add_flag("--version", version, "Connection url");
CLI::App* sendApp = app.add_subcommand("send", "Send a file");
sendApp->add_option("url", url, "Connection url")->required();
@ -135,7 +129,6 @@ int main(int argc, char** argv)
->required()
->check(CLI::ExistingPath);
sendApp->add_option("--pidfile", pidfile, "Pid file");
sendApp->add_flag("-x", disablePerMessageDeflate, "Disable per message deflate");
addTLSOptions(sendApp);
CLI::App* receiveApp = app.add_subcommand("receive", "Receive a file");
@ -173,8 +166,6 @@ int main(int argc, char** argv)
echoServerApp->add_option("--port", port, "Port");
echoServerApp->add_option("--host", hostname, "Hostname");
echoServerApp->add_flag("-g", greetings, "Verbose");
echoServerApp->add_flag("-6", ipv6, "IpV6");
echoServerApp->add_flag("-x", disablePerMessageDeflate, "Disable per message deflate");
addTLSOptions(echoServerApp);
CLI::App* broadcastServerApp = app.add_subcommand("broadcast_server", "Broadcasting server");
@ -277,9 +268,6 @@ int main(int argc, char** argv)
cobra2sentry->add_option("--rolesecret", rolesecret, "Role secret")->required();
cobra2sentry->add_option("--dsn", dsn, "Sentry DSN");
cobra2sentry->add_option("--jobs", jobs, "Number of thread sending events to Sentry");
cobra2sentry->add_option("--queue_size",
maxQueueSize,
"Size of the queue to hold messages before they are sent to Sentry");
cobra2sentry->add_option("channel", channel, "Channel")->required();
cobra2sentry->add_flag("-v", verbose, "Verbose");
cobra2sentry->add_flag("-s", strict, "Strict mode. Error out when sending to sentry fails");
@ -311,7 +299,6 @@ int main(int argc, char** argv)
snakeApp->add_option("--apps_config_path", appsConfigPath, "Path to auth data")
->check(CLI::ExistingPath);
snakeApp->add_flag("-v", verbose, "Verbose");
snakeApp->add_flag("-d", disablePong, "Disable Pongs");
addTLSOptions(snakeApp);
CLI::App* httpServerApp = app.add_subcommand("httpd", "HTTP server");
@ -337,19 +324,12 @@ int main(int argc, char** argv)
addTLSOptions(proxyServerApp);
CLI::App* minidumpApp = app.add_subcommand("upload_minidump", "Upload a minidump to sentry");
minidumpApp->add_option("--minidump", minidump, "Minidump path")
->required()
->check(CLI::ExistingPath);
minidumpApp->add_option("--metadata", metadata, "Metadata path")
->required()
->check(CLI::ExistingPath);
minidumpApp->add_option("--minidump", minidump, "Minidump path")->check(CLI::ExistingPath);
minidumpApp->add_option("--metadata", metadata, "Hostname")->check(CLI::ExistingPath);
minidumpApp->add_option("--project", project, "Sentry Project")->required();
minidumpApp->add_option("--key", key, "Sentry Key")->required();
minidumpApp->add_flag("-v", verbose, "Verbose");
CLI::App* dnsLookupApp = app.add_subcommand("dnslookup", "DNS lookup");
dnsLookupApp->add_option("host", hostname, "Hostname")->required();
CLI11_PARSE(app, argc, argv);
// pid file handling
@ -375,7 +355,7 @@ int main(int argc, char** argv)
}
else if (app.got_subcommand("send"))
{
ret = ix::ws_send_main(url, path, disablePerMessageDeflate, tlsOptions);
ret = ix::ws_send_main(url, path, tlsOptions);
}
else if (app.got_subcommand("receive"))
{
@ -399,8 +379,7 @@ int main(int argc, char** argv)
}
else if (app.got_subcommand("echo_server"))
{
ret = ix::ws_echo_server_main(
port, greetings, hostname, tlsOptions, ipv6, disablePerMessageDeflate);
ret = ix::ws_echo_server_main(port, greetings, hostname, tlsOptions);
}
else if (app.got_subcommand("broadcast_server"))
{
@ -476,7 +455,6 @@ int main(int argc, char** argv)
verbose,
strict,
jobs,
maxQueueSize,
tlsOptions);
}
else if (app.got_subcommand("cobra_metrics_to_redis"))
@ -493,15 +471,8 @@ int main(int argc, char** argv)
}
else if (app.got_subcommand("snake"))
{
ret = ix::ws_snake_main(port,
hostname,
redisHosts,
redisPort,
redisPassword,
verbose,
appsConfigPath,
tlsOptions,
disablePong);
ret = ix::ws_snake_main(
port, hostname, redisHosts, redisPort, redisPassword, verbose, appsConfigPath, tlsOptions);
}
else if (app.got_subcommand("httpd"))
{
@ -523,17 +494,13 @@ int main(int argc, char** argv)
{
ret = ix::ws_sentry_minidump_upload(metadata, minidump, project, key, verbose);
}
else if (app.got_subcommand("dnslookup"))
{
ret = ix::ws_dns_lookup(hostname);
}
else if (version)
{
spdlog::info("ws {}", ix::userAgent());
std::cout << "ws " << ix::userAgent() << std::endl;
}
else
{
spdlog::error("A subcommand or --version is required");
std::cerr << "A subcommand or --version is required" << std::endl;
}
ix::uninitNetSystem();

12
ws/ws.h
View File

@ -29,10 +29,7 @@ namespace ix
int ws_echo_server_main(int port,
bool greetings,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions,
bool ipv6,
bool disablePerMessageDeflate);
const ix::SocketTLSOptions& tlsOptions);
int ws_broadcast_server_main(int port,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions);
@ -58,7 +55,6 @@ namespace ix
int ws_send_main(const std::string& url,
const std::string& path,
bool disablePerMessageDeflate,
const ix::SocketTLSOptions& tlsOptions);
int ws_redis_publish_main(const std::string& hostname,
@ -123,7 +119,6 @@ namespace ix
bool verbose,
bool strict,
int jobs,
size_t maxQueueSize,
const ix::SocketTLSOptions& tlsOptions);
int ws_cobra_metrics_to_redis(const std::string& appkey,
@ -143,8 +138,7 @@ namespace ix
const std::string& redisPassword,
bool verbose,
const std::string& appsConfigPath,
const ix::SocketTLSOptions& tlsOptions,
bool disablePong);
const ix::SocketTLSOptions& tlsOptions);
int ws_httpd_main(int port,
const std::string& hostname,
@ -167,6 +161,4 @@ namespace ix
const std::string& project,
const std::string& key,
bool verbose);
int ws_dns_lookup(const std::string& hostname);
} // namespace ix

View File

@ -32,6 +32,7 @@
#include <atomic>
#include <condition_variable>
#include <iostream>
#include <ixwebsocket/IXSocket.h>
#include <ixwebsocket/IXWebSocket.h>
#include <mutex>
@ -90,7 +91,7 @@ namespace ix
{
if (!_quiet)
{
spdlog::info(msg);
std::cerr << msg;
}
}
@ -182,7 +183,7 @@ namespace ix
webSocket.setOnMessageCallback([&condition, &success](const ix::WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Close)
{
spdlog::info("Report generated");
std::cerr << "Report generated" << std::endl;
condition.notify_one();
}
else if (msg->type == ix::WebSocketMessageType::Error)
@ -192,7 +193,7 @@ namespace ix
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
spdlog::info(ss.str());
std::cerr << ss.str() << std::endl;
success = false;
}
@ -235,7 +236,7 @@ namespace ix
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
spdlog::info(ss.str());
std::cerr << ss.str() << std::endl;
condition.notify_one();
}
@ -268,7 +269,7 @@ namespace ix
int ws_autobahn_main(const std::string& url, bool quiet)
{
int testCasesCount = getTestCaseCount(url);
spdlog::info("Test cases count: {}", testCasesCount);
std::cerr << "Test cases count: " << testCasesCount << std::endl;
if (testCasesCount == -1)
{

View File

@ -4,18 +4,17 @@
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixwebsocket/IXWebSocketServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
{
int ws_broadcast_server_main(int port,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions)
{
spdlog::info("Listening on {}:{}", hostname, port);
std::cout << "Listening on " << hostname << ":" << port << std::endl;
ix::WebSocketServer server(port, hostname);
server.setTLSOptions(tlsOptions);
@ -26,20 +25,20 @@ namespace ix
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
spdlog::info("New connection");
spdlog::info("id: {}", connectionState->getId());
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cerr << "New connection" << std::endl;
std::cerr << "id: " << connectionState->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cerr << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
spdlog::info("Closed connection: code {} reason {}",
msg->closeInfo.code,
msg->closeInfo.reason);
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
@ -48,31 +47,32 @@ namespace ix
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
spdlog::info(ss.str());
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Fragment)
{
spdlog::info("Received message fragment");
std::cerr << "Received message fragment" << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("Received {} bytes", msg->wireSize);
std::cerr << "Received " << msg->wireSize << " bytes" << std::endl;
for (auto&& client : server.getClients())
{
if (client != webSocket)
{
client->send(msg->str, msg->binary, [](int current, int total) -> bool {
spdlog::info("Step {} out of {}", current, total);
std::cerr << "Step " << current << " out of " << total << std::endl;
return true;
});
do
{
size_t bufferedAmount = client->bufferedAmount();
spdlog::info("{} bytes left to be sent", bufferedAmount);
std::cerr << bufferedAmount << " bytes left to be sent"
<< std::endl;
std::chrono::duration<double, std::milli> duration(500);
std::chrono::duration<double, std::milli> duration(10);
std::this_thread::sleep_for(duration);
} while (client->bufferedAmount() != 0);
}
@ -84,7 +84,7 @@ namespace ix
auto res = server.listen();
if (!res.first)
{
spdlog::info(res.second);
std::cerr << res.second << std::endl;
return 1;
}

View File

@ -14,7 +14,6 @@
#include <ixwebsocket/IXSocket.h>
#include <ixwebsocket/IXWebSocket.h>
#include <queue>
#include <spdlog/spdlog.h>
#include <sstream>
// for convenience
@ -56,7 +55,7 @@ namespace ix
void WebSocketChat::log(const std::string& msg)
{
spdlog::info(msg);
std::cout << msg << std::endl;
}
size_t WebSocketChat::getReceivedMessagesCount() const
@ -86,21 +85,20 @@ namespace ix
if (msg->type == ix::WebSocketMessageType::Open)
{
log("ws chat: connected");
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Handshake Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cout << it.first << ": " << it.second << std::endl;
}
spdlog::info("ws chat: user {} connected !", _user);
ss << "ws chat: user " << _user << " Connected !";
log(ss.str());
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
ss << "ws chat user disconnected: " << _user;
ss << " code " << msg->closeInfo.code;
ss << " reason " << msg->closeInfo.reason << std::endl;
ss << "ws chat: user " << _user << " disconnected !"
<< " code " << msg->closeInfo.code << " reason " << msg->closeInfo.reason;
log(ss.str());
}
else if (msg->type == ix::WebSocketMessageType::Message)
@ -164,26 +162,25 @@ namespace ix
int ws_chat_main(const std::string& url, const std::string& user)
{
spdlog::info("Type Ctrl-D to exit prompt...");
std::cout << "Type Ctrl-D to exit prompt..." << std::endl;
WebSocketChat webSocketChat(url, user);
webSocketChat.start();
while (true)
{
// Read line
std::string line;
std::string text;
std::cout << user << " > " << std::flush;
std::getline(std::cin, line);
std::getline(std::cin, text);
if (!std::cin)
{
break;
}
webSocketChat.sendMessage(line);
webSocketChat.sendMessage(text);
}
spdlog::info("");
std::cout << std::endl;
webSocketChat.stop();
return 0;

View File

@ -7,6 +7,7 @@
#include <atomic>
#include <chrono>
#include <fstream>
#include <iostream>
#include <ixcobra/IXCobraMetricsPublisher.h>
#include <jsoncpp/json/json.h>
#include <spdlog/spdlog.h>

View File

@ -7,6 +7,7 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <ixsnake/IXRedisClient.h>
#include <mutex>
@ -43,7 +44,8 @@ namespace ix
auto timer = [&msgPerSeconds, &msgCount] {
while (true)
{
spdlog::info("#messages {} msg/s {}", msgCount, msgPerSeconds);
std::cout << "#messages " << msgCount << " "
<< "msg/s " << msgPerSeconds << std::endl;
msgPerSeconds = 0;
auto duration = std::chrono::seconds(1);

View File

@ -7,6 +7,7 @@
#include <atomic>
#include <chrono>
#include <fstream>
#include <iostream>
#include <ixcobra/IXCobraMetricsPublisher.h>
#include <jsoncpp/json/json.h>
#include <mutex>
@ -90,10 +91,6 @@ namespace ix
spdlog::info("Published message id {} acked", msgId);
messageAcked = true;
}
else if (eventType == ix::CobraConnection_EventType_Pong)
{
spdlog::info("Received websocket pong");
}
});
conn.connect();

View File

@ -6,6 +6,7 @@
#include <atomic>
#include <chrono>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <spdlog/spdlog.h>
#include <sstream>
@ -40,7 +41,8 @@ namespace ix
auto timer = [&msgPerSeconds, &msgCount] {
while (true)
{
spdlog::info("#messages {} msg/s {}", msgCount, msgPerSeconds);
std::cout << "#messages " << msgCount << " "
<< "msg/s " << msgPerSeconds << std::endl;
msgPerSeconds = 0;
auto duration = std::chrono::seconds(1);
@ -75,7 +77,7 @@ namespace ix
[&jsonWriter, &quiet, &msgPerSeconds, &msgCount](const Json::Value& msg) {
if (!quiet)
{
spdlog::info(jsonWriter.write(msg));
std::cerr << jsonWriter.write(msg) << std::endl;
}
msgPerSeconds++;
@ -98,10 +100,6 @@ namespace ix
{
spdlog::error("Published message hacked: {}", msgId);
}
else if (eventType == ix::CobraConnection_EventType_Pong)
{
spdlog::info("Received websocket pong");
}
});
while (true)

View File

@ -7,9 +7,9 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <ixsentry/IXSentryClient.h>
#include <map>
#include <mutex>
#include <queue>
#include <spdlog/spdlog.h>
@ -19,79 +19,6 @@
namespace ix
{
class QueueManager
{
public:
QueueManager(size_t maxQueueSize, std::atomic<bool>& stop)
: _maxQueueSize(maxQueueSize)
, _stop(stop)
{
}
Json::Value pop();
void add(Json::Value msg);
private:
std::map<std::string, std::queue<Json::Value>> _queues;
std::mutex _mutex;
std::condition_variable _condition;
size_t _maxQueueSize;
std::atomic<bool>& _stop;
};
Json::Value QueueManager::pop()
{
std::unique_lock<std::mutex> lock(_mutex);
if (_queues.empty())
{
Json::Value val;
return val;
}
std::vector<std::string> games;
for (auto it : _queues)
{
games.push_back(it.first);
}
std::random_shuffle(games.begin(), games.end());
std::string game = games[0];
_condition.wait(lock, [this] { return !_stop; });
if (_queues[game].empty())
{
Json::Value val;
return val;
}
auto msg = _queues[game].front();
_queues[game].pop();
return msg;
}
void QueueManager::add(Json::Value msg)
{
std::unique_lock<std::mutex> lock(_mutex);
std::string game;
if (msg.isMember("device") && msg["device"].isMember("game"))
{
game = msg["device"]["game"].asString();
}
if (game.empty()) return;
// if the sending is not fast enough there is no point
// in queuing too many events.
if (_queues[game].size() < _maxQueueSize)
{
_queues[game].push(msg);
_condition.notify_one();
}
}
int ws_cobra_to_sentry_main(const std::string& appkey,
const std::string& endpoint,
const std::string& rolename,
@ -102,7 +29,6 @@ namespace ix
bool verbose,
bool strict,
int jobs,
size_t maxQueueSize,
const ix::SocketTLSOptions& tlsOptions)
{
ix::CobraConnection conn;
@ -121,7 +47,9 @@ namespace ix
std::atomic<bool> stop(false);
std::atomic<bool> throttled(false);
QueueManager queueManager(maxQueueSize, stop);
std::condition_variable condition;
std::mutex conditionVariableMutex;
std::queue<Json::Value> queue;
auto timer = [&sentCount, &receivedCount] {
while (true)
@ -135,118 +63,105 @@ namespace ix
std::thread t1(timer);
auto heartbeat = [&sentCount, &receivedCount] {
std::string state("na");
auto sentrySender = [&condition,
&conditionVariableMutex,
&queue,
verbose,
&errorSending,
&sentCount,
&stop,
&throttled,
&dsn] {
SentryClient sentryClient(dsn);
while (true)
{
std::stringstream ss;
ss << "messages received " << receivedCount;
ss << "messages sent " << sentCount;
Json::Value msg;
std::string currentState = ss.str();
if (currentState == state)
{
spdlog::error("no messages received or sent for 1 minute, exiting");
exit(1);
}
state = currentState;
std::unique_lock<std::mutex> lock(conditionVariableMutex);
condition.wait(lock, [&queue, &stop] { return !queue.empty() && !stop; });
auto duration = std::chrono::minutes(1);
std::this_thread::sleep_for(duration);
msg = queue.front();
queue.pop();
}
auto ret = sentryClient.send(msg, verbose);
HttpResponsePtr response = ret.first;
if (!response)
{
spdlog::warn("Null HTTP Response");
continue;
}
if (verbose)
{
for (auto it : response->headers)
{
spdlog::info("{}: {}", it.first, it.second);
}
spdlog::info("Upload size: {}", response->uploadSize);
spdlog::info("Download size: {}", response->downloadSize);
spdlog::info("Status: {}", response->statusCode);
if (response->errorCode != HttpErrorCode::Ok)
{
spdlog::info("error message: {}", response->errorMsg);
}
if (response->headers["Content-Type"] != "application/octet-stream")
{
spdlog::info("payload: {}", response->payload);
}
}
if (response->statusCode != 200)
{
spdlog::error("Error sending data to sentry: {}", response->statusCode);
spdlog::error("Body: {}", ret.second);
spdlog::error("Response: {}", response->payload);
errorSending = true;
// Error 429 Too Many Requests
if (response->statusCode == 429)
{
auto retryAfter = response->headers["Retry-After"];
std::stringstream ss;
ss << retryAfter;
int seconds;
ss >> seconds;
if (!ss.eof() || ss.fail())
{
seconds = 30;
spdlog::warn("Error parsing Retry-After header. "
"Using {} for the sleep duration",
seconds);
}
spdlog::warn("Error 429 - Too Many Requests. ws will sleep "
"and retry after {} seconds",
retryAfter);
throttled = true;
auto duration = std::chrono::seconds(seconds);
std::this_thread::sleep_for(duration);
throttled = false;
}
}
else
{
++sentCount;
}
if (stop) return;
}
};
std::thread t2(heartbeat);
auto sentrySender =
[&queueManager, verbose, &errorSending, &sentCount, &stop, &throttled, &dsn] {
SentryClient sentryClient(dsn);
while (true)
{
Json::Value msg = queueManager.pop();
if (msg.isNull()) continue;
if (stop) return;
auto ret = sentryClient.send(msg, verbose);
HttpResponsePtr response = ret.first;
if (!response)
{
spdlog::warn("Null HTTP Response");
continue;
}
if (verbose)
{
for (auto it : response->headers)
{
spdlog::info("{}: {}", it.first, it.second);
}
spdlog::info("Upload size: {}", response->uploadSize);
spdlog::info("Download size: {}", response->downloadSize);
spdlog::info("Status: {}", response->statusCode);
if (response->errorCode != HttpErrorCode::Ok)
{
spdlog::info("error message: {}", response->errorMsg);
}
if (response->headers["Content-Type"] != "application/octet-stream")
{
spdlog::info("payload: {}", response->payload);
}
}
if (response->statusCode != 200)
{
spdlog::error("Error sending data to sentry: {}", response->statusCode);
spdlog::error("Body: {}", ret.second);
spdlog::error("Response: {}", response->payload);
errorSending = true;
// Error 429 Too Many Requests
if (response->statusCode == 429)
{
auto retryAfter = response->headers["Retry-After"];
std::stringstream ss;
ss << retryAfter;
int seconds;
ss >> seconds;
if (!ss.eof() || ss.fail())
{
seconds = 30;
spdlog::warn("Error parsing Retry-After header. "
"Using {} for the sleep duration",
seconds);
}
spdlog::warn("Error 429 - Too Many Requests. ws will sleep "
"and retry after {} seconds",
retryAfter);
throttled = true;
auto duration = std::chrono::seconds(seconds);
std::this_thread::sleep_for(duration);
throttled = false;
}
}
else
{
++sentCount;
}
if (stop) return;
}
};
// Create a thread pool
spdlog::info("Starting {} sentry sender jobs", jobs);
std::cerr << "Starting " << jobs << " sentry sender jobs" << std::endl;
std::vector<std::thread> pool;
for (int i = 0; i < jobs; i++)
{
@ -260,11 +175,13 @@ namespace ix
verbose,
&throttled,
&receivedCount,
&queueManager](ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
&condition,
&conditionVariableMutex,
&queue](ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
if (eventType == ix::CobraConnection_EventType_Open)
{
spdlog::info("Subscriber connected");
@ -280,11 +197,16 @@ namespace ix
}
else if (eventType == ix::CobraConnection_EventType_Authenticated)
{
spdlog::info("Subscriber authenticated");
std::cerr << "Subscriber authenticated" << std::endl;
conn.subscribe(channel,
filter,
[&jsonWriter, verbose, &throttled, &receivedCount, &queueManager](
const Json::Value& msg) {
[&jsonWriter,
verbose,
&throttled,
&receivedCount,
&condition,
&conditionVariableMutex,
&queue](const Json::Value& msg) {
if (verbose)
{
spdlog::info(jsonWriter.write(msg));
@ -293,11 +215,18 @@ namespace ix
// If we cannot send to sentry fast enough, drop the message
if (throttled)
{
condition.notify_one();
return;
}
++receivedCount;
queueManager.add(msg);
{
std::unique_lock<std::mutex> lock(conditionVariableMutex);
queue.push(msg);
}
condition.notify_one();
});
}
else if (eventType == ix::CobraConnection_EventType_Subscribed)
@ -316,10 +245,6 @@ namespace ix
{
spdlog::error("Published message hacked: {}", msgId);
}
else if (eventType == ix::CobraConnection_EventType_Pong)
{
spdlog::info("Received websocket pong");
}
});
while (true)

View File

@ -6,7 +6,7 @@
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <ixcobra/IXCobraConnection.h>
#include <spdlog/spdlog.h>
#include <sstream>
@ -17,59 +17,6 @@
#include <statsd_client.h>
#endif
namespace
{
class QueueManager
{
public:
QueueManager(size_t maxQueueSize, std::atomic<bool>& stop)
: _maxQueueSize(maxQueueSize)
, _stop(stop)
{
}
Json::Value pop();
void add(Json::Value msg);
private:
std::queue<Json::Value> _queue;
std::mutex _mutex;
std::condition_variable _condition;
size_t _maxQueueSize;
std::atomic<bool>& _stop;
};
Json::Value QueueManager::pop()
{
std::unique_lock<std::mutex> lock(_mutex);
if (_queue.empty())
{
Json::Value val;
return val;
}
_condition.wait(lock, [this] { return !_stop; });
auto msg = _queue.front();
_queue.pop();
return msg;
}
void QueueManager::add(Json::Value msg)
{
std::unique_lock<std::mutex> lock(_mutex);
// if the sending is not fast enough there is no point
// in queuing too many events.
if (_queue.size() < _maxQueueSize)
{
_queue.push(msg);
_condition.notify_one();
}
}
} // namespace
namespace ix
{
// fields are command line argument that can be specified multiple times
@ -133,143 +80,87 @@ namespace ix
auto tokens = parseFields(fields);
Json::FastWriter jsonWriter;
std::atomic<uint64_t> sentCount(0);
std::atomic<uint64_t> receivedCount(0);
std::atomic<bool> stop(false);
size_t maxQueueSize = 1000;
QueueManager queueManager(maxQueueSize, stop);
auto timer = [&sentCount, &receivedCount] {
while (true)
{
spdlog::info("messages received {} sent {}", receivedCount, sentCount);
auto duration = std::chrono::seconds(1);
std::this_thread::sleep_for(duration);
}
};
std::thread t1(timer);
auto heartbeat = [&sentCount, &receivedCount] {
std::string state("na");
while (true)
{
std::stringstream ss;
ss << "messages received " << receivedCount;
ss << "messages sent " << sentCount;
std::string currentState = ss.str();
if (currentState == state)
{
spdlog::error("no messages received or sent for 1 minute, exiting");
exit(1);
}
state = currentState;
auto duration = std::chrono::minutes(1);
std::this_thread::sleep_for(duration);
}
};
std::thread t2(heartbeat);
auto statsdSender = [&queueManager, &host, &port, &sentCount, &tokens, &prefix, &stop] {
// statsd client
// test with netcat as a server: `nc -ul 8125`
bool statsdBatch = true;
// statsd client
// test with netcat as a server: `nc -ul 8125`
bool statsdBatch = true;
#ifndef _WIN32
statsd::StatsdClient statsdClient(host, port, prefix, statsdBatch);
statsd::StatsdClient statsdClient(host, port, prefix, statsdBatch);
#else
int statsdClient;
int statsdClient;
#endif
while (true)
Json::FastWriter jsonWriter;
uint64_t msgCount = 0;
conn.setEventCallback([&conn,
&channel,
&filter,
&jsonWriter,
&statsdClient,
verbose,
&tokens,
&prefix,
&msgCount](ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
if (eventType == ix::CobraConnection_EventType_Open)
{
Json::Value msg = queueManager.pop();
spdlog::info("Subscriber connected");
if (msg.isNull()) continue;
if (stop) return;
std::string id;
for (auto&& attr : tokens)
for (auto it : headers)
{
id += ".";
id += extractAttr(attr, msg);
spdlog::info("{}: {}", it.first, it.second);
}
}
if (eventType == ix::CobraConnection_EventType_Closed)
{
spdlog::info("Subscriber closed");
}
else if (eventType == ix::CobraConnection_EventType_Authenticated)
{
spdlog::info("Subscriber authenticated");
conn.subscribe(channel,
filter,
[&jsonWriter, &statsdClient, verbose, &tokens, &prefix, &msgCount](
const Json::Value& msg) {
if (verbose)
{
spdlog::info(jsonWriter.write(msg));
}
sentCount += 1;
std::string id;
for (auto&& attr : tokens)
{
id += ".";
id += extractAttr(attr, msg);
}
spdlog::info("{} {}{}", msgCount++, prefix, id);
#ifndef _WIN32
statsdClient.count(id, 1);
statsdClient.count(id, 1);
#endif
});
}
};
std::thread t3(statsdSender);
conn.setEventCallback(
[&conn, &channel, &filter, &jsonWriter, verbose, &queueManager, &receivedCount](
ix::CobraConnectionEventType eventType,
const std::string& errMsg,
const ix::WebSocketHttpHeaders& headers,
const std::string& subscriptionId,
CobraConnection::MsgId msgId) {
if (eventType == ix::CobraConnection_EventType_Open)
{
spdlog::info("Subscriber connected");
for (auto it : headers)
{
spdlog::info("{}: {}", it.first, it.second);
}
}
if (eventType == ix::CobraConnection_EventType_Closed)
{
spdlog::info("Subscriber closed");
}
else if (eventType == ix::CobraConnection_EventType_Authenticated)
{
spdlog::info("Subscriber authenticated");
conn.subscribe(channel,
filter,
[&jsonWriter, &queueManager, verbose, &receivedCount](
const Json::Value& msg) {
if (verbose)
{
spdlog::info(jsonWriter.write(msg));
}
receivedCount++;
++receivedCount;
queueManager.add(msg);
});
}
else if (eventType == ix::CobraConnection_EventType_Subscribed)
{
spdlog::info("Subscriber: subscribed to channel {}", subscriptionId);
}
else if (eventType == ix::CobraConnection_EventType_UnSubscribed)
{
spdlog::info("Subscriber: unsubscribed from channel {}", subscriptionId);
}
else if (eventType == ix::CobraConnection_EventType_Error)
{
spdlog::error("Subscriber: error {}", errMsg);
}
else if (eventType == ix::CobraConnection_EventType_Published)
{
spdlog::error("Published message hacked: {}", msgId);
}
else if (eventType == ix::CobraConnection_EventType_Pong)
{
spdlog::info("Received websocket pong");
}
});
else if (eventType == ix::CobraConnection_EventType_Subscribed)
{
spdlog::info("Subscriber: subscribed to channel {}", subscriptionId);
}
else if (eventType == ix::CobraConnection_EventType_UnSubscribed)
{
spdlog::info("Subscriber: unsubscribed from channel {}", subscriptionId);
}
else if (eventType == ix::CobraConnection_EventType_Error)
{
spdlog::error("Subscriber: error {}", errMsg);
}
else if (eventType == ix::CobraConnection_EventType_Published)
{
spdlog::error("Published message hacked: {}", msgId);
}
});
while (true)
{

View File

@ -5,10 +5,10 @@
*/
#include "linenoise.hpp"
#include <iostream>
#include <ixwebsocket/IXSocket.h>
#include <ixwebsocket/IXSocketTLSOptions.h>
#include <ixwebsocket/IXWebSocket.h>
#include <spdlog/spdlog.h>
#include <sstream>
@ -93,7 +93,7 @@ namespace ix
auto key = token.substr(0, pos);
auto val = token.substr(pos + 1);
spdlog::info("{}: {}", key, val);
std::cerr << key << ": " << val << std::endl;
headers[key] = val;
}
@ -129,11 +129,11 @@ namespace ix
if (msg->type == ix::WebSocketMessageType::Open)
{
log("ws_connect: connected");
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Handshake Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cout << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
@ -145,7 +145,7 @@ namespace ix
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("Received {} bytes", msg->wireSize);
std::cerr << "Received " << msg->wireSize << " bytes" << std::endl;
ss << "ws_connect: received message: " << msg->str;
log(ss.str());
@ -160,15 +160,15 @@ namespace ix
}
else if (msg->type == ix::WebSocketMessageType::Fragment)
{
spdlog::info("Received message fragment");
std::cerr << "Received message fragment" << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Ping)
{
spdlog::info("Received ping");
std::cerr << "Received ping" << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Pong)
{
spdlog::info("Received pong");
std::cerr << "Received pong" << std::endl;
}
else
{
@ -225,14 +225,14 @@ namespace ix
if (line == "/stop")
{
spdlog::info("Stopping connection...");
std::cout << "Stopping connection..." << std::endl;
webSocketChat.stop();
continue;
}
if (line == "/start")
{
spdlog::info("Starting connection...");
std::cout << "Starting connection..." << std::endl;
webSocketChat.start();
continue;
}
@ -243,7 +243,7 @@ namespace ix
linenoise::AddHistory(line.c_str());
}
spdlog::info("");
std::cout << std::endl;
webSocketChat.stop();
return 0;

View File

@ -1,34 +0,0 @@
/*
* ws_dns_lookup.cpp
* Author: Benjamin Sergeant
* Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
*/
#include <atomic>
#include <ixwebsocket/IXDNSLookup.h>
#include <ixwebsocket/IXNetSystem.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
{
int ws_dns_lookup(const std::string& hostname)
{
auto dnsLookup = std::make_shared<DNSLookup>(hostname, 80);
std::string errMsg;
struct addrinfo* res;
res = dnsLookup->resolve(errMsg, [] { return false; });
auto addr = res->ai_addr;
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr, str, INET_ADDRSTRLEN);
spdlog::info("host: {} ip: {}", hostname, str);
return 0;
}
} // namespace ix

View File

@ -4,9 +4,8 @@
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include <ixwebsocket/IXNetSystem.h>
#include <iostream>
#include <ixwebsocket/IXWebSocketServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -14,27 +13,13 @@ namespace ix
int ws_echo_server_main(int port,
bool greetings,
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions,
bool ipv6,
bool disablePerMessageDeflate)
const ix::SocketTLSOptions& tlsOptions)
{
spdlog::info("Listening on {}:{}", hostname, port);
ix::WebSocketServer server(port,
hostname,
SocketServer::kDefaultTcpBacklog,
SocketServer::kDefaultMaxConnections,
WebSocketServer::kDefaultHandShakeTimeoutSecs,
(ipv6) ? AF_INET6 : AF_INET);
std::cout << "Listening on " << hostname << ":" << port << std::endl;
ix::WebSocketServer server(port, hostname);
server.setTLSOptions(tlsOptions);
if (disablePerMessageDeflate)
{
spdlog::info("Disable per message deflate");
server.disablePerMessageDeflate();
}
server.setOnConnectionCallback(
[greetings](std::shared_ptr<ix::WebSocket> webSocket,
std::shared_ptr<ConnectionState> connectionState) {
@ -42,13 +27,13 @@ namespace ix
[webSocket, connectionState, greetings](const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
spdlog::info("New connection");
spdlog::info("id: {}", connectionState->getId());
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cerr << "New connection" << std::endl;
std::cerr << "id: " << connectionState->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cerr << it.first << ": " << it.second << std::endl;
}
if (greetings)
@ -58,21 +43,22 @@ namespace ix
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
spdlog::info("Closed connection: client id {} code {} reason {}",
connectionState->getId(),
msg->closeInfo.code,
msg->closeInfo.reason);
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
spdlog::error("Connection error: {}", msg->errorInfo.reason);
spdlog::error("#retries: {}", msg->errorInfo.retries);
spdlog::error("Wait time(ms): {}", msg->errorInfo.wait_time);
spdlog::error("HTTP Status: {}", msg->errorInfo.http_status);
std::stringstream ss;
ss << "Connection error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("Received {} bytes", msg->wireSize);
std::cerr << "Received " << msg->wireSize << " bytes" << std::endl;
webSocket->send(msg->str, msg->binary);
}
});
@ -81,7 +67,7 @@ namespace ix
auto res = server.listen();
if (!res.first)
{
spdlog::error(res.second);
std::cerr << res.second << std::endl;
return 1;
}

View File

@ -5,10 +5,10 @@
*/
#include <fstream>
#include <iostream>
#include <ixwebsocket/IXHttpClient.h>
#include <ixwebsocket/IXSocketTLSOptions.h>
#include <ixwebsocket/IXWebSocketHttpHeaders.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -47,7 +47,7 @@ namespace ix
auto key = token.substr(0, pos);
auto val = token.substr(pos + 1);
spdlog::info("{}: {}", key, val);
std::cerr << key << ": " << val << std::endl;
headers[key] = val;
}
@ -76,7 +76,7 @@ namespace ix
auto key = token.substr(0, pos);
auto val = token.substr(pos + 1);
spdlog::info("{}: {}", key, val);
std::cerr << key << ": " << val << std::endl;
httpParameters[key] = val;
}
@ -108,9 +108,10 @@ namespace ix
args->maxRedirects = maxRedirects;
args->verbose = verbose;
args->compress = compress;
args->logger = [](const std::string& msg) { spdlog::info(msg); };
args->logger = [](const std::string& msg) { std::cout << msg; };
args->onProgressCallback = [](int current, int total) -> bool {
spdlog::info("Downloaded {} bytes out of {}", current, total);
std::cerr << "\r"
<< "Downloaded " << current << " bytes out of " << total;
return true;
};
@ -130,20 +131,20 @@ namespace ix
response = httpClient.post(url, httpParameters, args);
}
spdlog::info("");
std::cerr << std::endl;
for (auto it : response->headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cerr << it.first << ": " << it.second << std::endl;
}
spdlog::info("Upload size: {}", response->uploadSize);
spdlog::info("Download size: {}", response->downloadSize);
std::cerr << "Upload size: " << response->uploadSize << std::endl;
std::cerr << "Download size: " << response->downloadSize << std::endl;
spdlog::info("Status: {}", response->statusCode);
std::cerr << "Status: " << response->statusCode << std::endl;
if (response->errorCode != HttpErrorCode::Ok)
{
spdlog::info("error message: ", response->errorMsg);
std::cerr << "error message: " << response->errorMsg << std::endl;
}
if (!headersOnly && response->errorCode == HttpErrorCode::Ok)
@ -157,7 +158,7 @@ namespace ix
filename = output;
}
spdlog::info("Writing to disk: {}", filename);
std::cout << "Writing to disk: " << filename << std::endl;
std::ofstream out(filename);
out.write((char*) &response->payload.front(), response->payload.size());
out.close();
@ -166,13 +167,14 @@ namespace ix
{
if (response->headers["Content-Type"] != "application/octet-stream")
{
spdlog::info("payload: {}", response->payload);
std::cout << "payload: " << response->payload << std::endl;
}
else
{
spdlog::info("Binary output can mess up your terminal.");
spdlog::info("Use the -O flag to save the file to disk.");
spdlog::info("You can also use the --output option to specify a filename.");
std::cerr << "Binary output can mess up your terminal." << std::endl;
std::cerr << "Use the -O flag to save the file to disk." << std::endl;
std::cerr << "You can also use the --output option to specify a filename."
<< std::endl;
}
}
}

View File

@ -5,6 +5,7 @@
*/
#include <fstream>
#include <iostream>
#include <ixwebsocket/IXHttpServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
@ -31,7 +32,7 @@ namespace ix
auto res = server.listen();
if (!res.first)
{
spdlog::error(res.second);
std::cerr << res.second << std::endl;
return 1;
}

View File

@ -8,7 +8,6 @@
#include <ixwebsocket/IXSocket.h>
#include <ixwebsocket/IXSocketTLSOptions.h>
#include <ixwebsocket/IXWebSocket.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -41,7 +40,7 @@ namespace ix
void WebSocketPingPong::log(const std::string& msg)
{
spdlog::info(msg);
std::cout << msg << std::endl;
}
void WebSocketPingPong::stop()
@ -57,18 +56,18 @@ namespace ix
log(std::string("Connecting to url: ") + _url);
_webSocket.setOnMessageCallback([this](const ix::WebSocketMessagePtr& msg) {
spdlog::info("Received {} bytes", msg->wireSize);
std::cerr << "Received " << msg->wireSize << " bytes" << std::endl;
std::stringstream ss;
if (msg->type == ix::WebSocketMessageType::Open)
{
log("ping_pong: connected");
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Handshake Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cout << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
@ -128,7 +127,7 @@ namespace ix
int ws_ping_pong_main(const std::string& url, const ix::SocketTLSOptions& tlsOptions)
{
spdlog::info("Type Ctrl-D to exit prompt...");
std::cout << "Type Ctrl-D to exit prompt..." << std::endl;
WebSocketPingPong webSocketPingPong(url, tlsOptions);
webSocketPingPong.start();

View File

@ -4,8 +4,8 @@
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixwebsocket/IXWebSocketServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -44,7 +44,7 @@ namespace ix
const std::string& remoteUrl,
bool verbose)
{
spdlog::info("Listening on {}:{}", hostname, port);
std::cout << "Listening on " << hostname << ":" << port << std::endl;
ix::WebSocketServer server(port, hostname);
server.setTLSOptions(tlsOptions);
@ -61,39 +61,41 @@ namespace ix
// Server connection
state->webSocket().setOnMessageCallback([webSocket, state, verbose](
const WebSocketMessagePtr& msg) {
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
spdlog::info("New connection to remote server");
spdlog::info("id: {}", state->getId());
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cerr << "New connection" << std::endl;
std::cerr << "server id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cerr << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
spdlog::info("Closed remote server connection: client id {} code {} reason {}",
state->getId(),
msg->closeInfo.code,
msg->closeInfo.reason);
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
webSocket->close(msg->closeInfo.code, msg->closeInfo.reason);
state->setTerminated();
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
spdlog::error("Connection error: {}", msg->errorInfo.reason);
spdlog::error("#retries: {}", msg->errorInfo.retries);
spdlog::error("Wait time(ms): {}", msg->errorInfo.wait_time);
spdlog::error("HTTP Status: {}", msg->errorInfo.http_status);
std::stringstream ss;
ss << "Connection error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("Received {} bytes from server", msg->wireSize);
std::cerr << "Received " << msg->wireSize << " bytes from server" << std::endl;
if (verbose)
{
spdlog::info("payload {}", msg->str);
std::cerr << "payload " << msg->str << std::endl;
}
webSocket->send(msg->str, msg->binary);
@ -101,67 +103,67 @@ namespace ix
});
// Client connection
webSocket->setOnMessageCallback(
[state, remoteUrl, verbose](const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
webSocket->setOnMessageCallback([state, remoteUrl, verbose](
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
std::cerr << "New connection" << std::endl;
std::cerr << "client id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("New connection from client");
spdlog::info("id: {}", state->getId());
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
}
std::cerr << it.first << ": " << it.second << std::endl;
}
// Connect to the 'real' server
std::string url(remoteUrl);
url += msg->openInfo.uri;
state->webSocket().setUrl(url);
state->webSocket().disableAutomaticReconnection();
state->webSocket().start();
// Connect to the 'real' server
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
// connection with the remote server
while (state->webSocket().getReadyState() != ReadyState::Open)
{
spdlog::info("waiting for server connection establishment");
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
spdlog::info("server connection established");
}
else if (msg->type == ix::WebSocketMessageType::Close)
// we should sleep here for a bit until we've established the
// connection with the remote server
while (state->webSocket().getReadyState() != ReadyState::Open)
{
spdlog::info("Closed client connection: client id {} code {} reason {}",
state->getId(),
msg->closeInfo.code,
msg->closeInfo.reason);
state->webSocket().close(msg->closeInfo.code, msg->closeInfo.reason);
std::cerr << "waiting for server connection establishment" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
else if (msg->type == ix::WebSocketMessageType::Error)
std::cerr << "server connection established" << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
std::cerr << "Closed connection"
<< " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
state->webSocket().close(msg->closeInfo.code, msg->closeInfo.reason);
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
std::stringstream ss;
ss << "Connection error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
std::cerr << "Received " << msg->wireSize << " bytes from client" << std::endl;
if (verbose)
{
spdlog::error("Connection error: {}", msg->errorInfo.reason);
spdlog::error("#retries: {}", msg->errorInfo.retries);
spdlog::error("Wait time(ms): {}", msg->errorInfo.wait_time);
spdlog::error("HTTP Status: {}", msg->errorInfo.http_status);
std::cerr << "payload " << msg->str << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("Received {} bytes from client", msg->wireSize);
if (verbose)
{
spdlog::info("payload {}", msg->str);
}
state->webSocket().send(msg->str, msg->binary);
}
});
state->webSocket().send(msg->str, msg->binary);
}
});
});
auto res = server.listen();
if (!res.first)
{
spdlog::info(res.second);
std::cerr << res.second << std::endl;
return 1;
}

View File

@ -7,6 +7,7 @@
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <iostream>
#include <ixcrypto/IXBase64.h>
#include <ixcrypto/IXHash.h>
#include <ixcrypto/IXUuid.h>
@ -15,7 +16,6 @@
#include <ixwebsocket/IXWebSocket.h>
#include <msgpack11/msgpack11.hpp>
#include <mutex>
#include <spdlog/spdlog.h>
#include <sstream>
#include <vector>
@ -75,12 +75,12 @@ namespace ix
void WebSocketReceiver::log(const std::string& msg)
{
spdlog::info(msg);
std::cout << msg << std::endl;
}
void WebSocketReceiver::waitForConnection()
{
spdlog::info("{}: Connecting...", "ws_receive");
std::cout << "ws_receive: Connecting..." << std::endl;
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
_condition.wait(lock);
@ -88,7 +88,7 @@ namespace ix
void WebSocketReceiver::waitForMessage()
{
spdlog::info("{}: Waiting for message...", "ws_receive");
std::cout << "ws_receive: Waiting for message..." << std::endl;
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
_condition.wait(lock);
@ -124,7 +124,7 @@ namespace ix
void WebSocketReceiver::handleMessage(const std::string& str)
{
spdlog::info("ws_receive: Received message: {}", str.size());
std::cerr << "ws_receive: Received message: " << str.size() << std::endl;
std::string errMsg;
MsgPack data = MsgPack::parse(str, errMsg);
@ -134,17 +134,17 @@ namespace ix
return;
}
spdlog::info("id: {}", data["id"].string_value());
std::cout << "id: " << data["id"].string_value() << std::endl;
std::vector<uint8_t> content = data["content"].binary_items();
spdlog::info("ws_receive: Content size: {}", content.size());
std::cout << "ws_receive: Content size: " << content.size() << std::endl;
// Validate checksum
uint64_t cksum = ix::djb2Hash(content);
auto cksumRef = data["djb2_hash"].string_value();
spdlog::info("ws_receive: Computed hash: {}", cksum);
spdlog::info("ws_receive: Reference hash: {}", cksumRef);
std::cout << "ws_receive: Computed hash: " << cksum << std::endl;
std::cout << "ws_receive: Reference hash: " << cksumRef << std::endl;
if (std::to_string(cksum) != cksumRef)
{
@ -157,12 +157,12 @@ namespace ix
std::string filenameTmp = filename + ".tmp";
spdlog::info("ws_receive: Writing to disk: {}", filenameTmp);
std::cout << "ws_receive: Writing to disk: " << filenameTmp << std::endl;
std::ofstream out(filenameTmp);
out.write((char*) &content.front(), content.size());
out.close();
spdlog::info("ws_receive: Renaming {} to {}", filenameTmp, filename);
std::cout << "ws_receive: Renaming " << filenameTmp << " to " << filename << std::endl;
rename(filenameTmp.c_str(), filename.c_str());
std::map<MsgPack, MsgPack> pdu;
@ -170,7 +170,7 @@ namespace ix
pdu["id"] = data["id"];
pdu["filename"] = data["filename"];
spdlog::info("Sending ack to sender");
std::cout << "Sending ack to sender" << std::endl;
MsgPack msg(pdu);
_webSocket.sendBinary(msg.dump());
}
@ -192,11 +192,11 @@ namespace ix
_condition.notify_one();
log("ws_receive: connected");
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Handshake Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cout << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
@ -234,14 +234,6 @@ namespace ix
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
log(ss.str());
}
else if (msg->type == ix::WebSocketMessageType::Ping)
{
log("ws_receive: received ping");
}
else if (msg->type == ix::WebSocketMessageType::Pong)
{
log("ws_receive: received pong");
}
else
{
ss << "ws_receive: Invalid ix::WebSocketMessageType";
@ -267,7 +259,7 @@ namespace ix
std::chrono::duration<double, std::milli> duration(1000);
std::this_thread::sleep_for(duration);
spdlog::info("ws_receive: Done !");
std::cout << "ws_receive: Done !" << std::endl;
webSocketReceiver.stop();
}

View File

@ -4,8 +4,8 @@
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixsnake/IXRedisClient.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -20,7 +20,7 @@ namespace ix
RedisClient redisClient;
if (!redisClient.connect(hostname, port))
{
spdlog::info("Cannot connect to redis host");
std::cerr << "Cannot connect to redis host" << std::endl;
return 1;
}
@ -30,10 +30,10 @@ namespace ix
if (!redisClient.auth(password, authResponse))
{
std::stringstream ss;
spdlog::info("Cannot authenticated to redis");
std::cerr << "Cannot authenticated to redis" << std::endl;
return 1;
}
spdlog::info("Auth response: {}", authResponse);
std::cout << "Auth response: " << authResponse << ":" << port << std::endl;
}
std::string errMsg;
@ -41,7 +41,8 @@ namespace ix
{
if (!redisClient.publish(channel, message, errMsg))
{
spdlog::error("Error publishing to channel {} error {}", channel, errMsg);
std::cerr << "Error publishing to channel " << channel << "error: " << errMsg
<< std::endl;
return 1;
}
}

View File

@ -4,6 +4,7 @@
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixsnake/IXRedisServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
@ -19,7 +20,7 @@ namespace ix
auto res = server.listen();
if (!res.first)
{
spdlog::info(res.second);
std::cerr << res.second << std::endl;
return 1;
}

View File

@ -6,8 +6,8 @@
#include <atomic>
#include <chrono>
#include <iostream>
#include <ixsnake/IXRedisClient.h>
#include <spdlog/spdlog.h>
#include <sstream>
#include <thread>
@ -22,7 +22,7 @@ namespace ix
RedisClient redisClient;
if (!redisClient.connect(hostname, port))
{
spdlog::info("Cannot connect to redis host");
std::cerr << "Cannot connect to redis host" << std::endl;
return 1;
}
@ -32,10 +32,10 @@ namespace ix
if (!redisClient.auth(password, authResponse))
{
std::stringstream ss;
spdlog::info("Cannot authenticated to redis");
std::cerr << "Cannot authenticated to redis" << std::endl;
return 1;
}
spdlog::info("Auth response: {}", authResponse);
std::cout << "Auth response: " << authResponse << ":" << port << std::endl;
}
std::atomic<int> msgPerSeconds(0);
@ -44,7 +44,7 @@ namespace ix
auto callback = [&msgPerSeconds, &msgCount, verbose](const std::string& message) {
if (verbose)
{
spdlog::info("recived: {}", message);
std::cout << "received: " << message << std::endl;
}
msgPerSeconds++;
@ -52,13 +52,14 @@ namespace ix
};
auto responseCallback = [](const std::string& redisResponse) {
spdlog::info("Redis subscribe response: {}", redisResponse);
std::cout << "Redis subscribe response: " << redisResponse << std::endl;
};
auto timer = [&msgPerSeconds, &msgCount] {
while (true)
{
spdlog::info("#messages {} msg/s {}", msgCount, msgPerSeconds);
std::cout << "#messages " << msgCount << " "
<< "msg/s " << msgPerSeconds << std::endl;
msgPerSeconds = 0;
auto duration = std::chrono::seconds(1);
@ -68,10 +69,10 @@ namespace ix
std::thread t(timer);
spdlog::info("Subscribing to {} ...", channel);
std::cerr << "Subscribing to " << channel << "..." << std::endl;
if (!redisClient.subscribe(channel, responseCallback, callback))
{
spdlog::info("Error subscribing to channel {}", channel);
std::cerr << "Error subscribing to channel " << channel << std::endl;
return 1;
}

View File

@ -7,6 +7,7 @@
#include <chrono>
#include <condition_variable>
#include <fstream>
#include <iostream>
#include <ixcrypto/IXBase64.h>
#include <ixcrypto/IXHash.h>
#include <ixcrypto/IXUuid.h>
@ -15,7 +16,6 @@
#include <ixwebsocket/IXWebSocket.h>
#include <msgpack11/msgpack11.hpp>
#include <mutex>
#include <spdlog/spdlog.h>
#include <sstream>
#include <vector>
@ -37,7 +37,7 @@ namespace ix
void waitForConnection();
void waitForAck();
bool sendMessage(const std::string& filename, bool throttle);
void sendMessage(const std::string& filename, bool throttle);
private:
std::string _url;
@ -45,8 +45,6 @@ namespace ix
ix::WebSocket _webSocket;
bool _enablePerMessageDeflate;
std::atomic<bool> _connected;
std::mutex _conditionVariableMutex;
std::condition_variable _condition;
@ -58,7 +56,6 @@ namespace ix
const ix::SocketTLSOptions& tlsOptions)
: _url(url)
, _enablePerMessageDeflate(enablePerMessageDeflate)
, _connected(false)
{
_webSocket.disableAutomaticReconnection();
_webSocket.setTLSOptions(tlsOptions);
@ -71,12 +68,12 @@ namespace ix
void WebSocketSender::log(const std::string& msg)
{
spdlog::info(msg);
std::cout << msg << std::endl;
}
void WebSocketSender::waitForConnection()
{
spdlog::info("{}: Connecting...", "ws_send");
std::cout << "ws_send: Connecting..." << std::endl;
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
_condition.wait(lock);
@ -84,7 +81,7 @@ namespace ix
void WebSocketSender::waitForAck()
{
spdlog::info("{}: Waiting for ack...", "ws_send");
std::cout << "ws_send: Waiting for ack..." << std::endl;
std::unique_lock<std::mutex> lock(_conditionVariableMutex);
_condition.wait(lock);
@ -122,22 +119,18 @@ namespace ix
std::stringstream ss;
if (msg->type == ix::WebSocketMessageType::Open)
{
_connected = true;
_condition.notify_one();
log("ws_send: connected");
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cout << "Uri: " << msg->openInfo.uri << std::endl;
std::cout << "Handshake Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cout << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
_connected = false;
ss << "ws_send: connection closed:";
ss << " code " << msg->closeInfo.code;
ss << " reason " << msg->closeInfo.reason << std::endl;
@ -154,14 +147,14 @@ namespace ix
MsgPack data = MsgPack::parse(msg->str, errMsg);
if (!errMsg.empty())
{
spdlog::info("Invalid MsgPack response");
std::cerr << "Invalid MsgPack response" << std::endl;
return;
}
std::string id = data["id"].string_value();
if (_id != id)
{
spdlog::info("Invalid id");
std::cerr << "Invalid id" << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Error)
@ -173,18 +166,6 @@ namespace ix
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
log(ss.str());
}
else if (msg->type == ix::WebSocketMessageType::Ping)
{
spdlog::info("ws_send: received ping");
}
else if (msg->type == ix::WebSocketMessageType::Pong)
{
spdlog::info("ws_send: received pong");
}
else if (msg->type == ix::WebSocketMessageType::Fragment)
{
spdlog::info("ws_send: received fragment");
}
else
{
ss << "ws_send: Invalid ix::WebSocketMessageType";
@ -220,7 +201,7 @@ namespace ix
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now - _start);
_ms = milliseconds.count();
spdlog::info("{} completed in {} ms", _description, _ms);
std::cout << _description << " completed in " << _ms << "ms" << std::endl;
_reported = true;
}
@ -237,11 +218,11 @@ namespace ix
bool _reported;
};
bool WebSocketSender::sendMessage(const std::string& filename, bool throttle)
void WebSocketSender::sendMessage(const std::string& filename, bool throttle)
{
std::vector<uint8_t> content;
{
Bench bench("ws_send: load file from disk");
Bench bench("load file from disk");
content = load(filename);
}
@ -257,60 +238,33 @@ namespace ix
MsgPack msg(pdu);
auto serializedMsg = msg.dump();
spdlog::info("ws_send: sending {} bytes", serializedMsg.size());
Bench bench("Sending file through websocket");
_webSocket.sendBinary(msg.dump(), [throttle](int current, int total) -> bool {
std::cout << "ws_send: Step " << current << " out of " << total << std::endl;
Bench bench("ws_send: Sending file through websocket");
auto result =
_webSocket.sendBinary(serializedMsg, [this, throttle](int current, int total) -> bool {
spdlog::info("ws_send: Step {} out of {}", current + 1, total);
if (throttle)
{
std::chrono::duration<double, std::milli> duration(10);
std::this_thread::sleep_for(duration);
}
if (throttle)
{
std::chrono::duration<double, std::milli> duration(10);
std::this_thread::sleep_for(duration);
}
return _connected;
});
if (!result.success)
{
spdlog::error("ws_send: Error sending file.");
return false;
}
if (!_connected)
{
spdlog::error("ws_send: Got disconnected from the server");
return false;
}
spdlog::info("ws_send: sent {} bytes", serializedMsg.size());
return true;
});
do
{
size_t bufferedAmount = _webSocket.bufferedAmount();
spdlog::info("ws_send: {} bytes left to be sent", bufferedAmount);
std::cout << "ws_send: " << bufferedAmount << " bytes left to be sent" << std::endl;
std::chrono::duration<double, std::milli> duration(500);
std::chrono::duration<double, std::milli> duration(10);
std::this_thread::sleep_for(duration);
} while (_webSocket.bufferedAmount() != 0 && _connected);
} while (_webSocket.bufferedAmount() != 0);
if (_connected)
{
bench.report();
auto duration = bench.getDuration();
auto transferRate = 1000 * content.size() / duration;
transferRate /= (1024 * 1024);
spdlog::info("ws_send: Send transfer rate: {} MB/s", transferRate);
}
else
{
spdlog::error("ws_send: Got disconnected from the server");
}
return _connected;
bench.report();
auto duration = bench.getDuration();
auto transferRate = 1000 * content.size() / duration;
transferRate /= (1024 * 1024);
std::cout << "ws_send: Send transfer rate: " << transferRate << "MB/s" << std::endl;
}
void wsSend(const std::string& url,
@ -324,27 +278,21 @@ namespace ix
webSocketSender.waitForConnection();
spdlog::info("ws_send: Sending...");
if (webSocketSender.sendMessage(path, throttle))
{
webSocketSender.waitForAck();
spdlog::info("ws_send: Done !");
}
else
{
spdlog::error("ws_send: Error sending file.");
}
std::cout << "ws_send: Sending..." << std::endl;
webSocketSender.sendMessage(path, throttle);
webSocketSender.waitForAck();
std::cout << "ws_send: Done !" << std::endl;
webSocketSender.stop();
}
int ws_send_main(const std::string& url,
const std::string& path,
bool disablePerMessageDeflate,
const ix::SocketTLSOptions& tlsOptions)
{
bool throttle = false;
bool enablePerMessageDeflate = !disablePerMessageDeflate;
bool enablePerMessageDeflate = false;
wsSend(url, path, enablePerMessageDeflate, throttle, tlsOptions);
return 0;

View File

@ -48,6 +48,7 @@ namespace ix
// Read json data
std::string sentryMetadata = readBytes(metadataPath);
std::atomic<bool> done(false);
sentryClient.uploadMinidump(

View File

@ -5,8 +5,8 @@
*/
#include <fstream>
#include <iostream>
#include <ixsnake/IXSnakeServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace
@ -44,8 +44,7 @@ namespace ix
const std::string& redisPassword,
bool verbose,
const std::string& appsConfigPath,
const SocketTLSOptions& socketTLSOptions,
bool disablePong)
const SocketTLSOptions& socketTLSOptions)
{
snake::AppConfig appConfig;
appConfig.port = port;
@ -54,17 +53,16 @@ namespace ix
appConfig.redisPort = redisPort;
appConfig.redisPassword = redisPassword;
appConfig.socketTLSOptions = socketTLSOptions;
appConfig.disablePong = disablePong;
// Parse config file
auto str = readAsString(appsConfigPath);
if (str.empty())
{
spdlog::error("Cannot read content of {}", appsConfigPath);
std::cout << "Cannot read content of " << appsConfigPath << std::endl;
return 1;
}
spdlog::error(str);
std::cout << str << std::endl;
auto apps = nlohmann::json::parse(str);
appConfig.apps = apps["apps"];

View File

@ -4,8 +4,8 @@
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
*/
#include <iostream>
#include <ixwebsocket/IXWebSocketServer.h>
#include <spdlog/spdlog.h>
#include <sstream>
namespace ix
@ -14,7 +14,7 @@ namespace ix
const std::string& hostname,
const ix::SocketTLSOptions& tlsOptions)
{
spdlog::info("Listening on {}:{}", hostname, port);
std::cout << "ws_transfer: Listening on " << hostname << ":" << port << std::endl;
ix::WebSocketServer server(port, hostname);
server.setTLSOptions(tlsOptions);
@ -25,23 +25,22 @@ namespace ix
const WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open)
{
spdlog::info("ws_transfer: New connection");
spdlog::info("id: {}", connectionState->getId());
spdlog::info("Uri: {}", msg->openInfo.uri);
spdlog::info("Headers:");
std::cerr << "ws_transfer: New connection" << std::endl;
std::cerr << "id: " << connectionState->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers)
{
spdlog::info("{}: {}", it.first, it.second);
std::cerr << it.first << ": " << it.second << std::endl;
}
}
else if (msg->type == ix::WebSocketMessageType::Close)
{
spdlog::info("ws_transfer: Closed connection: client id {} code {} reason {}",
connectionState->getId(),
msg->closeInfo.code,
msg->closeInfo.reason);
std::cerr << "ws_transfer: [client " << connectionState->getId()
<< "]: Closed connection, code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl;
auto remaining = server.getClients().erase(webSocket);
spdlog::info("ws_transfer: {} remaining clients", remaining);
std::cerr << "ws_transfer: " << remaining << " remaining clients " << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Error)
{
@ -50,43 +49,40 @@ namespace ix
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
spdlog::info(ss.str());
std::cerr << ss.str();
}
else if (msg->type == ix::WebSocketMessageType::Fragment)
{
spdlog::info("ws_transfer: Received message fragment ");
std::cerr << "ws_transfer: Received message fragment " << std::endl;
}
else if (msg->type == ix::WebSocketMessageType::Message)
{
spdlog::info("ws_transfer: Received {} bytes", msg->wireSize);
std::cerr << "ws_transfer: Received " << msg->wireSize << " bytes" << std::endl;
size_t receivers = 0;
for (auto&& client : server.getClients())
{
if (client != webSocket)
{
auto readyState = client->getReadyState();
auto id = connectionState->getId();
if (readyState == ReadyState::Open)
{
++receivers;
client->send(
msg->str, msg->binary, [&id](int current, int total) -> bool {
spdlog::info("{}: [client {}]: Step {} out of {}",
"ws_transfer",
id,
current,
total);
return true;
});
client->send(msg->str,
msg->binary,
[id = connectionState->getId()](int current,
int total) -> bool {
std::cerr << "ws_transfer: [client " << id
<< "]: Step " << current << " out of "
<< total << std::endl;
return true;
});
do
{
size_t bufferedAmount = client->bufferedAmount();
spdlog::info("{}: [client {}]: {} bytes left to send",
"ws_transfer",
id,
bufferedAmount);
std::cerr << "ws_transfer: [client " << connectionState->getId()
<< "]: " << bufferedAmount
<< " bytes left to be sent, " << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
@ -100,19 +96,16 @@ namespace ix
? "Connecting"
: readyState == ReadyState::Closing ? "Closing" : "Closed";
size_t bufferedAmount = client->bufferedAmount();
spdlog::info(
"{}: [client {}]: has readystate {} bytes left to be sent {}",
"ws_transfer",
id,
readyStateString,
bufferedAmount);
std::cerr << "ws_transfer: [client " << connectionState->getId()
<< "]: has readystate '" << readyStateString << "' and "
<< bufferedAmount << " bytes left to be sent, "
<< std::endl;
}
}
}
if (!receivers)
{
spdlog::info("ws_transfer: no remaining receivers");
std::cerr << "ws_transfer: no remaining receivers" << std::endl;
}
}
});
@ -121,7 +114,7 @@ namespace ix
auto res = server.listen();
if (!res.first)
{
spdlog::info(res.second);
std::cerr << res.second << std::endl;
return 1;
}