Compare commits

...

315 Commits

Author SHA1 Message Date
Peter Thorson 378437aecd Merge branch 'develop' 2016-02-22 08:30:10 -05:00
Peter Thorson cc7d74d8d0 Set version flags for release 2016-02-22 08:28:27 -05:00
Peter Thorson b154ac5907 Add FAQ entry 2016-02-22 08:28:05 -05:00
Peter Thorson 0348510c8d Fix minor issue in hybi00 subprotocol support patch. Update changelog for recent PRs 2016-02-21 18:30:58 -05:00
Peter Thorson a495c8c529 Merge branch 'develop' of https://github.com/zaphoyd/websocketpp into develop 2016-02-21 18:25:14 -05:00
Peter Thorson fabf8bf1ca clarified debugging output in connection read_handshake 2016-02-21 18:24:57 -05:00
Peter Thorson 3f913f97ef update tls version used in tls timer tests 2016-02-21 18:24:37 -05:00
Peter Thorson ffaeba2ec7 switch comment style in connection tests 2016-02-21 18:24:19 -05:00
Peter Thorson db304bfec4 Remove the use of cached read and write handlers in the asio transport. references #490 #525
There isn't a clean way to implement this performance optimization without adding global state/locking, which performs worse. This should fix
2016-02-21 18:23:58 -05:00
Peter Thorson d3bec51d25 Merge pull request #518 from lobermann/hixie76-hybi00-subprotocol-support
added subprotocol support for hybi00 / hixie76
2016-02-21 13:07:24 -05:00
Peter Thorson 8b672f7372 Merge pull request #524 from xavigibert/fix-uri
Fixed uri validator by checking its length.
2016-02-21 13:04:18 -05:00
Xavier Gibert Serra a4a79f6bf6 Fixed uri validator. This bug caused asan error heap-buffer-overflow when passing a short address. 2016-02-18 08:45:20 -08:00
Peter Thorson 9dc013a3aa Add an FAQ entry explaining how to use permessage-deflate in 0.6.0 and 0.7.0 2016-02-18 09:11:19 -05:00
Peter Thorson 931ad40b5f documentation & friend updates 2016-02-18 08:46:15 -05:00
Peter Thorson 842f745e24 Add echo_client example 2016-02-18 08:45:31 -05:00
Lukas Obermann e6f8766707 added subprotocol support for hybi00 / hixie76
This was missing but it is described in the RFC here
https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00#section-1.9
2016-02-10 17:07:02 +01:00
Peter Thorson 17a2647454 Apply tentative fix for explicitly destroying objects that use io_service before it is deleted 2016-02-08 07:32:57 -05:00
Peter Thorson 323dec4efc Merge branch 'strand-fix-1' into develop 2016-02-08 07:31:41 -05:00
Peter Thorson ee343fb282 Adjust use of strand to work better with composite asio operations. references #459
particularly affected TLS servers and connection close behavior
2016-02-08 07:31:06 -05:00
Peter Thorson b76422aa7a explicitly delete work and resolver object before deleting io_service references #510 2016-02-07 11:58:04 -05:00
Peter Thorson 563fcc6b45 wrap TLS async_shutdown in a strand references #459 #466 2016-02-07 11:26:00 -05:00
Peter Thorson b6014cc79b FAQ & Change log minor update 2016-02-02 09:39:12 -05:00
Peter Thorson d917f0924b Remove execute permission from sha1.hpp fixes #489 2016-01-31 15:14:44 -05:00
Peter Thorson e036a5aeab Also fix this use of auto_ptr 2016-01-31 15:11:33 -05:00
Peter Thorson ed335a37b5 Replace deprecated use of auto_ptr when unique_ptr is available 2016-01-31 11:07:36 -05:00
Peter Thorson bb4cbf3d03 Merge branch 'develop' of https://github.com/zaphoyd/websocketpp into develop 2016-01-19 09:34:43 -05:00
Peter Thorson a388817606 Initial work on utility_server tutorial 2016-01-19 09:33:18 -05:00
Peter Thorson b373f1ea6b Merge pull request #509 from mgeier/no-get-uri
telemetry_server: Remove unnecessary call to get_uri()
2016-01-19 09:30:23 -05:00
Peter Thorson 28448c77a5 Merge pull request #507 from mgeier/unneeded-typedef
Remove unneeded typedef from telemetry_server example
2016-01-19 09:29:07 -05:00
Peter Thorson ae097d6a93 Merge pull request #508 from mgeier/lock-guard
broadcast_server: replace explicit unlock() by scoped unlock
2016-01-19 09:28:56 -05:00
Matthias Geier 02f0026a00 telemetry_server: Remove unnecessary call to get_uri() 2016-01-19 13:22:34 +01:00
Matthias Geier aac65bdfd0 broadcast_server: replace explicit unlock() by scoped unlock
Also: Replace some instances of unique_lock with lock_guard.
2016-01-19 12:31:23 +01:00
Matthias Geier 7b368e67ed Remove unneeded typedef from telemetry_server example 2016-01-19 10:29:37 +01:00
Peter Thorson d0802994d8 Merge branch 'pr/502' into develop 2016-01-14 09:12:02 -05:00
Peter Thorson 20cc197967 Fix a few other misc test related things 2016-01-12 10:51:59 -05:00
Gregor Jasny 89df55c577 Register tests to CTest 2016-01-05 09:51:15 +01:00
Peter Thorson 9713455e94 Fix TLS+Asio Standalone builds 2015-12-20 09:36:46 -05:00
Peter Thorson 044eda9cc4 Merge pull request #493 from jchampio/dev/cancel_socket
Always log errors when cancelling sockets
2015-12-19 11:52:24 -05:00
Peter Thorson fc6ec59ab8 more travis updates 2015-12-17 08:11:23 -05:00
Peter Thorson a01cce3b1a travis update 2015-12-17 07:32:26 -05:00
Peter Thorson e1b39037f7 travis config update 2015-12-17 07:30:00 -05:00
Peter Thorson f54fb0669b more docs 2015-12-17 07:29:51 -05:00
Peter Thorson 935c8a3264 Begin update to migrate manual content into the git repository
The goal here is to get all the documentation in one place including
the class reference, text based manual, tutorials, etc.
2015-12-16 10:03:14 -05:00
Peter Thorson 1e12e7aff8 use c++11 thread support on recent visual studio versions (really) 2015-12-15 19:17:11 -05:00
Peter Thorson bda1bd14cb use c++11 thread support on recent visual studio versions 2015-12-15 19:13:37 -05:00
Jacob Champion 5f52127cf7 Always log errors during socket cancel
cancel_socket_checked(), which logs any received errors, is now called
consistently instead of the lower-level cancel_socket().
2015-12-15 15:06:01 -08:00
Jacob Champion 999add0c4b Improve socket cancellation error messages
log_err() includes information about the error code.
2015-12-15 15:04:41 -08:00
Jacob Champion f7448bb1b0 Write to the error log for socket cancel failures
Previously an elevel entry was being written to an alog (possible
copy-paste error?).
2015-12-15 14:40:10 -08:00
Peter Thorson ed45dcc617 Fix an issue where the wrong type of strand was being created. 2015-11-24 10:22:54 -05:00
Peter Thorson 7f19b6ea95 Merge pull request #485 from Meoo/patch-1
Fix make_shared using the wrong strand type
2015-11-24 10:04:03 -05:00
Bastien Brunnenstein 5b99feef7f Fix make_shared using the wrong strand type
Fix compilation with standalone ASIO (#462), where asio::strand and asio::io_service::strand are separate types.
This is the correct type, as m_strand is a ``lib::shared_ptr<lib::asio::io_service::strand>``
2015-11-24 15:24:52 +01:00
Peter Thorson b85affddf4 Test how some doxygen compatible markup behaves on github 2015-11-05 08:29:04 -05:00
Peter Thorson 5500aef4ce Allow accessing the local endpoint when using the Asio transport. fixes #458 2015-11-05 06:33:15 -05:00
Peter Thorson 4e2fb75d07 Removes non-standards compliant masking behavior. fixes #469, fixes #395 2015-10-30 09:26:28 -04:00
Peter Thorson 6a94162264 Fix error handling in debug_client fixes #473 2015-10-30 08:45:32 -04:00
Peter Thorson 536db87c53 Merge branch 'pr/468' into develop 2015-09-30 09:59:11 -04:00
Peter Thorson 39c5f3ae3d Update changelog 2015-09-30 09:56:57 -04:00
vladon cd4af122c0 avoid unnecessary empty strings ("") in favor of clear() and empty() (performance) 2015-09-29 21:36:41 +03:00
Peter Thorson b6817e4c7e Actually have the response status getters work; also tests 2015-09-19 10:54:50 -04:00
Peter Thorson 72e55a76b5 remove alias for better compatibility with older compilers 2015-09-17 10:09:28 -04:00
Peter Thorson 93b75ccc7d Add get_status and get_response methods to connection fixes #465 2015-09-17 10:09:07 -04:00
Peter Thorson 3e8dbf767d Add example demonstrating external io_service 2015-09-17 08:11:48 -04:00
Peter Thorson 3c77ce3cc7 Fix race condition resulting in corruption of responses sent from non-blocking HTTP handers
The HTTP request processing code was expecting that the http response
state would be `deferred` after a call to an HTTP handler that deferred
the response. If, in addition to deferring, you also sent the response
the HTTP state advanced past `deferred` to `response_written`. This
doesn't easily show up in unit tests because the bug requires that the
async write still be in flight and the connection still be open when
the HTTP handler returns.

An asynchronous network transport (like Asio) combined with a
sufficiently large message that Asio yields control back to WebSocket++
before the response is fully written will trigger a second write on the
same connection while the first is in flight. This is not allowed per
the Asio spec and results in undefined behavior.

The HTTP request processing code now checks if the http state is init,
i.e. not deferred and no response has been started rather than just if
it was deferred.
2015-09-09 10:14:37 -04:00
Peter Thorson 54ce641d02 remove tabs 2015-08-25 09:30:00 -04:00
Peter Thorson e0bd3f7e95 Address an issue where an exception could be thrown when a socket gets canceled on Windows XP #460
This fix switches to using the non-exception variant of socket::cancel
and logging the error instead of throwing it. There is a chance that
something else will need to be addressed as a result of this change as
some async operations might not be cancelled? I believe everything in
question has timeouts that will trigger operation cancellation at some
point anyways.
2015-08-25 09:03:00 -04:00
Peter Thorson fb829e0895 Misc changes related to translation of asio transport errors #448 2015-08-20 10:14:55 -04:00
Peter Thorson f9dbc0fd9d Merge branch 'pr/456' into develop 2015-08-06 09:12:05 -04:00
Peter Thorson 0b2b77e4ad update changelog 2015-08-06 09:11:50 -04:00
Eli Fidler 15c78afbf4 fix crash in strip_lws()
Before this fix, a malicious client could cause a websocketpp server to create an invalid std::string.
2015-08-04 12:01:14 -04:00
Peter Thorson 4b18214eda Add preliminary support for C++11 features in Visual Studio 2015 2015-08-01 12:38:18 -04:00
Peter Thorson e80673278f Merge branch 'pr/454' into develop 2015-07-29 09:29:37 -04:00
Peter Thorson 95551e7e94 code style & change log update for PR 2015-07-29 09:28:22 -04:00
Peter Thorson 22918a3992 Merge branch 'permessage-deflate' into develop
Conflicts:
	Doxyfile
	examples/utility_client/CMakeLists.txt
	websocketpp/version.hpp
2015-07-29 09:12:21 -04:00
Peter Thorson 9b09b0b481 Merge branch 'pr/449' into develop 2015-07-29 08:59:14 -04:00
Peter Thorson ef380f7fff Add CMake build support for examples and tests, zlib dependencies 2015-07-29 08:57:56 -04:00
Mark Grimes 1f504001d2 Use smart pointer to hold new io_service temporarily in case of errors 2015-07-29 12:36:22 +01:00
Peter Thorson c54f2abaab utility client build scripts 2015-07-23 07:53:51 -04:00
Peter Thorson 3580530902 Miscellaneous changes
- Updates code style
- Adds some tags for future exception free work
- Fix utility client build scripts
2015-07-23 07:53:31 -04:00
Thijs Wenker bc7ad6550e fixed typo 2015-07-16 12:18:32 +02:00
Thijs Wenker d3fe51fa39 Added missing CMake files, organized the CMake structure between test and example directories using the global variable USE_FOLDERS 2015-07-16 12:17:59 +02:00
Thijs Wenker 7514c82c92 CMake: properly include examples and tests with macro (added unit_test_framework dependency for unit tests) 2015-07-16 11:38:38 +02:00
Peter Thorson dabf32a668 Better std::chrono autodetection for Visual Studio 2015-06-05 08:49:07 -04:00
Peter Thorson 0d7052d2ae Merge branch 'master' into permessage-deflate
Update permessage-deflate to track latest release version.
2015-06-03 09:21:06 -04:00
Peter Thorson 39497aaa61 reset dev branch for work on next version 2015-06-02 08:59:10 -04:00
Peter Thorson c5510d6de0 Merge branch 'develop'
Conflicts:
	CMakeLists.txt
	Doxyfile
	changelog.md
	readme.md
	websocketpp/version.hpp
2015-06-02 08:55:24 -04:00
Peter Thorson f931734369 prep for release 2015-06-02 07:19:59 -04:00
Peter Thorson af792aeaba Update changelog 2015-06-02 07:02:48 -04:00
Peter Thorson 2af2135d82 Merge pull request #432 from rec/develop
Fix dangling pointer and message in error.hpp.
2015-06-02 06:59:04 -04:00
Tom Ritchford f2b38d5634 Fix dangling pointer and message in error.hpp. 2015-05-27 19:18:24 -04:00
Peter Thorson 1b9e40040c update readme 2015-05-10 21:36:19 -04:00
Peter Thorson 8893faff53 Removes an unnecessary mutex lock in get_con_from_hdl 2015-05-10 21:36:19 -04:00
Peter Thorson 430fb82e76 Fix typo in cmake files 2015-05-10 21:36:19 -04:00
Peter Thorson 01d4109ae8 Merge pull request #428 from timrau/develop
Fix grammar
2015-05-07 09:02:24 -04:00
timrau 4cc678ee93 Fix grammar 2015-05-07 21:00:09 +08:00
Peter Thorson acb53a379c Refactor deferred http handler support to better match the library conventions 2015-04-29 20:00:20 -04:00
Peter Thorson c18f210ea3 Allow deferring the sending of an HTTP response. references #425
This allows processing of long running http handlers to defer their
response until it is ready without blocking the network thread.
2015-04-29 19:28:36 -04:00
Peter Thorson f469b90bfc update changelog credit 2015-04-29 19:24:04 -04:00
Peter Thorson 9d95501536 changelog update 2015-04-25 13:32:33 -04:00
Peter Thorson 9351e73e90 initial sketch of TLS tutorial 2015-04-25 12:41:14 -04:00
Peter Thorson b817c4499e Updates echo_server_tls reference TLS settings 2015-04-25 12:28:28 -04:00
Peter Thorson 7829de34a3 Update changelog 2015-04-25 12:26:16 -04:00
Peter Thorson 6973f02d1c make sure boost version is loaded before using it 2015-04-25 12:25:17 -04:00
Peter Thorson 31b75714bd Update common/chrono.hpp to latest spec 2015-04-25 12:24:53 -04:00
Peter Thorson 257b5ac8e5 add boost chrono to travis dependencies 2015-04-25 07:33:26 -04:00
Peter Thorson 769fe89533 Major refactor to support standalone Asio and remove Boost dependencies
It is now possible to use WebSocket++’s asio transport using only
standalone asio by defining ASIO_STANDALONE before including any
WebSocket++ headers.
2015-04-25 07:17:28 -04:00
Peter Thorson d670d69c6e Refactor boost dependencies
Introduces a common type_traits header that supplies aligned_storage
using either boost or C++11.

removes unused boost header boost/array.hpp

removes usage of boost::noncopyable in favor of C++11 deleted copy
constructor/operators
2015-04-24 09:40:59 -04:00
Peter Thorson 2c843b9343 echo_server now checks for a special command to stop listening for new connections 2015-04-14 08:14:47 -04:00
Peter Thorson d076e38e00 properly set opcode on outgoing close frames 2015-04-14 07:58:34 -04:00
Peter Thorson 4331de8a29 Add missing header references #418 2015-04-14 06:56:30 -04:00
Peter Thorson 6dde40d96e Merge pull request #413 from rec/public-accessor
Make transport::asio::connection::get_strand() public.
2015-04-14 06:50:09 -04:00
Peter Thorson d68fd03e40 date fix 2015-04-02 09:56:22 -04:00
Peter Thorson e161ffde69 permessage deflate error category utility methods should be inline 2015-04-02 09:39:03 -04:00
Tom Ritchford dc313effa5 Make transport::asio::connection::get_strand() public. 2015-03-27 00:06:01 -04:00
Peter Thorson 6300e090ad disable emplace test
emplace requires move assignability which the class in question doesn’t
support.
2015-03-05 07:55:03 -06:00
Peter Thorson 45dfcbec3c changelog update 2015-03-04 18:43:49 -06:00
Peter Thorson 39dbe3a4e0 adds a vectored write handler for iostream transport 2015-03-04 18:42:55 -06:00
Peter Thorson 371d2cdaef Merge branch 'master' into permessage-deflate
Conflicts:
	websocketpp/version.hpp
2015-02-27 09:55:51 -05:00
Peter Thorson 13f6da6f81 fix typo in changelog entry about typos 2015-02-27 09:54:21 -05:00
Peter Thorson ac5d7ea5af changelog typo 2015-02-27 09:51:47 -05:00
Peter Thorson 6f7ecc59cd Bump patch version 2015-02-27 09:49:46 -05:00
Peter Thorson f7cea42c92 Fix a type in the name of the set method for max_http_body_size. fixes #406 2015-02-27 09:48:28 -05:00
Peter Thorson 9efb12e59b Fixes an issue where some frame data was counted against the max header size limit
End result was that connections that included a lot of frame data
immediately after the initial handshake would erroneously fail due to
hitting the max header size limit.
2015-02-27 09:48:00 -05:00
Peter Thorson 174698f1df update testee_server and testee_client Autobahn test examples to support permessage deflate 2015-02-27 07:48:45 -05:00
Peter Thorson 214cedf949 Update version info for permessage deflate branch 2015-02-27 07:48:08 -05:00
Peter Thorson c39412ee38 Update connection to negotiate extensions for clients 2015-02-27 07:47:31 -05:00
Peter Thorson 643e7a0ce1 Update processor to allow client side extension negotiation
Existing code worked for both client and server but the type signatures
needed some adjustment
2015-02-27 07:46:57 -05:00
Peter Thorson 349717ad46 set default extension offer string
Currently the offer is for default settings and advertises the ability
to accept any counteroffer.
2015-02-27 07:45:39 -05:00
Peter Thorson bcd82bd6f4 asio transport clients will now connect properly to servers using TLS SNI 2015-02-23 09:10:23 -05:00
Peter Thorson 8f042d95ec don't test for std::move on non-c++11 systems 2015-02-06 08:07:42 -05:00
Peter Thorson 0278ba7895 temporary disable of a unit test 2015-02-06 08:00:36 -05:00
Peter Thorson 41c37cfd93 make sure key is always initialized
some compilers complain without this. Its probably a safer sane default
anyways.
2015-02-06 07:58:00 -05:00
Peter Thorson 4bea90f555 preliminary support for move semantics for endpoints 2015-02-06 07:51:24 -05:00
Peter Thorson f9b08ccea1 Merge branch 'master' into permessage-deflate
Conflicts:
	websocketpp/extensions/permessage_deflate/enabled.hpp
2015-01-22 10:21:11 -05:00
Peter Thorson ce0300e6dc prepare develop branch for next version 2015-01-22 10:00:51 -05:00
Peter Thorson f20b2e573f Merge branch 'develop' 2015-01-22 09:56:40 -05:00
Peter Thorson 650e4c336b Prepare version 0.5.0 for submission 2015-01-22 09:56:20 -05:00
Peter Thorson 31c761a0a9 Endpoints are now reset after listen failure. fixes #390 2015-01-22 08:20:13 -05:00
Peter Thorson 681c2331a1 Fixes out of scope pointer returned from websocketpp::exception::what(); fixes #397
Also adds unit tests for exception construction
2015-01-22 07:33:14 -05:00
Peter Thorson fccc78479e retest 2015-01-20 08:29:02 -05:00
Peter Thorson 3017a9c5e4 increase test timeouts 2015-01-20 07:55:42 -05:00
Peter Thorson d55f28fe4b fix a bunch of minor warnings 2015-01-20 07:53:53 -05:00
Peter Thorson a8d4a9a66a increase test timeouts to help avoid false positives 2015-01-20 07:17:29 -05:00
Peter Thorson 17544d4d62 correct some documentation & fix warnings 2015-01-20 07:00:43 -05:00
Peter Thorson 4d1693c96c Merge branch 'master' into permessage-deflate
Conflicts:
	examples/print_server/print_server.cpp
	websocketpp/extensions/permessage_deflate/enabled.hpp
2015-01-20 06:51:06 -05:00
Peter Thorson 875d420952 Merge pull request #398 from rec/uninitialized-variable
Initialize websocketpp::transport::asio::endpoint::m_io_service to NULL.
2015-01-15 20:09:21 -06:00
Tom Ritchford d792639c20 Initialize websocketpp::transport::asio::endpoint::m_io_service to NULL. 2015-01-15 11:00:04 -05:00
Peter Thorson d4e15c89ad update changelog 2015-01-14 06:18:56 -06:00
Peter Thorson 1d29d48bb8 Merge pull request #393 from Schebb/develop
fixed 'localtime_*' compilation error MinGW
2015-01-14 06:12:58 -06:00
Peter Thorson 09c5f6505e Disable default use of C++11 threads on MinGW 2015-01-06 17:34:00 -06:00
Peter Thorson 745ed4f77a increase test timeout to help fail less on slow travis machines 2015-01-06 17:33:01 -06:00
Schebb 854166364b fixed 'localtime_*' compilation error MinGW 2015-01-06 13:23:53 +01:00
Peter Thorson 1517d646f9 update changelog, remove unused parameters 2014-12-16 07:05:47 -05:00
Peter Thorson 6bb36a28e7 typos 2014-12-16 06:38:37 -05:00
Peter Thorson 96362774a3 move this up a bit to ignore response status code 2014-12-16 06:36:34 -05:00
Peter Thorson 0a879a6dc2 add a check to gracefully exit if terminate was called during an http handler 2014-12-16 06:25:58 -05:00
Peter Thorson 867b323af0 add raw_head to http_request 2014-12-16 06:24:29 -05:00
Peter Thorson 9dd99ead25 gitignore debug stuff 2014-12-13 06:42:48 -05:00
Peter Thorson e3884e351b gitignore test 2014-12-13 06:41:12 -05:00
Peter Thorson 23e97bcc11 Better C++11 detection for visual studio 2014-12-13 06:24:52 -05:00
Peter Thorson 77e2e2fabb fix minor errors in debug transport 2014-12-13 05:55:31 -05:00
Peter Thorson ef393f8aef Overhaul error handling for failed WebSocket and HTTP connections 2014-12-12 18:31:21 -05:00
Peter Thorson 99f4a66221 Add processor error code for short hybi00 key3 reads 2014-12-12 18:08:05 -05:00
Peter Thorson 768472c0d4 get_websocket_version now checks if request is complete
an incomplete request otherwise would produce a spurious zero value
2014-12-12 18:07:32 -05:00
Peter Thorson 1f061a920e Changelog update 2014-12-12 06:59:53 -05:00
Peter Thorson 07543a5dde disable debugging output from tests 2014-12-11 10:29:41 -05:00
Peter Thorson ff9af5f8ca update gitignore to not ignore new debug code 2014-12-11 10:12:10 -05:00
Peter Thorson ffedb97372 move debug transport to non-relative path location 2014-12-11 10:09:28 -05:00
Peter Thorson e1f1c8873b Major overhaul to handshake internal state machine error checking references #389 #361
This overhaul removes the use of exceptions in handling state errors
during handshake processing. All such errors are demoted to
rerror/recoverable error and will terminate the connection only rather
than the whole application. In addition, there are some cases where we
expect to see a state error due to non-deterministic interleaving of
timeout handlers and read/write handlers. In these expected cases state
errors are ignored entirely.
2014-12-11 09:52:03 -05:00
Peter Thorson 922f1c35bc add testing system for timer/handshake handler interleaving
This interleaving is non-deterministic and pre-0.5 can result in state
errors when timer handers race with read/write handlers. These tests
explicitly and deterministically check all common interleaving for both
clients and servers.
2014-12-11 09:43:01 -05:00
Peter Thorson 3c6c757d93 debug client/server updates 2014-12-10 21:33:59 -05:00
Peter Thorson 71f88c71d6 better C++11 detection 2014-12-10 21:33:04 -05:00
Peter Thorson 987f20feda typos and fixes for stub config and minimal config 2014-12-10 21:28:18 -05:00
Peter Thorson 27cea4e58f don't set non-existent handler! 2014-12-08 19:35:47 -05:00
Peter Thorson e7b2e69ecb remove unneeded code 2014-12-08 19:26:24 -05:00
Peter Thorson bc868a244d queue for retest 2014-12-08 19:24:10 -05:00
Peter Thorson 77f1bf593d Adds telemetry_server example 2014-12-08 18:56:44 -05:00
Peter Thorson 0a47a9a78c adjust example exception behavior to match latest spec 2014-12-08 18:56:28 -05:00
Peter Thorson 6578c5852e Add Hybi proposed generic subprotocol errors 2014-12-05 21:02:33 -05:00
Peter Thorson f9ff42c4b0 update boundaries checking code to be slightly tigher 2014-12-05 21:02:33 -05:00
Peter Thorson b9d4187e38 logger documentation 2014-12-05 10:19:31 -05:00
Peter Thorson cbe887524e Documentation and code style for syslog logger references #386 2014-12-05 10:10:44 -05:00
Peter Thorson 8a9b0beec0 Merge pull request #386 from airtimemedia/syslog
Add syslog logger support.
2014-12-05 09:20:41 -05:00
Peter Thorson 18994f7318 Add write_handler to iostream as an ostream replacement 2014-12-04 09:12:57 -05:00
Peter Thorson 3f65b2ff98 changelog update 2014-12-04 08:19:16 -05:00
Peter Thorson 0ad2da2083 updates to debug server to help test HTTP request body issues 2014-12-04 08:16:32 -05:00
Peter Thorson 7404b506db Add shutdown handler to iostream transport references #388 2014-12-04 08:15:57 -05:00
Tom Hughes b0efc72848 Remove virtual methods from syslog implementation. 2014-12-02 10:06:28 -08:00
Tom Hughes beac6e5bb6 Add syslog logger support. 2014-11-26 14:14:09 -08:00
Peter Thorson f6c6552622 Access to HTTP request bodies references #181
Use connection::get_request_body() to access. Use
endpoint::set_max_http_body_size(size_t value) to control maximum
upload size. Initial support is for single chunk bodies that define a
content-length . Transfer-Encoding: chunked is not currently supported
2014-11-18 22:05:46 -05:00
Peter Thorson 12700f2bc2 implement HTTP request body parsing 2014-11-18 22:00:31 -05:00
Peter Thorson 8cbe22266d include cleanup 2014-11-18 21:58:47 -05:00
Peter Thorson c23639d394 const correctness 2014-11-18 21:58:17 -05:00
Peter Thorson d3ba1187de use C++ style c-library header 2014-11-18 08:18:20 -05:00
Peter Thorson 02b53d979e changelog update 2014-11-18 08:11:52 -05:00
Peter Thorson 1d598558d8 code style, correct more STL includes 2014-11-18 08:10:39 -05:00
Peter Thorson ff3009ed26 remove unused file 2014-11-18 07:53:27 -05:00
Peter Thorson d1f3eb9516 code style, correct STL includes 2014-11-18 07:52:36 -05:00
Peter Thorson c0dc3c0e5f add documentation, fix STL includes, remove deprecated HTTP parser methods 2014-11-18 07:25:45 -05:00
Peter Thorson bfbfe2b052 Clean up code style and STL includes 2014-11-18 07:13:34 -05:00
Peter Thorson 1edc8deb01 remove unnecessary include 2014-11-18 06:57:54 -05:00
Peter Thorson 571be82531 code style 2014-11-17 22:16:33 -05:00
Peter Thorson 9ab9941f5e remove unused type 2014-11-17 22:11:02 -05:00
Peter Thorson 7dfe0d5815 fix some utility client warnings 2014-11-15 13:02:29 -05:00
Peter Thorson 088625eb53 changelog typo 2014-11-15 12:55:53 -05:00
Peter Thorson 575834b534 utility_client tutorial updates 2014-11-15 12:52:19 -05:00
Peter Thorson 02dd5150fc Chapter 6 (sending/receiving message) of utility_client tutorial 2014-11-15 11:22:08 -05:00
Peter Thorson 2917d9262c share C++11 detection logic 2014-11-15 11:13:01 -05:00
Peter Thorson fbc2966cda Frame payload logging now prints text messages as text rather than binary 2014-11-14 09:31:53 -05:00
Peter Thorson 9de0a087b3 prepared messages now have correct opcode
This value is only used internally
2014-11-14 09:30:40 -05:00
Peter Thorson e9dd9cbbeb fix spelling error 2014-11-14 09:29:35 -05:00
Peter Thorson dc7431c37f http::request::raw should be const 2014-11-08 08:18:02 -05:00
Peter Thorson 5fe6f8338d Disable SSLv3 in example servers 2014-11-04 12:26:07 -05:00
Peter Thorson 19f7886ca4 reset dev branch versions to dev status 2014-11-04 12:23:30 -05:00
Peter Thorson 802e34bd2c Merge branch 'develop' 2014-11-04 07:35:10 -05:00
Peter Thorson 4100fc3ce7 normalize copyright dates and prep release version 2014-11-04 07:31:24 -05:00
Peter Thorson 6bda8f85d4 adjust C++11 cmake settings on windows 2014-11-04 06:52:44 -05:00
Peter Thorson 56cdbcd1da more gcc put_time debugging 2014-11-03 17:37:04 -05:00
Peter Thorson 4c15d27bf4 fixes an issue with signed/unsigned comparison 2014-11-03 14:39:34 -05:00
Peter Thorson b3b20ebb04 fix for non-threadsafe use of localtime fixes #347 2014-11-03 09:51:02 -05:00
Peter Thorson 397f5c00bf better fix for use of put_time
Put time can’t be activated by _WEBSOCKETPP_CPP11_STL_ due to backwards
compatibility issues with GCC 4.7 and 4.8 which otherwise work with
that define but do not support put_time
2014-11-03 09:48:43 -05:00
Peter Thorson 82502a651a run travis on develop branch 2014-11-03 08:59:29 -05:00
Peter Thorson b46c0fb142 adds std/boost::ref as needed for non-const references passed to make_shared
required for boost::make_shared to work without rvalue references.
2014-11-03 08:53:49 -05:00
Peter Thorson e1a0401d25 fixes guard macro for use of std::put_time
std::put_time is in the c++11 iomanip header not chrono
2014-11-02 19:12:16 -05:00
Peter Thorson f23abe8e70 Fix bug in chrono config by boost_config 2014-11-02 19:08:15 -05:00
Peter Thorson 4309749dd9 switch to alternate method of clearing function objects
may help with null_ptr related issues when using boost with c++11
compilers
2014-10-19 08:56:07 -04:00
Peter Thorson f06b623767 Merge pull request #379 from dnovikoff/develop
Using std/boost make_shared for creating shared pointers
2014-10-15 08:56:36 -04:00
Peter Thorson 9807283a6b Update sha1::calc length parameter to more sane type references #358
also cleans up formatting and code style and adds documentation
2014-10-14 22:17:57 -04:00
Peter Thorson 83a66f4e3f Update base64_encode length parameter to more sane type references #358
Also adds documentation and cleans up formatting
2014-10-14 08:28:26 -04:00
Peter Thorson 2e7a902ef7 prefix htonll/ntohll fixes #381 fixes #382 references #358
This avoids conflicts with OS level macros
2014-10-14 08:08:30 -04:00
Peter Thorson 55b6cfae90 Merge pull request #369 from codemercenary/gitignore
Updating ignore list for in-source MSVC CMake environments
2014-10-08 10:36:58 -04:00
Peter Thorson 95bfe7c5ba Merge pull request #377 from LocutusOfBorg/patch-2
Fix build failure if CMAKE_CXX_FLAGS is not empty
2014-10-08 10:31:09 -04:00
Dmitry Novikov f7aeeaaa30 Using std/boost make_shared for creating shared pointers
Fixed boost::function nulling issue
2014-10-08 16:11:46 +04:00
Gianfranco Costamagna 55827fc825 Fix build failure if CMAKE_CXX_FLAGS is not empty
The wrong " were adding a new parameter, leading to an expanded flag list like
"-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 ;-std=c++0x"
and an obvious
"g++-4.8.real: fatal error: no input files"
error message.
2014-10-08 10:05:59 +02:00
Peter Thorson d7a7112c8b removes unused qualifiers references #376 2014-10-07 10:17:02 -04:00
Peter Thorson d6c9905e80 fixes another shadowing warning 2014-10-07 10:16:28 -04:00
Peter Thorson 0e66dbfde4 lots of cleanup of unused code & parameters references #376 2014-10-07 10:11:37 -04:00
Peter Thorson e8d25d22bc adds documentation and removes unused parameters references #376 2014-10-07 10:04:54 -04:00
Peter Thorson fe6d82e7a3 fix local variable shadowing warning 2014-10-07 08:17:53 -04:00
Peter Thorson 2f64f8d91a adds documentation and removes unused parameters references #376 2014-10-06 19:04:04 -04:00
Peter Thorson 6da47743e8 removes unused function references #376 2014-10-06 18:34:13 -04:00
Peter Thorson 6c242b205b detab entire project references #376 2014-10-06 18:33:55 -04:00
codemercenary 2d2c62c887 Updating ignore list for in-source MSVC CMake environments 2014-08-20 11:35:35 -07:00
Peter Thorson 71a10d83c8 Merge core requirements feature branch 2014-08-09 16:18:00 -05:00
Peter Thorson fe0310b283 make version introduced notes less specific 2014-08-09 16:13:19 -05:00
Peter Thorson 8a7beaa86a Merge branch 'exception_refactor' into develop
Conflicts:
	changelog.md
	websocketpp/impl/connection_impl.hpp
2014-08-09 15:44:46 -05:00
Peter Thorson 5d0c2f6341 update version information for develop branch 2014-08-09 15:38:25 -05:00
Peter Thorson 122d4e2128 Reduce conflict between std::min and macros
Adjust usage of std::min to be more compatible with systems that define
a min(...) macro
2014-08-09 15:36:10 -05:00
Peter Thorson e203dbed45 package for 0.3.0 release 2014-08-09 14:06:22 -05:00
Peter Thorson ad2932bbff Disable open timeout when duration is set to zero 2014-07-24 21:39:12 -05:00
Peter Thorson 3560fa144a Merge pull request #359 from redboltz/add_semicolon
Added a semicolon.
2014-07-08 18:56:42 -05:00
Takatoshi Kondo 296f61b595 Added a semicolon. 2014-07-08 17:15:19 +09:00
Peter Thorson 65cc3765a8 add docs for namespaces and concurrency policies 2014-05-30 16:02:07 -05:00
Peter Thorson 10be5eee14 clarified documentation for bad_connection error 2014-05-30 16:02:07 -05:00
Peter Thorson c39777e4c1 add documentation for socket policies 2014-05-30 16:02:06 -05:00
Peter Thorson af7149ae0a Adds read_all method to iostream transport
Adds `connection::read_all(...)` method to iostream transport as a
convenience method for reading all data into the connection buffer
without the end user needing to manually loop on `read_some`.
2014-05-22 21:10:58 -05:00
Peter Thorson 7c3eb3e6c2 fix log wording 2014-05-22 21:10:57 -05:00
Peter Thorson e7ce038207 remove unused file 2014-04-10 10:53:41 -05:00
Peter Thorson aaed2c4950 fix whitespace 2014-04-10 10:20:26 -05:00
Peter Thorson 64fffeda9f Add combination plain+TLS echo example 2014-04-10 10:19:30 -05:00
Peter Thorson 7137105a81 documentation updates 2014-04-02 11:57:04 -05:00
Peter Thorson c021766592 these are not defined in RFC6455 2014-03-26 07:29:27 -05:00
Peter Thorson 7f7e9d2c2c update interface and unit tests for new permessage-deflate parameter names 2014-03-26 07:19:35 -05:00
Peter Thorson 70923eea23 remove raw cout debug code 2014-03-26 06:48:36 -05:00
Peter Thorson 99ae2f768c fix issue where fragmented messages weren't getting decompressed correctly
the rsv1 bit is only set for the first fragment. check it then and
store the result in the message’s compressed flag instead.
2014-03-26 06:48:26 -05:00
Peter Thorson 884e7d210c this is just wrong, removing 2014-03-26 06:47:28 -05:00
Peter Thorson 75dd6f3ba5 fix negotiating multiple copies of the same extension 2014-03-25 19:43:11 -05:00
Peter Thorson 2ee496c08d update parameter fields to latest draft 2014-03-25 19:35:24 -05:00
Peter Thorson aabf87b6b1 add missing tls libraries 2014-03-25 19:35:07 -05:00
Peter Thorson cfabe17e83 Merge branch 'master' into permessage-deflate
Conflicts:
	changelog.md
2014-03-25 19:16:19 -05:00
Peter Thorson b92a2b7f61 Merge branch 'master' into exception_refactor 2014-03-25 07:22:54 -05:00
Peter Thorson 1f73456e25 update changelog 2014-03-25 07:22:40 -05:00
Peter Thorson 0ca2bae121 Merge branch 'master' into core_dependencies
Conflicts:
	changelog.md
2014-03-25 07:17:12 -05:00
Peter Thorson 7a46203beb added a note about breaking changes in the logging policy API 2014-03-20 07:18:59 -05:00
Peter Thorson 497bc574da remove references to unused iostream header from asio transport 2014-03-20 07:15:02 -05:00
Peter Thorson 0bfb67ef11 Add minimal_client and minimal_server configs references #338 2014-03-20 07:03:31 -05:00
Peter Thorson 762c013b93 Adds a stub transport policy
This will be used in the minimal config to avoid bringing in iostream
dependencies. It will also be used to document the minimal interface
for writing a custom transport policy.
2014-03-20 07:02:40 -05:00
Peter Thorson 9d237effc7 remove dependency on std::iostream from core
It is still required for the iostream transport and the basic
(iostream) logging policy.
2014-03-20 06:10:24 -05:00
Peter Thorson a63f7d8b7b switch all exceptions to be of type websocketpp::exception 2014-03-06 19:35:25 -06:00
Peter Thorson 770b32275c updates websocketpp::exception to wrap lib::error_code 2014-03-05 08:30:08 -06:00
Peter Thorson e62823a0af update deflate constants 2013-10-16 06:29:46 -05:00
Peter Thorson 8ce05cd228 Merge branch 'master' into permessage-deflate
Conflicts:
	test/extension/permessage_deflate.cpp
	websocketpp/extensions/permessage_deflate/disabled.hpp
	websocketpp/extensions/permessage_deflate/enabled.hpp
	websocketpp/impl/connection_impl.hpp
	websocketpp/message_buffer/message.hpp
	websocketpp/processors/hybi13.hpp
2013-09-08 13:39:17 -05:00
Peter Thorson eb314e55de retry build 2013-07-15 11:08:05 -05:00
Peter Thorson ccbd93f725 add a debug mode switch 2013-07-15 10:41:32 -05:00
Peter Thorson be9a320fc1 Merge branch 'master' into permessage-deflate 2013-07-14 11:08:51 -05:00
Peter Thorson 9a73b74a37 fix to ensure empty messages are handled correctly 2013-07-12 08:37:08 -05:00
Peter Thorson 48add58dc2 update compression tests 2013-07-12 08:35:49 -05:00
Peter Thorson e967ffc74d silence stratch server 2013-07-12 08:30:51 -05:00
Peter Thorson 475c478a2e protect against compress returning nothing 2013-07-12 08:29:34 -05:00
Peter Thorson b8d962950f impliment no_context_takeover options 2013-07-10 20:16:19 -05:00
Peter Thorson ba0094a0eb Merge branch 'master' into permessage-deflate
Conflicts:
	examples/scratch_client/SConscript
2013-07-10 19:10:03 -05:00
Peter Thorson eb362007ab permessage_deflate tests 2013-07-09 07:14:14 -05:00
Peter Thorson 4d63c10be7 remove debug printing 2013-07-09 07:14:00 -05:00
Peter Thorson 28f949d955 Merge branch 'master' into permessage-deflate 2013-07-08 18:12:21 -05:00
Peter Thorson 11906dc2ce Adds is_server detection flag to deflate extension init 2013-07-08 16:15:45 -05:00
Peter Thorson c60e089553 add back to back message compression test 2013-07-08 16:10:03 -05:00
Peter Thorson b809bf3706 ensure that the masking key is initialized 2013-07-08 12:08:16 -05:00
Peter Thorson 6920b39aa2 fix unused variable 2013-07-08 12:00:29 -05:00
Peter Thorson f7376ccf46 fix missing return value 2013-07-08 12:00:21 -05:00
Peter Thorson 243cea16db update scratch examples 2013-07-08 11:58:43 -05:00
Peter Thorson 98a75b8cea fix order of masking key initialization and use 2013-07-08 11:52:51 -05:00
Peter Thorson 5323076007 update permessage_deflate tests 2013-07-08 11:43:15 -05:00
Peter Thorson d0d97b860b add permessage_deflate finalization code 2013-07-08 11:42:28 -05:00
Peter Thorson 25e8d522b2 refactor message finalization 2013-07-08 11:42:12 -05:00
Peter Thorson bd408944fd refactor message prep to determine payload size sooner 2013-07-08 11:38:42 -05:00
Peter Thorson 14aa71091f initialize deflate extension after it is negotiated 2013-07-08 11:37:29 -05:00
Peter Thorson 4607150f82 add error checking to decompress method 2013-07-08 11:36:52 -05:00
Peter Thorson 359f03fb1e Documentation 2013-07-08 11:36:00 -05:00
Peter Thorson 4a52e548fd compress outgoing messages by default if able 2013-07-08 11:35:43 -05:00
Peter Thorson 0501f77b57 Add additional development logging of incoming data 2013-07-08 11:35:29 -05:00
Peter Thorson 631261c365 correctly set avail_in for compression 2013-07-08 11:34:45 -05:00
Peter Thorson a90ccd83dd update error name to be more descriptive 2013-07-08 11:34:19 -05:00
Peter Thorson c103032e9c add init to extension interface 2013-07-08 11:34:07 -05:00
Peter Thorson c32bebba3e take over print server example for testing 2013-07-05 11:39:02 -05:00
Peter Thorson 6c6c6951e5 fix spelling error 2013-07-05 11:38:24 -05:00
Peter Thorson aeb0e8fa7d Merge branch 'master' into permessage-deflate 2013-07-03 06:32:22 -05:00
226 changed files with 13121 additions and 4341 deletions
+14
View File
@@ -32,11 +32,15 @@ install_manifest.txt
*.ncb
*/Debug/*
*/*/Debug/*
bin/Debug
*/Release/*
*/*/Release/*
*/RelWithDebInfo/*
*/*/RelWithDebInfo/*
# explicitly allow this path with /debug/ in it
!websocketpp/transport/debug/*
objs_shared/
objs_static/
@@ -78,3 +82,13 @@ examples/wsperf/wsperf_client
*.out
*.log
*.opensdf
*.sdf
*.vcxproj
*.vcxproj.filters
*.user
install
Makefile
bin
Testing/Temporary/CTestCostData.txt
+4 -5
View File
@@ -2,18 +2,17 @@ language: cpp
compiler:
- gcc
before_install:
- sudo apt-get install libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
#- sudo apt-get install libboost-chrono1.48-dev libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
- sudo add-apt-repository -y ppa:boost-latest/ppa && sudo apt-get update -q && sudo apt-get install -y libboost-chrono1.55-dev libboost-random1.55-dev libboost-regex1.55-dev libboost-system1.55-dev libboost-thread1.55-dev libboost-test1.55-dev
env:
global:
- BOOST_INCLUDES=/usr/include
- BOOST_LIBS=/usr/lib
- BOOST_LIBS=/usr/lib/x86_64-linux-gnu
script: scons -j 2 && scons test
branches:
only:
- master
- permessage-deflate
- experimental
- 0.3.x-cmake
- develop
notifications:
recipients:
- travis@zaphoyd.com
+32 -8
View File
@@ -9,10 +9,12 @@ project (websocketpp)
cmake_minimum_required (VERSION 2.6)
set (WEBSOCKETPP_MAJOR_VERSION 0)
set (WEBSOCKETPP_MINOR_VERSION 3)
set (WEBSOCKETPP_MINOR_VERSION 7)
set (WEBSOCKETPP_PATCH_VERSION 0)
set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
if (WIN32 AND NOT CYGWIN)
set (DEF_INSTALL_CMAKE_DIR cmake)
@@ -67,10 +69,12 @@ option (BUILD_TESTS "Build websocketpp tests." FALSE)
if (BUILD_TESTS OR BUILD_EXAMPLES)
enable_testing ()
############ Compiler specific setup
set (WEBSOCKETPP_PLATFORM_LIBS "")
set (WEBSOCKETPP_PLATFORM_TSL_LIBS "")
set (WEBSOCKETPP_PLATFORM_TLS_LIBS "")
set (WEBSOCKETPP_BOOST_LIBS "")
# VC9 and C++11 reasoning
@@ -87,7 +91,14 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
# C++11 defines
if (ENABLE_CPP11)
add_definitions (-D_WEBSOCKETPP_CPP11_STL_)
if (MSVC)
add_definitions (-D_WEBSOCKETPP_CPP11_FUNCTIONAL_)
add_definitions (-D_WEBSOCKETPP_CPP11_SYSTEM_ERROR_)
add_definitions (-D_WEBSOCKETPP_CPP11_RANDOM_DEVICE_)
add_definitions (-D_WEBSOCKETPP_CPP11_MEMORY_)
else()
add_definitions (-D_WEBSOCKETPP_CPP11_STL_)
endif()
endif ()
# Visual studio
@@ -104,9 +115,9 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
# g++
if (CMAKE_COMPILER_IS_GNUCXX)
set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
set (WEBSOCKETPP_PLATFORM_TSL_LIBS ssl crypto)
set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
set (WEBSOCKETPP_BOOST_LIBS system thread)
set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++0x")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
if (NOT APPLE)
add_definitions (-DNDEBUG -Wall -Wcast-align) # todo: should we use CMAKE_C_FLAGS for these?
endif ()
@@ -126,7 +137,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
else()
set (WEBSOCKETPP_PLATFORM_LIBS pthread)
endif()
set (WEBSOCKETPP_PLATFORM_TSL_LIBS ssl crypto)
set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
set (WEBSOCKETPP_BOOST_LIBS system thread)
set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++0x -stdlib=libc++") # todo: is libc++ really needed here?
if (NOT APPLE)
@@ -143,6 +154,10 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
list (APPEND WEBSOCKETPP_BOOST_LIBS random)
endif()
if (BUILD_TESTS)
list (APPEND WEBSOCKETPP_BOOST_LIBS unit_test_framework)
endif()
############ Dependencies
# Set BOOST_ROOT env variable or pass with cmake -DBOOST_ROOT=path.
@@ -173,6 +188,14 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
set (Boost_USE_STATIC_LIBS FALSE)
endif ()
if (BOOST_STATIC)
set (Boost_USE_STATIC_LIBS TRUE)
endif ()
if (NOT Boost_USE_STATIC_LIBS)
add_definitions (/DBOOST_TEST_DYN_LINK)
endif ()
set (Boost_FIND_REQUIRED TRUE)
set (Boost_FIND_QUIETLY TRUE)
set (Boost_DEBUG FALSE)
@@ -205,6 +228,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
endif ()
find_package(OpenSSL)
find_package(ZLIB)
endif()
############ Add projects
@@ -214,12 +238,12 @@ add_subdirectory (websocketpp)
# Add examples
if (BUILD_EXAMPLES)
add_subdirectory (examples)
include_subdirs ("examples")
endif ()
# Add tests
if (BUILD_TESTS)
add_subdirectory (test)
include_subdirs ("test")
endif ()
print_used_build_config()
+1 -1
View File
@@ -1,6 +1,6 @@
Main Library:
Copyright (c) 2013, Peter Thorson. All rights reserved.
Copyright (c) 2014, Peter Thorson. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+1502 -1021
View File
File diff suppressed because it is too large Load Diff
+43 -9
View File
@@ -34,6 +34,11 @@ elif os.environ.has_key('BOOST_INCLUDES') and os.environ.has_key('BOOST_LIBS'):
else:
raise SCons.Errors.UserError, "Neither BOOST_ROOT, nor BOOST_INCLUDES + BOOST_LIBS was set!"
## Custom OpenSSL
if os.environ.has_key('OPENSSL_PATH'):
env.Append(CPPPATH = os.path.join(os.environ['OPENSSL_PATH'], 'include'))
env.Append(LIBPATH = os.environ['OPENSSL_PATH'])
if os.environ.has_key('WSPP_ENABLE_CPP11'):
env['WSPP_ENABLE_CPP11'] = True
else:
@@ -93,23 +98,38 @@ if env['PLATFORM'].startswith('win'):
#env['LIBPATH'] = env['BOOST_LIBS']
pass
else:
env['LIBPATH'] = ['/usr/lib',
'/usr/local/lib'] #, env['BOOST_LIBS']
env.Append(LIBPATH = ['/usr/lib', '/usr/local/lib'])
# Compiler specific warning flags
if env['CXX'].startswith('g++'):
#env.Append(CCFLAGS = ['-Wconversion'])
env.Append(CCFLAGS = ['-Wcast-align'])
env.Append(CCFLAGS = ['-Wshadow'])
env.Append(CCFLAGS = ['-Wunused-parameter'])
elif env['CXX'].startswith('clang++'):
#env.Append(CCFLAGS = ['-Wcast-align'])
#env.Append(CCFLAGS = ['-Wglobal-constructors'])
#env.Append(CCFLAGS = ['-Wconversion'])
env.Append(CCFLAGS = ['-Wno-padded'])
env.Append(CCFLAGS = ['-Wshadow'])
env.Append(CCFLAGS = ['-Wunused-parameter'])
env.Append(CCFLAGS = ['-Wsometimes-uninitialized'])
env.Append(CCFLAGS = ['-Wuninitialized'])
#env.Append(CCFLAGS = ['-Weverything'])
#env.Append(CCFLAGS = ['-Wno-documentation'])
#env.Append(CCFLAGS = ['-Wno-weak-vtables'])
#env.Append(CCFLAGS = ['-Wno-global-constructors'])
#env.Append(CCFLAGS = ['-Wno-sign-conversion'])
#env.Append(CCFLAGS = ['-Wno-exit-time-destructors'])
# Wpadded
# Wsign-conversion
#
platform_libs = []
tls_libs = []
@@ -132,7 +152,7 @@ env.Append(CPPPATH = ['#'])
##### Set up C++11 environment
polyfill_libs = [] # boost libraries used as drop in replacements for incomplete
# C++11 STL implementations
# C++11 STL implementations
env_cpp11 = env.Clone ()
if env_cpp11['CXX'].startswith('g++'):
@@ -165,18 +185,18 @@ else:
# values then use it for the boost libraries. Otherwise just add them to the
# regular CPPPATH values.
if env['CXX'].startswith('g++') or env['CXX'].startswith('clang'):
env.Append(CPPFLAGS = '-isystem ' + env['BOOST_INCLUDES'])
env.Append(CPPFLAGS = '-isystem ' + env['BOOST_INCLUDES'])
else:
env.Append(CPPPATH = [env['BOOST_INCLUDES']])
env.Append(CPPPATH = [env['BOOST_INCLUDES']])
env.Append(LIBPATH = [env['BOOST_LIBS']])
# if the build system is known to allow the isystem modifier for library include
# values then use it for the boost libraries. Otherwise just add them to the
# regular CPPPATH values.
if env_cpp11['CXX'].startswith('g++') or env_cpp11['CXX'].startswith('clang'):
env_cpp11.Append(CPPFLAGS = '-isystem ' + env_cpp11['BOOST_INCLUDES'])
env_cpp11.Append(CPPFLAGS = '-isystem ' + env_cpp11['BOOST_INCLUDES'])
else:
env_cpp11.Append(CPPPATH = [env_cpp11['BOOST_INCLUDES']])
env_cpp11.Append(CPPPATH = [env_cpp11['BOOST_INCLUDES']])
env_cpp11.Append(LIBPATH = [env_cpp11['BOOST_LIBS']])
releasedir = 'build/release/'
@@ -211,9 +231,13 @@ if not env['PLATFORM'].startswith('win'):
# echo_server
echo_server = SConscript('#/examples/echo_server/SConscript',variant_dir = builddir + 'echo_server',duplicate = 0)
# echo_client
echo_client = SConscript('#/examples/echo_client/SConscript',variant_dir = builddir + 'echo_client',duplicate = 0)
# echo_server_tls
if tls_build:
echo_server_tls = SConscript('#/examples/echo_server_tls/SConscript',variant_dir = builddir + 'echo_server_tls',duplicate = 0)
echo_server_both = SConscript('#/examples/echo_server_both/SConscript',variant_dir = builddir + 'echo_server_both',duplicate = 0)
# broadcast_server
broadcast_server = SConscript('#/examples/broadcast_server/SConscript',variant_dir = builddir + 'broadcast_server',duplicate = 0)
@@ -224,8 +248,12 @@ testee_server = SConscript('#/examples/testee_server/SConscript',variant_dir = b
# testee_client
testee_client = SConscript('#/examples/testee_client/SConscript',variant_dir = builddir + 'testee_client',duplicate = 0)
# utility_client
utility_client = SConscript('#/examples/utility_client/SConscript',variant_dir = builddir + 'utility_client',duplicate = 0)
# scratch_client
scratch_client = SConscript('#/examples/scratch_client/SConscript',variant_dir = builddir + 'scratch_client',duplicate = 0)
# scratch_server
scratch_server = SConscript('#/examples/scratch_server/SConscript',variant_dir = builddir + 'scratch_server',duplicate = 0)
# debug_client
debug_client = SConscript('#/examples/debug_client/SConscript',variant_dir = builddir + 'debug_client',duplicate = 0)
@@ -236,6 +264,12 @@ debug_server = SConscript('#/examples/debug_server/SConscript',variant_dir = bui
# subprotocol_server
subprotocol_server = SConscript('#/examples/subprotocol_server/SConscript',variant_dir = builddir + 'subprotocol_server',duplicate = 0)
# telemetry_server
telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0)
# external_io_service
external_io_service = SConscript('#/examples/external_io_service/SConscript',variant_dir = builddir + 'external_io_service',duplicate = 0)
if not env['PLATFORM'].startswith('win'):
# iostream_server
iostream_server = SConscript('#/examples/iostream_server/SConscript',variant_dir = builddir + 'iostream_server',duplicate = 0)
+208 -1
View File
@@ -1,4 +1,208 @@
HEAD
0.7.0 - 2016-02-22
- MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method
`cancel_socket` will now return `lib::asio::error_code` instead of `void`.
Custom Asio transport socket policies will need to be updated accordingly.
This does not affect anyone using the bundled socket policies.
- Feature: Basic support for the permessage-deflate extension. #344
- Feature: Allow accessing the local endpoint when using the Asio transport.
This allows inspection of the address and port in cases where they are chosen
by the operating system rather than the user. Thank you Andreas Weis and
Muzahid Hussain for reporting and related code. #458
- Feature: Add support for subprotocols in Hybi00. Thank you Lukas Obermann
for reporting and a patch. #518
- Improvement: Better automatic std::chrono feature detection for Visual Studio
- Improvement: Major refactoring to bundled CMake build system. CMake can now be
used to build all of the examples and the test suite. Thank you Thijs Wenker
for a significant portion of this code. #378, #435, #449
- Improvement: In build environments where `lib::error_code` and
`lib::asio::error_code` match (such as using `boost::asio` with
`boost::system_error` or standalone asio with `std::system_error`, transport
errors are passed through natively rather than being reported as a translated
`pass_through` error type.
- Improvement: Add a `get_transport_error` method to Asio transport connections
to allow retrieving a machine readable native transport error.
- Improvement: Add `connection::get_response`, `connection::get_response_code`,
and `connection::get_response_msg` methods to allow accessing additional
information about the HTTP responses that WebSocket++ sends. #465 Thank you
Flow86 for reporting.
- Improvement: Removes use of empty strings ("") in favor of `string::clear()`
and `string::empty()`. This avoids generating unnecessary temporary objects.
#468 Thank you Vladislav Yaroslavlev for reporting and a patch.
- Documentation: Adds an example demonstrating the use of external `io_service`
- Documentation: Adds a simple echo_client example.
- Documentation: Begins migration of the web based user manual into Doxygen.
- Bug: Fix memory leak when init_asio produces an error. #454 Thank you Mark
Grimes for reporting and fixing.
- Bug: Fix crash when processing a specially crafted HTTP header. Thank you Eli
Fidler for reporting, test cases, and a patch. #456
- Bug: Fix an issue where standalone Asio builds that use TLS would not compile
due to lingering boost code. #448 Thank you mjsp for reporting
- Bug: Fix an issue where canceling a socket could throw an exception on some
older Windows XP platforms. It now prints an appropriate set of log messages
instead. Thank you Thijs Wenker for reporting and researching solutions. #460
- Bug: Fix an issue where deferred HTTP connections that start sending a very
long response before their HTTP handler ends would result in a second set of
HTTP headers being injected into the output. Thank you Kevin Smith for
reporting and providing test case details. #443
- Bug: Fix an issue where the wrong type of strand was being created. Thank you
Bastien Brunnenstein for reporting and a patch. #462
- Bug: Fix an issue where TLS includes were broken for Asio Standalone builds.
Thank you giachi and Bastien Brunnenstein for reporting. #491
- Bug: Remove the use of cached read and write handlers in the Asio transport.
This feature caused memory leaks when the io_service the connection was
running on was abruptly stopped. There isn't a clean and safe way of using
this optimization without global state and the associated locks. The locks
perform worse. Thank you Xavier Gibert for reporting, test cases, and code.
Fixes #490.
- Bug: Fix a heap buffer overflow when checking very short URIs. Thank you
Xavier Gibert for reporting and a patch #524
- Compatibility: Fixes a number of build & config issues on Visual Studio 2015
- Compatibility: Removes non-standards compliant masking behavior. #395, #469
- Compatibility: Replace deprecated use of auto_ptr on systems where unique_ptr
is available.
0.6.0 - 2015-06-02
- MINOR BREAKING TRANSPORT POLICY CHANGE: Custom transport policies will now be
required to include a new method `void set_uri(uri_ptr u)`. An implementation
is not required. The stub transport policy includes an example stub method
that can be added to any existing custom transport policy to fulfill this
requirement. This does not affect anyone using the bundled transports or
configs.
- MINOR BREAKING SOCKET POLICY CHANGE: Custom asio transport socket policies
will now be required to include a new method `void set_uri(uri_ptr u)`. Like
with the transport layer, an implementation is not required. This does not
affect anyone using the bundled socket policies.
- MINOR BREAKING DEPENDENCY CHANGE: When using Boost versions greater than or
equal to 1.49 in C++03 mode, `libboost-chrono` is needed now instead of
`libboost-date_time`. Users with C++11 compilers or using Boost versions 1.48
and earlier are not affected. Note: This change affects the bundled unit test
suite.
- Feature: WebSocket++ Asio transport policy can now be used with the standalone
version of Asio (1.8.0+) when a C++11 compiler and standard library are
present. This means that it is possible now to use WebSocket++'s Asio
transport entirely without Boost. Thank you Robert Seiler for proof of concept
code that was used as a guide for this implementation. Fixes #324
- Feature: Adds a vectored/scatter-gather write handler to the iostream
transport.
- Feature: Adds the ability to defer sending an HTTP response until sometime
after the `http_handler` is run. This allows processing of long running http
handlers to defer their response until it is ready without blocking the
network thread. references #425
- Improvement: `echo_server_tls` has been update to demonstrate how to configure
it for Mozilla's recommended intermediate and modern TLS security profiles.
- Improvement: `endpoint::set_timer` now uses a steady clock provided by
`boost::chrono` or `std::chrono` where available instead of the non-monotonic
system clock. Thank you breyed for reporting. fixes #241
- Improvement: Outgoing TLS connections to servers using the SNI extension to
choose a certificate will now work. Thank you moozzyk for reporting.
Fixes #400
- Improvement: Removes an unnecessary mutex lock in `get_con_from_hdl`.
- Cleanup: Asio transport policy has been refactored to remove many Boost
dependencies. On C++03 compilers the `boost::noncopyable` dependency has been
removed and the `boost::date_time` dependency has been replaced with the newer
`boost::chrono` when possible. On C++11 compilers the `boost::aligned_storage`
and `boost::date_time` dependencies are gone, replaced with equivalent C++11
standard library features.
- Bug: Fixes a potential dangling pointer and inconsistent error message
handling in `websocketpp::exception`. #432 Thank you Tom Swirly for the fix.
0.5.1 - 2015-02-27
- Bug: Fixes an issue where some frame data was counted against the max header
size limit, resulting in connections that included a lot of frame data
immediately after the opening handshake to fail.
- Bug: Fix a typo in the name of the set method for `max_http_body_size`. #406
Thank you jplatte for reporting.
0.5.0 - 2015-01-22
- BREAKING UTILITY CHANGE: Deprecated methods `http::parser::parse_headers`,
`http::response::parse_complete`, and `http::request::parse_complete` have
been removed.
- Security: Disabled SSLv3 in example servers.
- Feature: Adds basic support for accessing HTTP request bodies in the http
handler. #181
- Feature: Adds the ability to register a shutdown handler when using the
iostream transport. This provides a clean interface for triggering the shut
down of external sockets and other cleanup without hooking in to higher level
WebSocket handlers.
- Feature: Adds the ability to register a write handler when using the iostream
transport. This handler can be used to handle transport output in place of
registering an ostream to write to.
- Feature: Adds a new logging policy that outputs to syslog. #386 Thank you Tom
Hughes for submitting the initial version of this policy.
- Improvement: Message payload logging now prints text for text messages rather
than binary.
- Improvement: Overhaul of handshake state machine. Should make it impossible
for exceptions to bubble out of transport methods like `io_service::run`.
- Improvement: Overhaul of handshake error reporting. Fail handler error codes
will be more detailed and precise. Adds new [fail] and [http] logging channels
that log failed websocket connections and successful HTTP connections
respectively. A new aggregate channel package, `alevel::access_core`, allows
enabling connect, disconnect, fail, and http together. Successful HTTP
connections will no longer trigger a fail handler.
- Improvement: Ability to terminate connection during an http handler to cleanly
suppress the default outgoing HTTP response.
- Documentation: Add Sending & Receiving Messages step to chapter one of the
`utility_client` tutorial. Update `utility_client` example to match.
- Cleanup: Removes unused files & STL includes. Adds required STL includes.
Normalizes include order.
- Bug: Fixes a fatal state error when a handshake response is completed
immediately after that handshake times out. #389
- Bug: MinGW fixes; C++11 feature detection, localtime use. #393 Thank you
Schebb for reporting, code, and testing.
- Bug: Fixes an issue where `websocketpp::exception::what()` could return an out
of scope pointer. #397 Thank you fabioang for reporting.
- Bug: Fixes an issue where endpoints were not reset properly after a call to
`endpoint::listen` failed. #390 Thank you wyyqyl for reporting.
0.4.0 - 2014-11-04
- BREAKING API CHANGE: All WebSocket++ methods now throw an exception of type
`websocketpp::exception` which derives from `std::exception`. This normalizes
all exception types under the standard exception hierarchy and allows
WebSocket++ exceptions to be caught in the same statement as others. The error
code that was previously thrown is wrapped in the exception object and can be
accessed via the `websocketpp::exception::code()` method.
- BREAKING API CHANGE: Custom logging policies have some new required
constructors that take generic config settings rather than pointers to
std::ostreams. This allows writing logging policies that do not involve the
use of std::ostream. This does not affect anyone using the built in logging
policies.
- BREAKING UTILITY CHANGE: `websocketpp::lib::net::htonll` and
`websocketpp::lib::net::ntohll` have been prefixed with an underscore to avoid
conflicts with similarly named macros in some operating systems. If you are
using the WebSocket++ provided 64 bit host/network byte order functions you
will need to switch to the prefixed versions.
- BREAKING UTILITY CHANGE: The signature of `base64_encode` has changed from
`websocketpp::base64_encode(unsigned char const *, unsigned int)` to
`websocketpp::base64_encode(unsigned char const *, size_t)`.
- BREAKING UTILITY CHANGE: The signature of `sha1::calc` has changed from
`websocketpp::sha1::calc(void const *, int, unsigned char *)` to
`websocketpp::sha1::calc(void const *, size_t, unsigned char *)`
- Feature: Adds incomplete `minimal_server` and `minimal_client` configs that
can be used to build custom configs without pulling in the dependencies of
`core` or `core_client`. These configs will offer a stable base config to
future-proof custom configs.
- Improvement: Core library no longer has std::iostream as a dependency.
std::iostream is still required for the optional iostream logging policy and
iostream transport.
- Bug: C++11 Chrono support was being incorrectly detected by the `boost_config`
header. Thank you Max Dmitrichenko for reporting and a patch.
- Bug: use of `std::put_time` is now guarded by a unique flag rather than a
chrono library flag. Thank you Max Dmitrichenko for reporting.
- Bug: Fixes non-thread safe use of std::localtime. #347 #383
- Compatibility: Adjust usage of std::min to be more compatible with systems
that define a min(...) macro.
- Compatibility: Removes unused parameters from all library, test, and example
code. This assists with those developing with -Werror and -Wunused-parameter
#376
- Compatibility: Renames ntohll and htonll methods to avoid conflicts with
platform specific macros. #358 #381, #382 Thank you logotype, unphased,
svendjo
- Cleanup: Removes unused functions, fixes variable shadow warnings, normalizes
all whitespace in library, examples, and tests to 4 spaces. #376
0.3.0 - 2014-08-10
- Feature: Adds `start_perpetual` and `stop_perpetual` methods to asio transport
These may be used to replace manually managed `asio::io_service::work` objects
- Feature: Allow setting pong and handshake timeouts at runtime.
@@ -17,6 +221,9 @@ HEAD
- Feature: Adds the ability to specify a maximum message size.
- Feature: Adds `close::status::get_string(...)` method to look up a human
readable string given a close code value.
- Feature: Adds `connection::read_all(...)` method to iostream transport as a
convenience method for reading all data into the connection buffer without the
end user needing to manually loop on `read_some`.
- Improvement: Open, close, and pong timeouts can be disabled entirely by
setting their duration to 0.
- Improvement: Numerous performance improvements. Including: tuned default
@@ -125,7 +332,7 @@ HEAD
- Change default HTTP response error code when no http_handler is defined from
500/Internal Server Error to 426/Upgrade Required
- Remove timezone from logger timestamp to work around issues with the Windows
implimentation of strftime. Thank you breyed for testing and code. #257
implementation of strftime. Thank you breyed for testing and code. #257
- Switch integer literals to char literals to improve VCPP compatibility.
Thank you breyed for testing and code. #257
- Add MSVCPP warning suppression for the bundled SHA1 library. Thank you breyed
+32 -1
View File
@@ -13,7 +13,12 @@ macro (print_used_build_config)
message ("")
message (STATUS "WEBSOCKETPP_BOOST_LIBS = ${WEBSOCKETPP_BOOST_LIBS}")
message (STATUS "WEBSOCKETPP_PLATFORM_LIBS = ${WEBSOCKETPP_PLATFORM_LIBS}")
message (STATUS "WEBSOCKETPP_PLATFORM_TSL_LIBS = ${WEBSOCKETPP_PLATFORM_TSL_LIBS}")
message (STATUS "WEBSOCKETPP_PLATFORM_TLS_LIBS = ${WEBSOCKETPP_PLATFORM_TLS_LIBS}")
message ("")
message (STATUS "OPENSSL_FOUND = ${OPENSSL_FOUND}")
message (STATUS "OPENSSL_INCLUDE_DIR = ${OPENSSL_INCLUDE_DIR}")
message (STATUS "OPENSSL_LIBRARIES = ${OPENSSL_LIBRARIES}")
message (STATUS "OPENSSL_VERSION = ${OPENSSL_VERSION}")
message ("")
endmacro ()
@@ -49,10 +54,23 @@ macro (build_executable TARGET_NAME)
include_directories (${WEBSOCKETPP_ROOT} ${WEBSOCKETPP_INCLUDE})
target_link_libraries(${TARGET_NAME} ${WEBSOCKETPP_PLATFORM_LIBS})
set_target_properties (${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${WEBSOCKETPP_BIN})
set_target_properties (${TARGET_NAME} PROPERTIES DEBUG_POSTFIX d)
endmacro ()
# Build executable and register as test
macro (build_test TARGET_NAME)
build_executable (${TARGET_NAME} ${ARGN})
if (${CMAKE_VERSION} VERSION_LESS 3)
message(WARNING "CMake too old to register ${TARGET_NAME} as a test")
else ()
add_test(NAME ${TARGET_NAME} COMMAND $<TARGET_FILE:${TARGET_NAME}>)
endif ()
endmacro ()
# Finalize target for all types
macro (final_target)
if ("${TARGET_LIB_TYPE}" STREQUAL "EXECUTABLE")
@@ -76,3 +94,16 @@ endmacro ()
macro (link_openssl)
target_link_libraries (${TARGET_NAME} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
endmacro ()
macro (link_zlib)
target_link_libraries (${TARGET_NAME} ${ZLIB_LIBRARIES})
endmacro ()
macro (include_subdirs PARENT)
file (GLOB SDIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PARENT}/*")
foreach (SUBDIR ${SDIRS})
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/CMakeLists.txt")
add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}")
endif ()
endforeach ()
endmacro()
+86
View File
@@ -0,0 +1,86 @@
/** \page faq FAQ
## Dependency Management
### Can WebSocket++ be used without Boost?
Yes. WebSocket++ only uses Boost features as polyfills for C++11 language features and libraries. If you have a C++11 compiler and standard library you can use WebSocket++ without Boost. In most cases setting your build environment to use the C++11 (or later) language dialect is sufficient to enable this mode of use.
With less common compilers (and sometimes very recently release compilers) there may be specific issues with certain libraries that aren't automatically detected by the library. For these situations there are additional defines available to fine tune which C++11 libraries and features are used. TODO: more details about them.
For the iostream/raw transport the C++11 standard library is sufficient. For the Asio based transports, there is no C++11 library that provides the networking capabilaties that Asio does. As such even with a C++11 build system, you will need a standalone copy of Asio to use if Boost Asio is not available.
### Can WebSocket++ be used with standalone Asio
Yes. The process is the same as used with standalone Asio itself. Define `ASIO_STANDALONE` before including Asio or WebSocket++ headers. You will need to download a copy of the Asio headers separately (http://www.think-async.com) and make sure they are in your build system's include path.
### Can WebSocket++ be used without TLS or OpenSSL?
Yes. When using the iostream/raw transport, there are no TLS features and OpenSSL is not required. When using the Asio transport TLS features are optional. You only need OpenSSL if you want to use TLS. You can only make or recieve encrypted connections (https/wss) if you have enabled TLS features.
Whether an Asio endpoint uses TLS or not is determined by its config template parameter. The default bundled `websocketpp::config::asio` and `websocketpp::config::asio_client` configs do not support TLS, the `websocketpp::config::asio_tls` and `websocketpp::config::asio_tls_client` do.
The `<websocketpp/config/asio.hpp>` and `<websocketpp/config/asio_client.hpp>` headers will include both the TLS and non-TLS varients of their respective configs and require the presence of OpenSSL. The `<websocketpp/config/asio_no_tls.hpp>` and `<websocketpp/config/asio_no_tls_client.hpp>` headers will include only the non-TLS configs and do not require OpenSSL.
## Compression
### How do I use permessage-deflate in version 0.6.0-permessagedeflate and 0.7.0?
These versions of the library require a custom config to use the permessage-deflate extension. Here is a minimal example of such a custom config. You can also integrate these lines into an existing custom config.
Note that in these versions there is no fine grained control over which connections are compressed or not. Clients will request compression with the default settings and use it if the server supports it. Servers will accept whatever parameters clients request.
Outgoing messages by default will be compressed if compression was auto-negotiated during the handshake. There is an option to force a specific message to be sent uncompressed even if compression was negotiated. This may be useful for sending data that you know to be compressed already (images, zip files, etc).
__Server Example__
```
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
struct deflate_server_config : public websocketpp::config::asio {
// ... additional custom config if you need it for other things
/// permessage_compress extension
struct permessage_deflate_config {};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
};
typedef websocketpp::server<deflate_server_config> server_endpoint_type;
```
__Client Example__
```
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
struct deflate_client_config : public websocketpp::config::asio_client {
// ... additional custom config if you need it for other things
/// permessage_compress extension
struct permessage_deflate_config {};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
};
typedef websocketpp::client<deflate_client_config> client_endpoint_type;
```
## Security
### Is it possible to terminate a malicious connection quickly, without tying up resources performing clean close steps,
Yes. The library will automatically detect and terminate connections that violate the WebSocket protocol. In cases where the library believes the remote endpoint to be malicious or sufficiently broken to be unlikely to understand or process the closing handshake, it will be omited.
If your application detects conditions above the protocol level that you believe to be malicious, for example, if you recognize an IP from a known denial of service attack, you can close the connection with two different levels of urgency. Use the standard `websocketpp::endpoint::close` or `websocketpp::connection::close` methods with one of the following special close codes:
- `websocketpp::close::status::omit_handshake`: Omits the closing handshake, but cleanly closes the TCP connection.
- `websocketpp::close::status::force_tcp_drop`: Forcibly drop the TCP connection.
Please note that usage of these disconnect methods results in a violation of the WebSocket protocol and may have negative reprocusions for the remote endpoint with respect to network timeouts. Please use caution when using them.
## Build Issues
### Getting compile errors related to `std::chrono`, `boost::chrono`, `waitable_timer`, or `steady_clock`
Your build system may be confused about whether it is supposed to be using `boost::chrono` or `std::chrono`. Boost automatically detects this setup on some compilers but not others. Defining `BOOST_ASIO_HAS_STD_CHRONO` can help. See http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/overview/cpp2011/chrono.html for more details.
*/
+27
View File
@@ -0,0 +1,27 @@
/** \page getting_started Getting Started
WebSocket++ code is available on github at https://github.com/zaphoyd/websocketpp
The official project homepage lives at http://www.zaphoyd.com/websocketpp
The git repository is organized into several directories:
- **docs**: This documentation
- **examples**: Example programs that demonstrate how to build basic versions of some commonly used patterns for WebSocket clients and servers.
- **test**: Unit tests that confirm that the code you have works properly and help detect platform specific issues.
- **tutorials**: Detailed walkthroughs of a select set of the example programs.
- **websocketpp**: All of the library code and default configuration files.
WebSocket++ is a header only library. You can start using it by including the websocketpp source directory in your project's include path and including the appropriate WebSocket++ headers in your program. You may also need to include and/or link to appropriate Boost/system libraries. TODO: More information: Building a program with WebSocket++, Walkthroughs of the example programs
WebSocket++ includes cmake and scons scripts for building the examples and unit tests. Neither system is needed unless you want to build tests or examples in an automated fashion.
__Usage questions__ should be posted to the project mailing list at http://groups.google.com/group/websocketpp/ or the IRC channel (\#websocketpp on freenode).
__Bugs and issues__ should be posted to the project GitHub issues queue: https://github.com/zaphoyd/websocketpp/issues.
__Pull requests__ on GitHub are welcome. Please make them against the `develop` branch.
WebSocket++ is written and maintained by Peter Thorson. You can contact me via GitHub messaging, IRC, or via email at websocket@zaphoyd.com.
*/
+165
View File
@@ -0,0 +1,165 @@
/** \page reference.handlers Handler Reference
Handlers allow WebSocket++ programs to receive notifications about events
that happen in relation to their connections. Some handlers also behave as
hooks that give the program a chance to modify state or adjust settings before
the connection continues.
Handlers are registered by calling the appropriate `set_*_handler` method on either an
endpoint or connection. The * refers to the name of the handler (as
specified in the signature field below). For example, to set the open handler,
call `set_open_handler(...)`.
Setting handlers on an endpoint will result in them being copied as the default
handler to all new connections created by that endpoint. Changing an endpoint's
handlers will not affect connections that are already in progress. This includes
connections that are in the listening state. As such, it is important to set any
endpoint handlers before you call `endpoint::start_accept` or else the handlers
will not be attached to your first connection.
Setting handlers on a connection will result in the handler being changed for
that connection only, starting at the next time that handler is called. This can
be used to change the handler during a connection.
Connection Handlers
-------------------
These handlers will be called at most once per connection in the order specified below.
### Socket Init Handler
| Event | Signature | Availability |
| --------------------- | ----------------------------------------------------- | -------------------- |
| Socket initialization | `socket_init(connection_hdl, asio::ip::tcp::socket&)` | 0.3.0 Asio Transport |
This hook is triggered after the socket has been initialized but before a connection is established.
It allows setting arbitrary socket options before connections are sent/recieved.
### TCP Pre-init Handler
| Event | Signature | Availability |
| ----------------------------- | ------------------------------ | -------------------- |
| TCP established, no data sent | `tcp_pre_init(connection_hdl)` | 0.3.0 Asio Transport |
This hook is triggered after the TCP connection is established, but before any pre-WebSocket-handshake
operations have been run. Common pre-handshake operations include TLS handshakes and proxy connections.
### TCP Post-init Handler
| Event | Signature | Availability |
| ----------------------- | ------------------------------------------ | ----------------------------- |
| Request for TLS context | `tls_context_ptr tls_init(connection_hdl)` | 0.3.0 Asio Transport with TLS |
This hook is triggered before the TLS handshake to request the TLS context to use. You must
return a pointer to a configured TLS conext to continue. This provides the opportuinity to
set up the TLS settings, certificates, etc.
### Validate Handler
| Event | Signature | Availability |
| ------------------------------------- | ------------------------------- | ---------------------------- |
| Hook to accept or reject a connection | `bool validate(connection_hdl)` | 0.3.0 Core, Server role only |
This hook is triggered for servers during the opening handshake after the request has been
processed but before the response has been sent. It gives a program the opportunity to inspect
headers and other connection details and either accept or reject the connection. Validate happens
before the open or fail handler.
Return true to accept the connection, false to reject. If no validate handler is registered,
all connections will be accepted.
### Open Connection Handler
| Event | Signature | Availability |
| ------------------------- | ---------------------- | ------------ |
| Successful new connection | `open(connection_hdl)` | 0.3.0 Core |
Either open or fail will be called for each connection. Never both. All
connections that begin with an open handler call will also have a matching
close handler call when the connection ends.
### Fail Connection Handler
| Event | Signature | Availability |
| ----------------------------------- | ---------------------- | ------------ |
| Connection failed (before opening) | `fail(connection_hdl)` | 0.3.0 Core |
Either open or fail will be called for each connection. Never both. Connections
that fail will never have a close handler called.
### Close Connection Handler
| Event | Signature | Availability |
| --------------------------------- | ----------------------- | ------------ |
| Connection closed (after opening) | `close(connection_hdl)` | 0.3.0 Core |
Close will be called exactly once for every connection that open was called for.
Close is not called for failed connections.
Message Handlers
----------------
These handers are called in response to incoming messages or message like events. They only will be called while the connection is in the open state.
### Message Handler
| Event | Signature | Availability |
| --------------------- | -------------------------------------- | ------------ |
| Data message recieved | `message(connection_hdl, message_ptr)` | 0.3.0 Core |
Applies to all non-control messages, including both text and binary opcodes. The
`message_ptr` type and its API depends on your endpoint type and its config.
### Ping Handler
| Event | Signature | Availability |
| ------------- | ---------------------------------------- | ------------ |
| Ping recieved | `bool ping(connection_hdl, std::string)` | 0.3.0 Core |
Second (string) argument is the binary ping payload. Handler return value
indicates whether or not to respond to the ping with a pong. If no ping handler
is set, WebSocket++ will respond with a pong containing the same binary data as
the ping (Per requirements in RFC6455).
### Pong Handler
| Event | Signature | Availability |
| ------------- | ----------------------------------- | ------------ |
| Pong recieved | `pong(connection_hdl, std::string)` | 0.3.0 Core |
Second (string) argument is the binary pong payload.
### Pong Timeout Handler
| Event | Signature | Availability |
| ---------------------------------- | ------------------------------------------- | ---------------------------------------- |
| Timed out while waiting for a pong | `pong_timeout(connection_hdl, std::string)` | 0.3.0 Core, transport with timer support |
Triggered if there is no response to a ping after the configured duration. The second
(string) argument is the binary payload of the unanswered ping.
### HTTP Handler
| Event | Signature | Availability |
| --------------------- | --------------------- | ---------------------------- |
| HTTP request recieved | `http(connection_hdl` | 0.3.0 Core, Server role only |
Called when HTTP requests that are not WebSocket handshake upgrade requests are
recieved. Allows responding to regular HTTP requests. If no handler is registered
a 426/Upgrade Required error is returned.
### Interrupt Handler
| Event | Signature | Availability |
| ----------------------------------- | --------------------------- | ------------ |
| Connection was manually interrupted | `interrupt(connection_hdl)` | 0.3.0 Core |
Interrupt events can be triggered by calling `endpoint::interrupt` or `connection::interrupt`.
Interrupt is similar to a timer event with duration zero but with lower overhead. It is useful
for single threaded programs to allow breaking up a very long handler into multiple parts and
for multi threaded programs as a way for worker threads to signale to the main/network thread
that an event is ready.
todo: write low and high watermark handlers
*/
+22
View File
@@ -0,0 +1,22 @@
.tabs, .tabs2, .tabs3, .navpath ul {
background-image: none;
background-color: #333;
border: none;
border-bottom: 1px solid #575757;
}
.tablist li, .navpath li {
background-image: none;
background-color: #333;
}
.tablist a, .navpath li.navelem a {
color: #ccc;
text-shadow: 0px 1px 1px black;
}
.tablist a:hover, .navpath li.navelem a:hover {
background-image: none;
background-color: #444;
color: #ccc;
}
+21
View File
@@ -0,0 +1,21 @@
/** \mainpage
WebSocket++ is a C++ library that can be used to implement WebSocket functionality. The goals of the project are to provide a WebSocket implementation that is portable, flexible, lightweight, low level, and high performance.
WebSocket++ does not intend to be used alone as a web application framework or full featured web services platform. As such the components, examples, and performance tuning are geared towards operation as a WebSocket client or server. There are some minimal convenience features that stray from this (for example the ability to respond to HTTP requests other than WebSocket Upgrades) but these are not the focus of the project. In particular WebSocket++ does not intend to implement any non-WebSocket related fallback options (ajax / long polling / comet / etc).
In order to remain compact and improve portability, the WebSocket++ project strives to reduce or eliminate external dependencies where possible and appropriate. WebSocket++ core has no dependencies other than the C++11 standard library. For non-C++11 compilers the Boost libraries provide drop in polyfills for the C++11 functionality used.
WebSocket++ implements a pluggable data transport component. The default component allows reduced functionality by using STL iostream or raw byte shuffling via reading and writing char buffers. This component has no non-STL dependencies and can be used in a C++11 environment without Boost. Also included is an Asio based transport component that provides full featured network client/server functionality. This component requires either Boost Asio or a C++11 compiler and standalone Asio. As an advanced option, WebSocket++ supports custom transport layers if you want to provide your own using another library.
In order to accommodate the wide variety of use cases WebSocket++ has collected, the library is built in a way that most of the major components are loosely coupled and can be swapped out and replaced. WebSocket++ will attempt to track the future development of the WebSocket protocol and any extensions as they are developed.
- \subpage getting_started "Getting Started"
- \subpage faq "FAQ"
- \subpage tutorials "Tutorials"
- \subpage md_changelog "Change Log / Version History"
- Reference
- \subpage reference.handlers "Handler Reference"
*/
+1 -1
View File
@@ -36,7 +36,7 @@ public:
void run(uint16_t port) {
m_server.listen(port);
m_server.start_accept();
m_server.start_accept();
m_server.run();
}
private:
+1 -1
View File
@@ -46,7 +46,7 @@ public:
void run(uint16_t port) {
m_server.listen(port);
m_server.start_accept();
m_server.start_accept();
m_server.run();
}
private:
+10
View File
@@ -0,0 +1,10 @@
/** \page tutorials Tutorials
These tutorials are works in progress, some are more complete than others.
- \subpage md_tutorials_utility_client_utility_client
- \subpage md_tutorials_utility_server_utility_server
- \subpage md_tutorials_broadcast_tutorial_broadcast_tutorial
- \subpage md_tutorials_chat_tutorial_chat_tutorial
*/
-6
View File
@@ -1,6 +0,0 @@
file (GLOB SDIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *)
foreach (SUBDIR ${SDIRS})
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/CMakeLists.txt")
add_subdirectory (${SUBDIR})
endif ()
endforeach ()
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (associative_storage)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
@@ -30,7 +30,7 @@ public:
connection_data data;
data.sessionid = m_next_sessionid++;
data.name = "";
data.name.clear();
m_connections[hdl] = data;
}
@@ -47,7 +47,7 @@ public:
void on_message(connection_hdl hdl, server::message_ptr msg) {
connection_data& data = get_data_from_hdl(hdl);
if (data.name == "") {
if (data.name.empty()) {
data.name = msg->get_payload();
std::cout << "Setting name of connection with sessionid "
<< data.sessionid << " to " << data.name << std::endl;
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (broadcast_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+33 -32
View File
@@ -3,6 +3,7 @@
#include <websocketpp/server.hpp>
#include <iostream>
#include <set>
/*#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
@@ -18,6 +19,7 @@ using websocketpp::lib::bind;
using websocketpp::lib::thread;
using websocketpp::lib::mutex;
using websocketpp::lib::lock_guard;
using websocketpp::lib::unique_lock;
using websocketpp::lib::condition_variable;
@@ -59,42 +61,41 @@ public:
m_server.listen(port);
// Start the server accept loop
m_server.start_accept();
m_server.start_accept();
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
try {
m_server.run();
} catch (const std::exception & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
void on_open(connection_hdl hdl) {
unique_lock<mutex> lock(m_action_lock);
//std::cout << "on_open" << std::endl;
m_actions.push(action(SUBSCRIBE,hdl));
lock.unlock();
{
lock_guard<mutex> guard(m_action_lock);
//std::cout << "on_open" << std::endl;
m_actions.push(action(SUBSCRIBE,hdl));
}
m_action_cond.notify_one();
}
void on_close(connection_hdl hdl) {
unique_lock<mutex> lock(m_action_lock);
//std::cout << "on_close" << std::endl;
m_actions.push(action(UNSUBSCRIBE,hdl));
lock.unlock();
{
lock_guard<mutex> guard(m_action_lock);
//std::cout << "on_close" << std::endl;
m_actions.push(action(UNSUBSCRIBE,hdl));
}
m_action_cond.notify_one();
}
void on_message(connection_hdl hdl, server::message_ptr msg) {
// queue message up for sending by processing thread
unique_lock<mutex> lock(m_action_lock);
//std::cout << "on_message" << std::endl;
m_actions.push(action(MESSAGE,hdl,msg));
lock.unlock();
{
lock_guard<mutex> guard(m_action_lock);
//std::cout << "on_message" << std::endl;
m_actions.push(action(MESSAGE,hdl,msg));
}
m_action_cond.notify_one();
}
@@ -112,13 +113,13 @@ public:
lock.unlock();
if (a.type == SUBSCRIBE) {
unique_lock<mutex> con_lock(m_connection_lock);
lock_guard<mutex> guard(m_connection_lock);
m_connections.insert(a.hdl);
} else if (a.type == UNSUBSCRIBE) {
unique_lock<mutex> con_lock(m_connection_lock);
lock_guard<mutex> guard(m_connection_lock);
m_connections.erase(a.hdl);
} else if (a.type == MESSAGE) {
unique_lock<mutex> con_lock(m_connection_lock);
lock_guard<mutex> guard(m_connection_lock);
con_list::iterator it;
for (it = m_connections.begin(); it != m_connections.end(); ++it) {
@@ -130,7 +131,7 @@ public:
}
}
private:
typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
typedef std::set<connection_hdl,std::owner_less<connection_hdl> > con_list;
server m_server;
con_list m_connections;
@@ -142,18 +143,18 @@ private:
};
int main() {
try {
broadcast_server server_instance;
try {
broadcast_server server_instance;
// Start a thread to run the processing loop
thread t(bind(&broadcast_server::process_messages,&server_instance));
// Start a thread to run the processing loop
thread t(bind(&broadcast_server::process_messages,&server_instance));
// Run the asio loop with the main thread
server_instance.run(9002);
// Run the asio loop with the main thread
server_instance.run(9002);
t.join();
t.join();
} catch (std::exception & e) {
std::cout << e.what() << std::endl;
}
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
}
+17
View File
@@ -0,0 +1,17 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (OPENSSL_FOUND)
init_target (debug_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_openssl()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
endif()
+30 -15
View File
@@ -36,7 +36,7 @@
#include <iostream>
#include <chrono>
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::client<websocketpp::config::asio_client> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
@@ -63,10 +63,11 @@ public:
// Register our handlers
m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1));
m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
//m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2));
m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
m_endpoint.set_fail_handler(bind(&type::on_fail,this,::_1));
}
void start(std::string uri) {
@@ -74,29 +75,31 @@ public:
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
if (ec) {
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
return;
}
//con->set_proxy("http://humupdates.uchicago.edu:8443");
m_endpoint.connect(con);
// Start the ASIO io_service run loop
m_start = std::chrono::high_resolution_clock::now();
// Start the ASIO io_service run loop
m_start = std::chrono::high_resolution_clock::now();
m_endpoint.run();
}
void on_socket_init(websocketpp::connection_hdl hdl) {
void on_socket_init(websocketpp::connection_hdl) {
m_socket_init = std::chrono::high_resolution_clock::now();
}
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
context_ptr on_tls_init(websocketpp::connection_hdl) {
m_tls_init = std::chrono::high_resolution_clock::now();
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
try {
ctx->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::no_sslv3 |
boost::asio::ssl::context::single_dh_use);
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
@@ -104,15 +107,27 @@ public:
return ctx;
}
void on_fail(websocketpp::connection_hdl hdl) {
client::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
std::cout << "Fail handler" << std::endl;
std::cout << con->get_state() << std::endl;
std::cout << con->get_local_close_code() << std::endl;
std::cout << con->get_local_close_reason() << std::endl;
std::cout << con->get_remote_close_code() << std::endl;
std::cout << con->get_remote_close_reason() << std::endl;
std::cout << con->get_ec() << " - " << con->get_ec().message() << std::endl;
}
void on_open(websocketpp::connection_hdl hdl) {
m_open = std::chrono::high_resolution_clock::now();
m_endpoint.send(hdl, "", websocketpp::frame::opcode::text);
}
void on_message(websocketpp::connection_hdl hdl, message_ptr msg) {
void on_message(websocketpp::connection_hdl hdl, message_ptr) {
m_message = std::chrono::high_resolution_clock::now();
m_endpoint.close(hdl,websocketpp::close::status::going_away,"");
}
void on_close(websocketpp::connection_hdl hdl) {
void on_close(websocketpp::connection_hdl) {
m_close = std::chrono::high_resolution_clock::now();
std::cout << "Socket Init: " << std::chrono::duration_cast<dur_type>(m_socket_init-m_start).count() << std::endl;
@@ -133,13 +148,13 @@ private:
};
int main(int argc, char* argv[]) {
std::string uri = "wss://echo.websocket.org";
std::string uri = "wss://echo.websocket.org";
if (argc == 2) {
uri = argv[1];
}
if (argc == 2) {
uri = argv[1];
}
try {
try {
perftest endpoint;
endpoint.start(uri);
} catch (const std::exception & e) {
+2
View File
@@ -8,3 +8,5 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+86 -4
View File
@@ -31,11 +31,60 @@
#include <websocketpp/config/debug_asio_no_tls.hpp>
// Custom logger
#include <websocketpp/logger/syslog.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
typedef websocketpp::server<websocketpp::config::debug_asio> server;
////////////////////////////////////////////////////////////////////////////////
///////////////// Custom Config for debugging custom policies //////////////////
////////////////////////////////////////////////////////////////////////////////
struct debug_custom : public websocketpp::config::debug_asio {
typedef debug_custom type;
typedef debug_asio base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
/// Custom Logging policies
/*typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::elevel> elog_type;
typedef websocketpp::log::syslog<concurrency_type,
websocketpp::log::alevel> alog_type;
*/
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
static const long timeout_open_handshake = 0;
};
////////////////////////////////////////////////////////////////////////////////
typedef websocketpp::server<debug_custom> server;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
@@ -44,6 +93,33 @@ using websocketpp::lib::bind;
// pull out the type of messages sent by our config
typedef server::message_ptr message_ptr;
bool validate(server *, websocketpp::connection_hdl) {
//sleep(6);
return true;
}
void on_http(server* s, websocketpp::connection_hdl hdl) {
server::connection_ptr con = s->get_con_from_hdl(hdl);
std::string res = con->get_request_body();
std::stringstream ss;
ss << "got HTTP request with " << res.size() << " bytes of body data.";
con->set_body(ss.str());
con->set_status(websocketpp::http::status_code::ok);
}
void on_fail(server* s, websocketpp::connection_hdl hdl) {
server::connection_ptr con = s->get_con_from_hdl(hdl);
std::cout << "Fail handler: " << con->get_ec() << " " << con->get_ec().message() << std::endl;
}
void on_close(websocketpp::connection_hdl) {
std::cout << "Close handler" << std::endl;
}
// Define a callback to handle incoming messages
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
std::cout << "on_message called with hdl: " << hdl.lock().get()
@@ -59,10 +135,10 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
}
int main() {
// Create a server endpoint
// Create a server endpoint
server echo_server;
try {
try {
// Set logging settings
echo_server.set_access_channels(websocketpp::log::alevel::all);
echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
@@ -74,13 +150,19 @@ int main() {
// Register our message handler
echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
echo_server.set_http_handler(bind(&on_http,&echo_server,::_1));
echo_server.set_fail_handler(bind(&on_fail,&echo_server,::_1));
echo_server.set_close_handler(&on_close);
echo_server.set_validate_handler(bind(&validate,&echo_server,::_1));
// Listen on port 9012
echo_server.listen(9012);
// Start the server accept loop
echo_server.start_accept();
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
echo_server.run();
} catch (const std::exception & e) {
std::cout << e.what() << std::endl;
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
#init_target (dev)
#build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
#link_boost ()
#final_target ()
#set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+122 -122
View File
@@ -1,5 +1,5 @@
//#ifndef _WEBSOCKETPP_CPP11_STL_
// #define _WEBSOCKETPP_CPP11_STL_
// #define _WEBSOCKETPP_CPP11_STL_
//#endif
#include <random>
@@ -24,177 +24,177 @@
typedef websocketpp::server<websocketpp::config::core> server;
/*class handler : public server::handler {
bool validate(connection_ptr con) {
std::cout << "handler validate" << std::endl;
if (con->get_origin() != "http://www.example.com") {
con->set_status(websocketpp::http::status_code::FORBIDDEN);
return false;
}
return true;
}
bool validate(connection_ptr con) {
std::cout << "handler validate" << std::endl;
if (con->get_origin() != "http://www.example.com") {
con->set_status(websocketpp::http::status_code::FORBIDDEN);
return false;
}
return true;
}
void http(connection_ptr con) {
std::cout << "handler http" << std::endl;
}
void http(connection_ptr con) {
std::cout << "handler http" << std::endl;
}
void on_load(connection_ptr con, ptr old_handler) {
std::cout << "handler on_load" << std::endl;
}
void on_unload(connection_ptr con, ptr new_handler) {
std::cout << "handler on_unload" << std::endl;
}
void on_load(connection_ptr con, ptr old_handler) {
std::cout << "handler on_load" << std::endl;
}
void on_unload(connection_ptr con, ptr new_handler) {
std::cout << "handler on_unload" << std::endl;
}
void on_open(connection_ptr con) {
std::cout << "handler on_open" << std::endl;
}
void on_fail(connection_ptr con) {
std::cout << "handler on_fail" << std::endl;
}
void on_open(connection_ptr con) {
std::cout << "handler on_open" << std::endl;
}
void on_fail(connection_ptr con) {
std::cout << "handler on_fail" << std::endl;
}
void on_message(connection_ptr con, message_ptr msg) {
std::cout << "handler on_message" << std::endl;
void on_message(connection_ptr con, message_ptr msg) {
std::cout << "handler on_message" << std::endl;
}
}
void on_close(connection_ptr con) {
std::cout << "handler on_close" << std::endl;
}
void on_close(connection_ptr con) {
std::cout << "handler on_close" << std::endl;
}
};*/
int main() {
typedef websocketpp::message_buffer::message<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
typedef websocketpp::message_buffer::message<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
con_msg_man_type::ptr manager(new con_msg_man_type());
con_msg_man_type::ptr manager = websocketpp::lib::make_shared<con_msg_man_type>();
size_t foo = 1024;
size_t foo = 1024;
message_type::ptr input = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
message_type::ptr output = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
websocketpp::frame::masking_key_type key;
message_type::ptr input = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
message_type::ptr output = manager->get_message(websocketpp::frame::opcode::TEXT,foo);
websocketpp::frame::masking_key_type key;
std::random_device dev;
std::random_device dev;
key.i = 0x12345678;
key.i = 0x12345678;
double m = 18094238402394.0824923;
double m = 18094238402394.0824923;
/*std::cout << "Some Math" << std::endl;
{
boost::timer::auto_cpu_timer t;
/*std::cout << "Some Math" << std::endl;
{
boost::timer::auto_cpu_timer t;
for (int i = 0; i < foo; i++) {
m /= 1.001;
}
for (int i = 0; i < foo; i++) {
m /= 1.001;
}
}*/
}*/
std::cout << m << std::endl;
std::cout << m << std::endl;
std::cout << "Random Gen" << std::endl;
{
boost::timer::auto_cpu_timer t;
std::cout << "Random Gen" << std::endl;
{
boost::timer::auto_cpu_timer t;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
}
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
}
std::cout << "Out of place accelerated" << std::endl;
{
boost::timer::auto_cpu_timer t;
std::cout << "Out of place accelerated" << std::endl;
{
boost::timer::auto_cpu_timer t;
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(output->get_raw_payload().data())), foo, key);
}
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(output->get_raw_payload().data())), foo, key);
}
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
std::cout << "In place accelerated" << std::endl;
{
boost::timer::auto_cpu_timer t;
std::cout << "In place accelerated" << std::endl;
{
boost::timer::auto_cpu_timer t;
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), foo, key);
}
websocketpp::frame::word_mask_exact(reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), reinterpret_cast<uint8_t*>(const_cast<char*>(input->get_raw_payload().data())), foo, key);
}
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
std::cout << "Out of place byte by byte" << std::endl;
{
boost::timer::auto_cpu_timer t;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
std::cout << "Out of place byte by byte" << std::endl;
{
boost::timer::auto_cpu_timer t;
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin(), key);
}
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin(), key);
}
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
std::cout << "In place byte by byte" << std::endl;
{
boost::timer::auto_cpu_timer t;
input->get_raw_payload().replace(0,foo,foo,'\0');
output->get_raw_payload().replace(0,foo,foo,'\0');
std::cout << "In place byte by byte" << std::endl;
{
boost::timer::auto_cpu_timer t;
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), input->get_raw_payload().begin(), key);
}
websocketpp::frame::byte_mask(input->get_raw_payload().begin(), input->get_raw_payload().end(), input->get_raw_payload().begin(), key);
}
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
input->get_raw_payload().replace(0,foo,foo,'a');
output->get_raw_payload().replace(0,foo,foo,'b');
std::cout << "Copy" << std::endl;
{
boost::timer::auto_cpu_timer t;
input->get_raw_payload().replace(0,foo,foo,'a');
output->get_raw_payload().replace(0,foo,foo,'b');
std::cout << "Copy" << std::endl;
{
boost::timer::auto_cpu_timer t;
std::copy(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin());
}
std::copy(input->get_raw_payload().begin(), input->get_raw_payload().end(), output->get_raw_payload().begin());
}
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(input->get_payload().c_str(),20) << std::endl;
std::cout << websocketpp::utility::to_hex(output->get_payload().c_str(),20) << std::endl;
/*server::handler::ptr h(new handler());
/*server::handler::ptr h(new handler());
server test_server(h);
server::connection_ptr con;
server test_server(h);
server::connection_ptr con;
std::stringstream output;
std::stringstream output;
test_server.register_ostream(&output);
test_server.register_ostream(&output);
con = test_server.get_connection();
con = test_server.get_connection();
con->start();
con->start();
//foo.handle_accept(con,true);
//foo.handle_accept(con,true);
std::stringstream input;
input << "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
//input << "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
input >> *con;
std::stringstream input;
input << "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
//input << "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
input >> *con;
std::stringstream input2;
input2 << "messageabc2";
input2 >> *con;
std::stringstream input2;
input2 << "messageabc2";
input2 >> *con;
std::stringstream input3;
input3 << "messageabc3";
input3 >> *con;
std::stringstream input3;
input3 << "messageabc3";
input3 >> *con;
std::stringstream input4;
input4 << "close";
input4 >> *con;
std::stringstream input4;
input4 << "close";
input4 >> *con;
std::cout << "connection output:" << std::endl;
std::cout << output.str() << std::endl;*/
std::cout << "connection output:" << std::endl;
std::cout << output.str() << std::endl;*/
}
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (echo_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+23
View File
@@ -0,0 +1,23 @@
## echo_client example
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env_cpp11.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2016, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
typedef websocketpp::client<websocketpp::config::asio_client> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
// pull out the type of messages sent by our config
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
// This message handler will be invoked once for each incoming message. It
// prints the message and then sends a copy of the message back to the server.
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
websocketpp::lib::error_code ec;
c->send(hdl, msg->get_payload(), msg->get_opcode(), ec);
if (ec) {
std::cout << "Echo failed because: " << ec.message() << std::endl;
}
}
int main(int argc, char* argv[]) {
// Create a client endpoint
client c;
std::string uri = "ws://localhost:9002";
if (argc == 2) {
uri = argv[1];
}
try {
// Set logging to be pretty verbose (everything except message payloads)
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
// Initialize ASIO
c.init_asio();
// Register our message handler
c.set_message_handler(bind(&on_message,&c,::_1,::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
// Note that connect here only requests a connection. No network messages are
// exchanged until the event loop starts running in the next line.
c.connect(con);
// Start the ASIO io_service run loop
// this will cause a single connection to be made to the server. c.run()
// will exit when this connection is closed.
c.run();
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
}
+2
View File
@@ -8,3 +8,5 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+3 -3
View File
@@ -29,9 +29,9 @@
#define WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
class echo_handler : public server::handler {
void on_message(connection_ptr con, std::string msg) {
con->write(msg);
}
void on_message(connection_ptr con, std::string msg) {
con->write(msg);
}
};
#endif // WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
+12 -7
View File
@@ -19,6 +19,13 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
<< " and message: " << msg->get_payload()
<< std::endl;
// check for a special command to instruct the server to stop listening so
// it can be cleanly exited.
if (msg->get_payload() == "stop-listening") {
s->stop_listening();
return;
}
try {
s->send(hdl, msg->get_payload(), msg->get_opcode());
} catch (const websocketpp::lib::error_code& e) {
@@ -28,15 +35,15 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
}
int main() {
// Create a server endpoint
// Create a server endpoint
server echo_server;
try {
try {
// Set logging settings
echo_server.set_access_channels(websocketpp::log::alevel::all);
echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
// Initialize ASIO
// Initialize Asio
echo_server.init_asio();
// Register our message handler
@@ -48,12 +55,10 @@ int main() {
// Start the server accept loop
echo_server.start_accept();
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
echo_server.run();
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
+18
View File
@@ -0,0 +1,18 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (OPENSSL_FOUND)
init_target (echo_server_both)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_openssl()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
endif()
+24
View File
@@ -0,0 +1,24 @@
## Combo plain+tls echo server
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
prgs += env_cpp11.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
prgs += env.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
Return('prgs')
@@ -0,0 +1,87 @@
#include <websocketpp/config/asio.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
// define types for two different server endpoints, one for each config we are
// using
typedef websocketpp::server<websocketpp::config::asio> server_plain;
typedef websocketpp::server<websocketpp::config::asio_tls> server_tls;
// alias some of the bind related functions as they are a bit long
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
// type of the ssl context pointer is long so alias it
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
// The shared on_message handler takes a template parameter so the function can
// resolve any endpoint dependent types like message_ptr or connection_ptr
template <typename EndpointType>
void on_message(EndpointType* s, websocketpp::connection_hdl hdl,
typename EndpointType::message_ptr msg)
{
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
try {
s->send(hdl, msg->get_payload(), msg->get_opcode());
} catch (const websocketpp::lib::error_code& e) {
std::cout << "Echo failed because: " << e
<< "(" << e.message() << ")" << std::endl;
}
}
// No change to TLS init methods from echo_server_tls
std::string get_password() {
return "test";
}
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
try {
ctx->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::no_sslv3 |
boost::asio::ssl::context::single_dh_use);
ctx->set_password_callback(bind(&get_password));
ctx->use_certificate_chain_file("server.pem");
ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem);
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
return ctx;
}
int main() {
// set up an external io_service to run both endpoints on. This is not
// strictly necessary, but simplifies thread management a bit.
boost::asio::io_service ios;
// set up plain endpoint
server_plain endpoint_plain;
// initialize asio with our external io_service rather than an internal one
endpoint_plain.init_asio(&ios);
endpoint_plain.set_message_handler(
bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2));
endpoint_plain.listen(80);
endpoint_plain.start_accept();
// set up tls endpoint
server_tls endpoint_tls;
endpoint_tls.init_asio(&ios);
endpoint_tls.set_message_handler(
bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2));
// TLS endpoint has an extra handler for the tls init
endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1));
// tls endpoint listens on a different port
endpoint_tls.listen(443);
endpoint_tls.start_accept();
// Start the ASIO io_service run loop running both endpoints
ios.run();
}
+58
View File
@@ -0,0 +1,58 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A0ED66EF872A48A9
gXuvKojXzApVhhPVNdRliiajbC4PtwQG5c8TA7JADLgwOR7o9t6KtXEr37bDRpvB
9aO9P+SJaK5OOp3XKPGthOdqv+tvCRTlmzmC8GjPLBX389DWT2xoGu7JkGwDtdSm
rnF49Rlp5bfjpACk5xKNiKeDo1CWfeEJzw9Kto0g+5eMaEdors64oPzjXs3geA2g
TxCJSHv9qSX6++pCLKKCUTbyzidAxV/Zb0AAubt5V40QKqX4HhSwwstFnTaX3tlb
3QOdY+y04VIkM6d7qN5W8M7NzRkMpZ1qBpQcUMpkhQcRzWP2wub5AAff9D2GntRd
4Dz1vn3u41U3Okdr0CNj+iH7byCzuokoAhk6ZQEN6WB+GTpGgfBXdtUZrfpb0MKm
UNYP5AF2AmUqJRXhViTDVtu/V2tHF3LGuNT+W2Dz+spFZEq0byEO0N858eR0dikc
6jOASvNQbSwD0+mkgBC1gXKKU3ngj2gpJUwljeACdWFd8N2egrZfyI05CmX7vPNC
NXbs7k2buWNdjP4/D8IM+HDVidWzQa/kG/qokXKqllem9Egg37lUucwnP3cX2/Hw
U2mfaBWzeZtqc+GqRp08rYIql+Reai3sUYlQMnNk01prVY47UQb+dxuqjaxGV5Xx
Xkx0s2mfQnNRjL4S7Hjhqelufi6GpkCQ2EGsPpA+6K1ztZ0ame9Q2BE1SXeM/6vU
rxT5nRrCxueyXAyQSGcqMX9//gSeK8WWBqG/c1IAMVDa0NWrJeOJhSziE+ta3B0m
bHAPBY6vh0iB3lLdRlbUOPbC6R1TpxMOs+6Vbs2+OTifFpvOVymEoZq/nroyg68P
vn5uCKogwWA7o8EArf/UTlIwWJmH9bgILdZKld4wMel2HQg16RDzm+mEXAJi52a/
FC+fgfphdxltmUJ+rqOyR4AHULjaTWUQqTIB6sdlzgmES1nXAiE71zX//KFqomar
O60SPPk3C1bs0x5DsvmGJa8SIfDhyd+D7NPyqwEKqrZsaotYGklNkfqxa6pa8mrc
ejxquW1PK4FvBk26+osu5a90Jih0PcQM7DUMMr2WHdTiMSXWAiK2ToYF8Itt25Qv
Cd0CsSYw9CJkXNr1u1+mObheaY9QYOmztnSJLy4ZO2JsMhqNwuAueIcwmhXOREq7
kzlnGMgJcuSeAS/OBNj8Zgx0c7QQ0kzc+YmnOCsqoMtPsu/CsXJ4iJiM3Tki/2jT
bywrTiQwE6R3a/87GREOREX+WLicZBWX3k9/4tBL5XSe1p5wPpuIRQUDvAGNfNHP
JN7kujDF4SehilF1qtvCygAwvxHFDj+EwhXKNDKJzoZZIM15rAk3k92n2j6nz1qH
a3xOU05yydOlO6F6w51I1QoDddmkzCRNB0TeO3D6rekHsCK1aDWmC+qRcm2ZFtVz
sY6fdZN2NEmMQokIh9Opi1f8CSYSizPESMzdu2SF0xVO9n/IGIkn1ksK04O2BZo0
X3LBPHLfCRsQNY1eF17bj07fYU2oPZKs/XzJiwxkqK6LFvpeAVaYrtg9fqRO/UVe
QhUIj3BL550ocEpa15xLehLrmwzYiW5zwGjSHQ4EgZluGLCwyKGTh4QswEJRA9Rt
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIE0DCCA7igAwIBAgIJAM5MuKJezXq0MA0GCSqGSIb3DQEBBQUAMIGgMQswCQYD
VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xGDAW
BgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0KysxFjAU
BgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3RlckB6
YXBob3lkLmNvbTAeFw0xMTExMTUyMTIwMDZaFw0xMjExMTQyMTIwMDZaMIGgMQsw
CQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28x
GDAWBgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0Kysx
FjAUBgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3Rl
ckB6YXBob3lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANR0
tdwAnIB8I9qRZ7QbzEWY95RpM7GIn0u/9oH90PzdHiE0rXSkKT+yw3XUzH0iw5t0
5dEwSC+srSP5Vm4cA6kXc94agVVaPW89tGcdP4fHptCruSrzQsDXELCPl5UUvMpA
YUcGisdXYPN/EeOoqb9wKWxoW5mREsyyeWWS89fYN5qU/d0QpbSvEWghqLbL/ZS2
hOlXT9LufOeA+vHiV1/T/h5xC7ecIH02YDQw1EnqxbPmkLPcWThztLS9FiufNDRM
Rhcoaj2b9VDHvDwdbeA0T5v5qNdG34LaapYOelxzQMOtM0f9Dgqehodyxl2qm9mR
lq432dlOEzDnVCPNHwECAwEAAaOCAQkwggEFMB0GA1UdDgQWBBTTPKfNMnKOykhv
+vKS7vql5JsMyzCB1QYDVR0jBIHNMIHKgBTTPKfNMnKOykhv+vKS7vql5JsMy6GB
pqSBozCBoDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQH
EwdDaGljYWdvMRgwFgYDVQQKEw9aYXBob3lkIFN0dWRpb3MxFDASBgNVBAsTC1dl
YlNvY2tldCsrMRYwFAYDVQQDEw1QZXRlciBUaG9yc29uMSQwIgYJKoZIhvcNAQkB
FhV3ZWJtYXN0ZXJAemFwaG95ZC5jb22CCQDOTLiiXs16tDAMBgNVHRMEBTADAQH/
MA0GCSqGSIb3DQEBBQUAA4IBAQB+SH0s/hrv5VYqgX6SNLzxdSLvCVsUkCdTpxwY
wOJ84XmYcXDMhKDtZqLtOtN6pfEwVusFlC9mkieuunztCnWNmsSG83RuljJPjFSi
1d4Id4bKEQkQ4cfnjoHKivRrViWLnxuNnLzC6tpyGH/35kKWhhr6T58AXerFgVw3
mHvLPTr1DuhdAZA0ZuvuseVAFFAjI3RetSySwHJE3ak8KswDVfLi6E3XxMVsIWTS
/iFsC2WwoZQlljya2V/kRYIhu+uCdqJ01wunn2BvmURPSgr4GTBF0FQ9JGpNbXxM
TAU7oQJgyFc5sCcuEgPTO0dWVQTvdZVgay4tkmduKDRkmJBF
-----END CERTIFICATE-----
+3
View File
@@ -12,4 +12,7 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_openssl()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
endif()
+8
View File
@@ -0,0 +1,8 @@
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAqxMGKZB8YNV8WQnbJWwwwmifc+PfVRtd1FN5v5aQSsf6dpjX3Zlh
N1NmgecsQyg4u2EWe4Umta10QzCgYaxf6QdTCg7iprLzFNw7IvWYbQ6du12NMGDr
hmwA6KQKwbTgPL6mSlSlcK2wTP2FzxDTNffFu10cB/6Fj4kdQjPG0c1Koz/z7OOq
BuDElJLClS8rjp3z1xvrc7gX95dFa2KaKgOAYDkpe8tfHRhHfJeIVS/whH9hzx6r
OBg+E5K9JyvayrUoKgPeptRKCqo8A4YevtMLpRxMup0nMUgAIv6+BGTwPAFpwgl/
8UIVcvjh1v95PwGDM/Q8yvIBJznBYk/e2wIBAg==
-----END DH PARAMETERS-----
+100 -18
View File
@@ -1,3 +1,39 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* NOTES
*
* This example uses a number of standard classes through the websocketpp::lib
* namespace. This is to allow easy switching between Boost, the C++11 STL, and
* the standalone Asio library. Your program need not use these namespaces if
* you do not need this sort of flexibility.
*/
#include <websocketpp/config/asio.hpp>
#include <websocketpp/server.hpp>
@@ -12,7 +48,7 @@ using websocketpp::lib::bind;
// pull out the type of messages sent by our config
typedef websocketpp::config::asio::message_type::ptr message_ptr;
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
std::cout << "on_message called with hdl: " << hdl.lock().get()
@@ -27,46 +63,92 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
}
}
void on_http(server* s, websocketpp::connection_hdl hdl) {
server::connection_ptr con = s->get_con_from_hdl(hdl);
con->set_body("Hello World!");
con->set_status(websocketpp::http::status_code::ok);
}
std::string get_password() {
return "test";
}
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
// See https://wiki.mozilla.org/Security/Server_Side_TLS for more details about
// the TLS modes. The code below demonstrates how to implement both the modern
enum tls_mode {
MOZILLA_INTERMEDIATE = 1,
MOZILLA_MODERN = 2
};
context_ptr on_tls_init(tls_mode mode, websocketpp::connection_hdl hdl) {
namespace asio = websocketpp::lib::asio;
std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
std::cout << "using TLS mode: " << (mode == MOZILLA_MODERN ? "Mozilla Modern" : "Mozilla Intermediate") << std::endl;
context_ptr ctx = websocketpp::lib::make_shared<asio::ssl::context>(asio::ssl::context::sslv23);
try {
ctx->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::single_dh_use);
if (mode == MOZILLA_MODERN) {
// Modern disables TLSv1
ctx->set_options(asio::ssl::context::default_workarounds |
asio::ssl::context::no_sslv2 |
asio::ssl::context::no_sslv3 |
asio::ssl::context::no_tlsv1 |
asio::ssl::context::single_dh_use);
} else {
ctx->set_options(asio::ssl::context::default_workarounds |
asio::ssl::context::no_sslv2 |
asio::ssl::context::no_sslv3 |
asio::ssl::context::single_dh_use);
}
ctx->set_password_callback(bind(&get_password));
ctx->use_certificate_chain_file("server.pem");
ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem);
ctx->use_private_key_file("server.pem", asio::ssl::context::pem);
// Example method of generating this file:
// `openssl dhparam -out dh.pem 2048`
// Mozilla Intermediate suggests 1024 as the minimum size to use
// Mozilla Modern suggests 2048 as the minimum size to use.
ctx->use_tmp_dh_file("dh.pem");
std::string ciphers;
if (mode == MOZILLA_MODERN) {
ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK";
} else {
ciphers = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
}
if (SSL_CTX_set_cipher_list(ctx->native_handle() , ciphers.c_str()) != 1) {
std::cout << "Error setting cipher list" << std::endl;
}
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
std::cout << "Exception: " << e.what() << std::endl;
}
return ctx;
}
int main() {
// Create a server endpoint
server echo_server;
server echo_server;
// Initialize ASIO
echo_server.init_asio();
echo_server.init_asio();
// Register our message handler
echo_server.set_message_handler(bind(&on_message,&echo_server,::_1,::_2));
echo_server.set_tls_init_handler(bind(&on_tls_init,::_1));
echo_server.set_http_handler(bind(&on_http,&echo_server,::_1));
echo_server.set_tls_init_handler(bind(&on_tls_init,MOZILLA_INTERMEDIATE,::_1));
// Listen on port 9002
echo_server.listen(9002);
// Listen on port 9002
echo_server.listen(9002);
// Start the server accept loop
echo_server.start_accept();
// Start the server accept loop
echo_server.start_accept();
// Start the ASIO io_service run loop
echo_server.run();
// Start the ASIO io_service run loop
echo_server.run();
}
+51 -54
View File
@@ -1,58 +1,55 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A0ED66EF872A48A9
gXuvKojXzApVhhPVNdRliiajbC4PtwQG5c8TA7JADLgwOR7o9t6KtXEr37bDRpvB
9aO9P+SJaK5OOp3XKPGthOdqv+tvCRTlmzmC8GjPLBX389DWT2xoGu7JkGwDtdSm
rnF49Rlp5bfjpACk5xKNiKeDo1CWfeEJzw9Kto0g+5eMaEdors64oPzjXs3geA2g
TxCJSHv9qSX6++pCLKKCUTbyzidAxV/Zb0AAubt5V40QKqX4HhSwwstFnTaX3tlb
3QOdY+y04VIkM6d7qN5W8M7NzRkMpZ1qBpQcUMpkhQcRzWP2wub5AAff9D2GntRd
4Dz1vn3u41U3Okdr0CNj+iH7byCzuokoAhk6ZQEN6WB+GTpGgfBXdtUZrfpb0MKm
UNYP5AF2AmUqJRXhViTDVtu/V2tHF3LGuNT+W2Dz+spFZEq0byEO0N858eR0dikc
6jOASvNQbSwD0+mkgBC1gXKKU3ngj2gpJUwljeACdWFd8N2egrZfyI05CmX7vPNC
NXbs7k2buWNdjP4/D8IM+HDVidWzQa/kG/qokXKqllem9Egg37lUucwnP3cX2/Hw
U2mfaBWzeZtqc+GqRp08rYIql+Reai3sUYlQMnNk01prVY47UQb+dxuqjaxGV5Xx
Xkx0s2mfQnNRjL4S7Hjhqelufi6GpkCQ2EGsPpA+6K1ztZ0ame9Q2BE1SXeM/6vU
rxT5nRrCxueyXAyQSGcqMX9//gSeK8WWBqG/c1IAMVDa0NWrJeOJhSziE+ta3B0m
bHAPBY6vh0iB3lLdRlbUOPbC6R1TpxMOs+6Vbs2+OTifFpvOVymEoZq/nroyg68P
vn5uCKogwWA7o8EArf/UTlIwWJmH9bgILdZKld4wMel2HQg16RDzm+mEXAJi52a/
FC+fgfphdxltmUJ+rqOyR4AHULjaTWUQqTIB6sdlzgmES1nXAiE71zX//KFqomar
O60SPPk3C1bs0x5DsvmGJa8SIfDhyd+D7NPyqwEKqrZsaotYGklNkfqxa6pa8mrc
ejxquW1PK4FvBk26+osu5a90Jih0PcQM7DUMMr2WHdTiMSXWAiK2ToYF8Itt25Qv
Cd0CsSYw9CJkXNr1u1+mObheaY9QYOmztnSJLy4ZO2JsMhqNwuAueIcwmhXOREq7
kzlnGMgJcuSeAS/OBNj8Zgx0c7QQ0kzc+YmnOCsqoMtPsu/CsXJ4iJiM3Tki/2jT
bywrTiQwE6R3a/87GREOREX+WLicZBWX3k9/4tBL5XSe1p5wPpuIRQUDvAGNfNHP
JN7kujDF4SehilF1qtvCygAwvxHFDj+EwhXKNDKJzoZZIM15rAk3k92n2j6nz1qH
a3xOU05yydOlO6F6w51I1QoDddmkzCRNB0TeO3D6rekHsCK1aDWmC+qRcm2ZFtVz
sY6fdZN2NEmMQokIh9Opi1f8CSYSizPESMzdu2SF0xVO9n/IGIkn1ksK04O2BZo0
X3LBPHLfCRsQNY1eF17bj07fYU2oPZKs/XzJiwxkqK6LFvpeAVaYrtg9fqRO/UVe
QhUIj3BL550ocEpa15xLehLrmwzYiW5zwGjSHQ4EgZluGLCwyKGTh4QswEJRA9Rt
MIIEowIBAAKCAQEA77v5VbFaq+geVd/RCLXoKTWj/LgXGjiOXBpJZca3o5edi7N1
Ej41/13jfZ4OxgFIRFAALd+fU4NsObXzskth3rJLmJjUtGajRIPqF2IUVjFMmybQ
9dUDSqPzd/bG+ul0DP7DNuiBcLC8XNC3/kchPUzVq9gNDk56jXn87kMoIkVXBWQS
Rwk0yCtELSfwxxRCrGKgQDfXnRdwmkPe42DmKtdGksXJlUhP1UVTAXaSw1Nz64LV
9bJje/eoDsSe4OxifVVToE6ZxIW+r1jVgrcupeYXQrSHIztl2U/rx2JkGMN0eS+P
qrsJmkmRBN1cpgmvSV7WoM3hj6Eq71z4Dfv6EwIDAQABAoIBAEXAL19bZsI1mv3p
TOx34MB8tuXEuhQK+ICbtVdDZhLW/iOzZxCTwSo3qwTVg/7gSKJ3lFXEhprJ1idE
ZU8u157vyUbw0JJceoxoxSdghgI9/cf2lz2vaHHDGgeBaYt/eSB+z1WeeGrNQUDQ
CXiWQXmQbWq+Ra4v70BSieDY8UhmzCTRhvfZV80vaY/4SnHxJ9C8Nu8/An7U3pwq
ccfTaWMp3Q5ztmEnExF6/b1SUsnI8rzFovw/4C50AU09N/Z6zZVFsXgJAT2Kd1Tx
HfP1vUkWZ/TJ6kcmVIV9U3uMcedBD8Rb/3M0Qdp+eymQ+1oYQ3K3/a2RlUQIeXzf
hRbE4wECgYEA/WyULrwBsvSMPqK0K9pZpv921Yl6d4bGnpxKze7ltc9o5/LsU35q
8u29Es7cPyhyUDOsPW8v2CNjw54t+eFGsu59bBvXZNz5gB7hTUEyLntB24cO5PmN
kVExcMDFC6NgPaauBtUhODievKJ2C8P7sRJDAVKE9KkavDddU7nSEjMCgYEA8ivG
AqwNXYsiIFjAo4uj3kuBFt8LU/q4m6GXI+9qyxfiJjuF1dROx5qaQGiE85VaBFUu
gpbnjZH7s+BBgoaQhrB4i6mztljdN1KKuAlnjhB+Fywg8m8N9lAi3wIaxnIEqDkU
vFiIFPTBCk0U7IZ/OyCrKPQTE9ApWHfBwA/vWKECgYBQixrJg61SkBCms5Vpvprx
zY2aLniC1o33yRqpOr09PG9OENH1c19QWCjYenBbjmJOhS2/1L+zBQRnHrXkDion
Ik8wdeTORMDzbF0U7ZyiU0BKIjGkqn/I6LI68LlvinxC+9+hgkltkek5cLTt5lrv
Gyu6ltx02e4KVdpOiuduKwKBgQC3U0PWigCkK8ttyUIrjG5Evcu/UKH2tPpDdpQ/
8+JYVIAyiSTLtqjcmcDjuTvMWeeHGCTZXvtzRGvSw5VUBiIqlDTtJU6SX7s3QhkZ
MKVf+kQ5roJShJeBOzDquWEjkPTNlEiKPErn8lCgR7HrS/XNAPIRUpOOkCp8ekwF
5Qo/gQKBgAue3TeCeIzxh4PxSAk39Uaj+AaLvlYg8C+ucEodCNQZnJ7jOO0hHkfT
NvZBes0VukCGlBLOGRQtC3kgtyrerscnDiZOhdnJrhPIdNPC0k/p/uAfh7+C5Sxm
rCEL0S7kORdEjlIGd5j6ZEN/HZe8FyOYSjbFAoJSlAId9WMSxycQ
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIE0DCCA7igAwIBAgIJAM5MuKJezXq0MA0GCSqGSIb3DQEBBQUAMIGgMQswCQYD
VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xGDAW
BgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0KysxFjAU
BgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3RlckB6
YXBob3lkLmNvbTAeFw0xMTExMTUyMTIwMDZaFw0xMjExMTQyMTIwMDZaMIGgMQsw
CQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28x
GDAWBgNVBAoTD1phcGhveWQgU3R1ZGlvczEUMBIGA1UECxMLV2ViU29ja2V0Kysx
FjAUBgNVBAMTDVBldGVyIFRob3Jzb24xJDAiBgkqhkiG9w0BCQEWFXdlYm1hc3Rl
ckB6YXBob3lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANR0
tdwAnIB8I9qRZ7QbzEWY95RpM7GIn0u/9oH90PzdHiE0rXSkKT+yw3XUzH0iw5t0
5dEwSC+srSP5Vm4cA6kXc94agVVaPW89tGcdP4fHptCruSrzQsDXELCPl5UUvMpA
YUcGisdXYPN/EeOoqb9wKWxoW5mREsyyeWWS89fYN5qU/d0QpbSvEWghqLbL/ZS2
hOlXT9LufOeA+vHiV1/T/h5xC7ecIH02YDQw1EnqxbPmkLPcWThztLS9FiufNDRM
Rhcoaj2b9VDHvDwdbeA0T5v5qNdG34LaapYOelxzQMOtM0f9Dgqehodyxl2qm9mR
lq432dlOEzDnVCPNHwECAwEAAaOCAQkwggEFMB0GA1UdDgQWBBTTPKfNMnKOykhv
+vKS7vql5JsMyzCB1QYDVR0jBIHNMIHKgBTTPKfNMnKOykhv+vKS7vql5JsMy6GB
pqSBozCBoDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQH
EwdDaGljYWdvMRgwFgYDVQQKEw9aYXBob3lkIFN0dWRpb3MxFDASBgNVBAsTC1dl
YlNvY2tldCsrMRYwFAYDVQQDEw1QZXRlciBUaG9yc29uMSQwIgYJKoZIhvcNAQkB
FhV3ZWJtYXN0ZXJAemFwaG95ZC5jb22CCQDOTLiiXs16tDAMBgNVHRMEBTADAQH/
MA0GCSqGSIb3DQEBBQUAA4IBAQB+SH0s/hrv5VYqgX6SNLzxdSLvCVsUkCdTpxwY
wOJ84XmYcXDMhKDtZqLtOtN6pfEwVusFlC9mkieuunztCnWNmsSG83RuljJPjFSi
1d4Id4bKEQkQ4cfnjoHKivRrViWLnxuNnLzC6tpyGH/35kKWhhr6T58AXerFgVw3
mHvLPTr1DuhdAZA0ZuvuseVAFFAjI3RetSySwHJE3ak8KswDVfLi6E3XxMVsIWTS
/iFsC2WwoZQlljya2V/kRYIhu+uCdqJ01wunn2BvmURPSgr4GTBF0FQ9JGpNbXxM
TAU7oQJgyFc5sCcuEgPTO0dWVQTvdZVgay4tkmduKDRkmJBF
MIIEpzCCA4+gAwIBAgIJAMlCHvwnJ+F/MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xGTAXBgNVBAoT
EFdlYlNvY2tldCsrIERlbW8xIjAgBgNVBAMTGXV0aWxpdGllcy53ZWJzb2NrZXRw
cC5vcmcxJjAkBgkqhkiG9w0BCQEWF3dlYnNvY2tldHBwQHphcGhveWQuY29tMB4X
DTE1MDQyNTE1NTk1M1oXDTE4MDMyODE1NTk1M1owgZMxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEZMBcGA1UEChMQV2ViU29ja2V0
KysgRGVtbzEiMCAGA1UEAxMZdXRpbGl0aWVzLndlYnNvY2tldHBwLm9yZzEmMCQG
CSqGSIb3DQEJARYXd2Vic29ja2V0cHBAemFwaG95ZC5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDvu/lVsVqr6B5V39EItegpNaP8uBcaOI5cGkll
xrejl52Ls3USPjX/XeN9ng7GAUhEUAAt359Tg2w5tfOyS2HeskuYmNS0ZqNEg+oX
YhRWMUybJtD11QNKo/N39sb66XQM/sM26IFwsLxc0Lf+RyE9TNWr2A0OTnqNefzu
QygiRVcFZBJHCTTIK0QtJ/DHFEKsYqBAN9edF3CaQ97jYOYq10aSxcmVSE/VRVMB
dpLDU3PrgtX1smN796gOxJ7g7GJ9VVOgTpnEhb6vWNWCty6l5hdCtIcjO2XZT+vH
YmQYw3R5L4+quwmaSZEE3VymCa9JXtagzeGPoSrvXPgN+/oTAgMBAAGjgfswgfgw
HQYDVR0OBBYEFAWNBET93ZzSukXGkuGb93CfmUkDMIHIBgNVHSMEgcAwgb2AFAWN
BET93ZzSukXGkuGb93CfmUkDoYGZpIGWMIGTMQswCQYDVQQGEwJVUzELMAkGA1UE
CBMCSUwxEDAOBgNVBAcTB0NoaWNhZ28xGTAXBgNVBAoTEFdlYlNvY2tldCsrIERl
bW8xIjAgBgNVBAMTGXV0aWxpdGllcy53ZWJzb2NrZXRwcC5vcmcxJjAkBgkqhkiG
9w0BCQEWF3dlYnNvY2tldHBwQHphcGhveWQuY29tggkAyUIe/Ccn4X8wDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA2DRQSDmo2Q5t8MEjp6jddRIFts5t
BDBWPSwJ0qvmheFt53MuLds2hhvMn42WGrKtVJiLiDyOWuUZ41REJZb1uaissUuY
r9pLuP5QLdibx7+/30iDEY0OGTgtSTfgwNx8bIApBSHoZEN3/HaikqplBng2+6u/
kTe6UnRrBJ+8JOGl+duhCXNPeSyLa2NcrxE9XpWC/k1kC9MTUF+2NuqCtK3zO8ci
p0mqARWDSrEBYISh3dAOgDFrcX6zj+0MK+iswu3ijEdItGAjxjlQ2t4XT1T/CDbc
ysHg04TJw7v682+v124GrnrAPYUK34OK8kFVJ60SNYRUi7euOCdTM4Lwkw==
-----END CERTIFICATE-----
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (enriched_storage)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
@@ -61,7 +61,7 @@ public:
void on_message(connection_hdl hdl, server::message_ptr msg) {
connection_ptr con = m_server.get_con_from_hdl(hdl);
if (con->name == "") {
if (con->name.empty()) {
con->name = msg->get_payload();
std::cout << "Setting name of connection with sessionid "
<< con->sessionid << " to " << con->name << std::endl;
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (external_io_service)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+23
View File
@@ -0,0 +1,23 @@
## Main development example
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS)
Return('prgs')
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "tcp_echo_server.hpp"
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::server<websocketpp::config::asio> ws_echo_server;
// Define a callback to handle incoming messages
void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_server::message_ptr msg) {
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
// check for a special command to instruct the server to stop listening so
// it can be cleanly exited.
if (msg->get_payload() == "stop-listening") {
s->stop_listening();
return;
}
try {
s->send(hdl, msg->get_payload(), msg->get_opcode());
} catch (websocketpp::lib::error_code const & e) {
std::cout << "Echo failed because: " << e
<< "(" << e.message() << ")" << std::endl;
}
}
int main() {
asio::io_service service;
// Add a TCP echo server on port 9003
tcp_echo_server custom_http_server(service, 9003);
// Add a WebSocket echo server on port 9002
ws_echo_server ws_server;
ws_server.set_access_channels(websocketpp::log::alevel::all);
ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
// The only difference in this code between an internal and external
// io_service is the different constructor to init_asio
ws_server.init_asio(&service);
// Register our message handler
ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2));
ws_server.listen(9002);
ws_server.start_accept();
// TODO: add a timer?
// Start the Asio io_service run loop for all
service.run();
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* TCP Echo Server
*
* This file defines a simple TCP Echo Server. It is adapted from the Asio
* example: cpp03/echo/async_tcp_echo_server.cpp
*/
#include <websocketpp/common/asio.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/functional.hpp>
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
namespace asio = websocketpp::lib::asio;
struct tcp_echo_session : websocketpp::lib::enable_shared_from_this<tcp_echo_session> {
typedef websocketpp::lib::shared_ptr<tcp_echo_session> ptr;
tcp_echo_session(asio::io_service & service) : m_socket(service) {}
void start() {
m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)),
websocketpp::lib::bind(
&tcp_echo_session::handle_read, shared_from_this(), _1, _2));
}
void handle_read(const asio::error_code & ec, size_t transferred) {
if (!ec) {
asio::async_write(m_socket,
asio::buffer(m_buffer, transferred),
bind(&tcp_echo_session::handle_write, shared_from_this(), _1));
}
}
void handle_write(const asio::error_code & ec) {
if (!ec) {
m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)),
bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2));
}
}
asio::ip::tcp::socket m_socket;
char m_buffer[1024];
};
struct tcp_echo_server {
tcp_echo_server(asio::io_service & service, short port)
: m_service(service)
, m_acceptor(service, asio::ip::tcp::endpoint(asio::ip::tcp::v6(), port))
{
this->start_accept();
}
void start_accept() {
tcp_echo_session::ptr new_session(new tcp_echo_session(m_service));
m_acceptor.async_accept(new_session->m_socket,
bind(&tcp_echo_server::handle_accept, this, new_session, _1));
}
void handle_accept(tcp_echo_session::ptr new_session, const asio::error_code & ec) {
if (!ec) {
new_session->start();
}
start_accept();
}
asio::io_service & m_service;
asio::ip::tcp::acceptor m_acceptor;
};
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (handler_switch)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (iostream_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+5 -9
View File
@@ -18,17 +18,17 @@ typedef server::message_ptr message_ptr;
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
s->get_alog().write(websocketpp::log::alevel::app,
"Text Message Received: "+msg->get_payload());
"Text Message Received: "+msg->get_payload());
} else {
s->get_alog().write(websocketpp::log::alevel::app,
"Binary Message Received: "+websocketpp::utility::to_hex(msg->get_payload()));
"Binary Message Received: "+websocketpp::utility::to_hex(msg->get_payload()));
}
try {
s->send(hdl, msg->get_payload(), msg->get_opcode());
} catch (const websocketpp::lib::error_code& e) {
s->get_alog().write(websocketpp::log::alevel::app,
"Echo Failed: "+e.message());
"Echo Failed: "+e.message());
}
}
@@ -36,7 +36,7 @@ int main() {
server s;
std::ofstream log;
try {
try {
// set up access channels to only log interesting things
s.clear_access_channels(websocketpp::log::alevel::all);
s.set_access_channels(websocketpp::log::alevel::connect);
@@ -82,12 +82,8 @@ int main() {
}
con->eof();
}
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
log.close();
}
+2
View File
@@ -8,3 +8,5 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+3 -1
View File
@@ -5,7 +5,7 @@
typedef websocketpp::server<websocketpp::config::asio> server;
void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg) {
void on_message(websocketpp::connection_hdl, server::message_ptr msg) {
std::cout << msg->get_payload() << std::endl;
}
@@ -13,6 +13,8 @@ int main() {
server print_server;
print_server.set_message_handler(&on_message);
print_server.set_access_channels(websocketpp::log::alevel::all);
print_server.set_error_channels(websocketpp::log::elevel::all);
print_server.init_asio();
print_server.listen(9002);
+24
View File
@@ -0,0 +1,24 @@
## Scratch client example
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
prgs += env_cpp11.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+270
View File
@@ -0,0 +1,270 @@
/*
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// **NOTE:** This file is a snapshot of the WebSocket++ utility client tutorial.
// Additional related material can be found in the tutorials/utility_client
// directory of the WebSocket++ repository.
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/common/thread.hpp>
#include <websocketpp/common/memory.hpp>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>
typedef websocketpp::client<websocketpp::config::asio_client> client;
class connection_metadata {
public:
typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;
connection_metadata(int id, websocketpp::connection_hdl hdl, std::string uri)
: m_id(id)
, m_hdl(hdl)
, m_status("Connecting")
, m_uri(uri)
, m_server("N/A")
{}
void on_open(client * c, websocketpp::connection_hdl hdl) {
m_status = "Open";
client::connection_ptr con = c->get_con_from_hdl(hdl);
m_server = con->get_response_header("Server");
}
void on_fail(client * c, websocketpp::connection_hdl hdl) {
m_status = "Failed";
client::connection_ptr con = c->get_con_from_hdl(hdl);
m_server = con->get_response_header("Server");
m_error_reason = con->get_ec().message();
}
void on_close(client * c, websocketpp::connection_hdl hdl) {
m_status = "Closed";
client::connection_ptr con = c->get_con_from_hdl(hdl);
std::stringstream s;
s << "close code: " << con->get_remote_close_code() << " ("
<< websocketpp::close::status::get_string(con->get_remote_close_code())
<< "), close reason: " << con->get_remote_close_reason();
m_error_reason = s.str();
}
websocketpp::connection_hdl get_hdl() const {
return m_hdl;
}
int get_id() const {
return m_id;
}
std::string get_status() const {
return m_status;
}
friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
private:
int m_id;
websocketpp::connection_hdl m_hdl;
std::string m_status;
std::string m_uri;
std::string m_server;
std::string m_error_reason;
};
std::ostream & operator<< (std::ostream & out, connection_metadata const & data) {
out << "> URI: " << data.m_uri << "\n"
<< "> Status: " << data.m_status << "\n"
<< "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n"
<< "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason);
return out;
}
class websocket_endpoint {
public:
websocket_endpoint () : m_next_id(0) {
m_endpoint.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint.clear_error_channels(websocketpp::log::elevel::all);
m_endpoint.init_asio();
m_endpoint.start_perpetual();
m_thread.reset(new websocketpp::lib::thread(&client::run, &m_endpoint));
}
~websocket_endpoint() {
m_endpoint.stop_perpetual();
for (con_list::const_iterator it = m_connection_list.begin(); it != m_connection_list.end(); ++it) {
if (it->second->get_status() != "Open") {
// Only close open connections
continue;
}
std::cout << "> Closing connection " << it->second->get_id() << std::endl;
websocketpp::lib::error_code ec;
m_endpoint.close(it->second->get_hdl(), websocketpp::close::status::going_away, "", ec);
if (ec) {
std::cout << "> Error closing connection " << it->second->get_id() << ": "
<< ec.message() << std::endl;
}
}
m_thread->join();
}
int connect(std::string const & uri) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
if (ec) {
std::cout << "> Connect initialization error: " << ec.message() << std::endl;
return -1;
}
int new_id = m_next_id++;
connection_metadata::ptr metadata_ptr(new connection_metadata(new_id, con->get_handle(), uri));
m_connection_list[new_id] = metadata_ptr;
con->set_open_handler(websocketpp::lib::bind(
&connection_metadata::on_open,
metadata_ptr,
&m_endpoint,
websocketpp::lib::placeholders::_1
));
con->set_fail_handler(websocketpp::lib::bind(
&connection_metadata::on_fail,
metadata_ptr,
&m_endpoint,
websocketpp::lib::placeholders::_1
));
con->set_close_handler(websocketpp::lib::bind(
&connection_metadata::on_close,
metadata_ptr,
&m_endpoint,
websocketpp::lib::placeholders::_1
));
m_endpoint.connect(con);
return new_id;
}
void close(int id, websocketpp::close::status::value code, std::string reason) {
websocketpp::lib::error_code ec;
con_list::iterator metadata_it = m_connection_list.find(id);
if (metadata_it == m_connection_list.end()) {
std::cout << "> No connection found with id " << id << std::endl;
return;
}
m_endpoint.close(metadata_it->second->get_hdl(), code, reason, ec);
if (ec) {
std::cout << "> Error initiating close: " << ec.message() << std::endl;
}
}
connection_metadata::ptr get_metadata(int id) const {
con_list::const_iterator metadata_it = m_connection_list.find(id);
if (metadata_it == m_connection_list.end()) {
return connection_metadata::ptr();
} else {
return metadata_it->second;
}
}
private:
typedef std::map<int,connection_metadata::ptr> con_list;
client m_endpoint;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread;
con_list m_connection_list;
int m_next_id;
};
int main() {
bool done = false;
std::string input;
websocket_endpoint endpoint;
while (!done) {
std::cout << "Enter Command: ";
std::getline(std::cin, input);
if (input == "quit") {
done = true;
} else if (input == "help") {
std::cout
<< "\nCommand List:\n"
<< "connect <ws uri>\n"
<< "close <connection id> [<close code:default=1000>] [<close reason>]\n"
<< "show <connection id>\n"
<< "help: Display this help text\n"
<< "quit: Exit the program\n"
<< std::endl;
} else if (input.substr(0,7) == "connect") {
int id = endpoint.connect(input.substr(8));
if (id != -1) {
std::cout << "> Created connection with id " << id << std::endl;
}
} else if (input.substr(0,5) == "close") {
std::stringstream ss(input);
std::string cmd;
int id;
int close_code = websocketpp::close::status::normal;
std::string reason;
ss >> cmd >> id >> close_code;
std::getline(ss,reason);
endpoint.close(id, close_code, reason);
} else if (input.substr(0,4) == "show") {
int id = atoi(input.substr(5).c_str());
connection_metadata::ptr metadata = endpoint.get_metadata(id);
if (metadata) {
std::cout << *metadata << std::endl;
} else {
std::cout << "> Unknown connection id " << id << std::endl;
}
} else {
std::cout << "> Unrecognized Command" << std::endl;
}
}
return 0;
}
+24
View File
@@ -0,0 +1,24 @@
## Scratch server example
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] + ['z']
prgs += env_cpp11.Program('scratch_server', ["scratch_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs] + [tls_libs] + ['z']
prgs += env.Program('scratch_server', ["scratch_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+106
View File
@@ -0,0 +1,106 @@
/**
* This example is presently used as a scratch space. It may or may not be broken
* at any given time.
*/
#include <iostream>
#include <websocketpp/config/debug_asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
struct deflate_config : public websocketpp::config::debug_core {
typedef deflate_config type;
typedef debug_core base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
/// permessage_compress extension
struct permessage_deflate_config {};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
};
typedef websocketpp::server<deflate_config> server;
typedef server::message_ptr message_ptr;
// Define a callback to handle incoming messages
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
/*std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message (" << msg->get_payload().size() << "): " << msg->get_payload()
<< std::endl;
*/
try {
s->send(hdl, msg->get_payload(), msg->get_opcode());
} catch (const websocketpp::lib::error_code& e) {
std::cout << "Echo failed because: " << e
<< "(" << e.message() << ")" << std::endl;
}
}
int main(int argc, char * argv[]) {
// Create a server endpoint
server echo_server;
try {
// Set logging settings
if (argc > 1 && std::string(argv[1]) == "-d") {
echo_server.set_access_channels(websocketpp::log::alevel::all);
echo_server.set_error_channels(websocketpp::log::elevel::all);
} else {
echo_server.set_access_channels(websocketpp::log::alevel::none);
echo_server.set_error_channels(websocketpp::log::elevel::none);
}
// Initialize ASIO
echo_server.init_asio();
// Register our message handler
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
echo_server.set_message_handler(bind(&on_message,&echo_server,_1,_2));
// Listen on port 9002
echo_server.listen(9002);
// Start the server accept loop
echo_server.start_accept();
// Start the ASIO io_service run loop
echo_server.run();
} catch (const std::exception & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (simple_broadcast_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+1
View File
@@ -9,3 +9,4 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+1 -1
View File
@@ -12,7 +12,7 @@ env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is avaliable build using that, otherwise use boost
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
+7 -11
View File
@@ -43,13 +43,13 @@ void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
int main(int argc, char* argv[]) {
std::string uri = "ws://localhost:9001";
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
if (argc == 2) {
uri = argv[1];
}
try {
try {
// We expect there to be a lot of errors, so suppress them
sip_client.clear_access_channels(websocketpp::log::alevel::all);
sip_client.clear_error_channels(websocketpp::log::elevel::all);
@@ -69,7 +69,7 @@ int main(int argc, char* argv[]) {
sip_client.connect(con);
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
sip_client.run();
while(!received) {
@@ -78,11 +78,7 @@ int main(int argc, char* argv[]) {
std::cout << "done" << std::endl;
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (subprotocol_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
@@ -42,11 +42,7 @@ int main() {
s.start_accept();
s.run();
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
+2
View File
@@ -8,3 +8,5 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+11 -11
View File
@@ -30,20 +30,20 @@ public:
// Bind the handlers we are using
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::bind;
m_client.set_open_handler(bind(&telemetry_client::on_open,this,::_1));
m_client.set_close_handler(bind(&telemetry_client::on_close,this,::_1));
m_client.set_fail_handler(bind(&telemetry_client::on_fail,this,::_1));
m_client.set_open_handler(bind(&telemetry_client::on_open,this,_1));
m_client.set_close_handler(bind(&telemetry_client::on_close,this,_1));
m_client.set_fail_handler(bind(&telemetry_client::on_fail,this,_1));
}
// This method will block until the connection is complete
void run(const std::string & uri) {
// Create a new connection to the given URI
// Create a new connection to the given URI
websocketpp::lib::error_code ec;
client::connection_ptr con = m_client.get_connection(uri, ec);
if (ec) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Get Connection Error: "+ec.message());
return;
m_client.get_alog().write(websocketpp::log::alevel::app,
"Get Connection Error: "+ec.message());
return;
}
// Grab a handle for this connection so we can talk to it in a thread
@@ -65,7 +65,7 @@ public:
}
// The open handler will signal that we are ready to start sending telemetry
void on_open(websocketpp::connection_hdl hdl) {
void on_open(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection opened, starting telemetry!");
@@ -74,7 +74,7 @@ public:
}
// The close handler will signal that we should stop sending telemetry
void on_close(websocketpp::connection_hdl hdl) {
void on_close(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection closed, stopping telemetry!");
@@ -83,7 +83,7 @@ public:
}
// The fail handler will signal that we should stop sending telemetry
void on_fail(websocketpp::connection_hdl hdl) {
void on_fail(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection failed, stopping telemetry!");
@@ -128,7 +128,7 @@ public:
// in this simple example, we'll stop the telemetry loop.
if (ec) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Send Error: "+ec.message());
"Send Error: "+ec.message());
break;
}
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (telemetry_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+23
View File
@@ -0,0 +1,23 @@
## Main development example
##
Import('env')
Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+85
View File
@@ -0,0 +1,85 @@
<!doctype html>
<html>
<head>
<title>WebSocket++ Telemetry Client</title>
</head>
<body>
<script type="text/javascript">
var ws;
var url;
function connect() {
url = document.getElementById("server_url").value;
if ("WebSocket" in window) {
ws = new WebSocket(url);
} else if ("MozWebSocket" in window) {
ws = new MozWebSocket(url);
} else {
document.getElementById("messages").innerHTML += "This Browser does not support WebSockets<br />";
return;
}
ws.onopen = function(e) {
document.getElementById("messages").innerHTML += "Client: A connection to "+ws.url+" has been opened.<br />";
document.getElementById("server_url").disabled = true;
document.getElementById("toggle_connect").innerHTML = "Disconnect";
};
ws.onerror = function(e) {
document.getElementById("messages").innerHTML += "Client: An error occured, see console log for more details.<br />";
console.log(e);
};
ws.onclose = function(e) {
document.getElementById("messages").innerHTML += "Client: The connection to "+url+" was closed. ["+e.code+(e.reason != "" ? ","+e.reason : "")+"]<br />";
cleanup_disconnect();
};
ws.onmessage = function(e) {
document.getElementById("messages").innerHTML += "Server: "+e.data+"<br />";
};
}
function disconnect() {
ws.close();
cleanup_disconnect();
}
function cleanup_disconnect() {
document.getElementById("server_url").disabled = false;
document.getElementById("toggle_connect").innerHTML = "Connect";
}
function toggle_connect() {
if (document.getElementById("server_url").disabled === false) {
connect();
} else {
disconnect();
}
}
</script>
<style>
body,html {
margin: 0px;
padding: 0px;
}
#controls {
float:right;
background-color: #999;
}
</style>
<div id="controls">
<div id="server">
<input type="text" name="server_url" id="server_url" value="ws://localhost:9002" /><br />
<button id="toggle_connect" onclick="toggle_connect();">Connect</button>
</div>
</div>
<div id="messages"></div>
</body>
</html>
@@ -0,0 +1,203 @@
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <fstream>
#include <iostream>
#include <set>
#include <streambuf>
#include <string>
/**
* The telemetry server accepts connections and sends a message every second to
* each client containing an integer count. This example can be used as the
* basis for programs that expose a stream of telemetry data for logging,
* dashboards, etc.
*
* This example uses the timer based concurrency method and is self contained
* and singled threaded. Refer to telemetry client for an example of a similar
* telemetry setup using threads rather than timers.
*
* This example also includes an example simple HTTP server that serves a web
* dashboard displaying the count. This simple design is suitable for use
* delivering a small number of files to a small number of clients. It is ideal
* for cases like embedded dashboards that don't want the complexity of an extra
* HTTP server to serve static files.
*
* This design *will* fall over under high traffic or DoS conditions. In such
* cases you are much better off proxying to a real HTTP server for the http
* requests.
*/
class telemetry_server {
public:
typedef websocketpp::connection_hdl connection_hdl;
typedef websocketpp::server<websocketpp::config::asio> server;
telemetry_server() : m_count(0) {
// set up access channels to only log interesting things
m_endpoint.clear_access_channels(websocketpp::log::alevel::all);
m_endpoint.set_access_channels(websocketpp::log::alevel::access_core);
m_endpoint.set_access_channels(websocketpp::log::alevel::app);
// Initialize the Asio transport policy
m_endpoint.init_asio();
// Bind the handlers we are using
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::bind;
m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1));
m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1));
m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1));
}
void run(std::string docroot, uint16_t port) {
std::stringstream ss;
ss << "Running telemetry server on port "<< port <<" using docroot=" << docroot;
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ss.str());
m_docroot = docroot;
// listen on specified port
m_endpoint.listen(port);
// Start the server accept loop
m_endpoint.start_accept();
// Set the initial timer to start telemetry
set_timer();
// Start the ASIO io_service run loop
try {
m_endpoint.run();
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
}
void set_timer() {
m_timer = m_endpoint.set_timer(
1000,
websocketpp::lib::bind(
&telemetry_server::on_timer,
this,
websocketpp::lib::placeholders::_1
)
);
}
void on_timer(websocketpp::lib::error_code const & ec) {
if (ec) {
// there was an error, stop telemetry
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
"Timer Error: "+ec.message());
return;
}
std::stringstream val;
val << "count is " << m_count++;
// Broadcast count to all connections
con_list::iterator it;
for (it = m_connections.begin(); it != m_connections.end(); ++it) {
m_endpoint.send(*it,val.str(),websocketpp::frame::opcode::text);
}
// set timer for next telemetry check
set_timer();
}
void on_http(connection_hdl hdl) {
// Upgrade our connection handle to a full connection_ptr
server::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
std::ifstream file;
std::string filename = con->get_resource();
std::string response;
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
"http request1: "+filename);
if (filename == "/") {
filename = m_docroot+"index.html";
} else {
filename = m_docroot+filename.substr(1);
}
m_endpoint.get_alog().write(websocketpp::log::alevel::app,
"http request2: "+filename);
file.open(filename.c_str(), std::ios::in);
if (!file) {
// 404 error
std::stringstream ss;
ss << "<!doctype html><html><head>"
<< "<title>Error 404 (Resource not found)</title><body>"
<< "<h1>Error 404</h1>"
<< "<p>The requested URL " << filename << " was not found on this server.</p>"
<< "</body></head></html>";
con->set_body(ss.str());
con->set_status(websocketpp::http::status_code::not_found);
return;
}
file.seekg(0, std::ios::end);
response.reserve(file.tellg());
file.seekg(0, std::ios::beg);
response.assign((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
con->set_body(response);
con->set_status(websocketpp::http::status_code::ok);
}
void on_open(connection_hdl hdl) {
m_connections.insert(hdl);
}
void on_close(connection_hdl hdl) {
m_connections.erase(hdl);
}
private:
typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
server m_endpoint;
con_list m_connections;
server::timer_ptr m_timer;
std::string m_docroot;
// Telemetry data
uint64_t m_count;
};
int main(int argc, char* argv[]) {
telemetry_server s;
std::string docroot;
uint16_t port = 9002;
if (argc == 1) {
std::cout << "Usage: telemetry_server [documentroot] [port]" << std::endl;
return 1;
}
if (argc >= 2) {
docroot = std::string(argv[1]);
}
if (argc >= 3) {
int i = atoi(argv[2]);
if (i <= 0 || i > 65535) {
std::cout << "invalid port" << std::endl;
return 1;
}
port = uint16_t(i);
}
s.run(docroot, port);
return 0;
}
+6
View File
@@ -2,10 +2,16 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (ZLIB_FOUND)
init_target (testee_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_zlib()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
endif()
+2 -2
View File
@@ -14,10 +14,10 @@ prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+75 -14
View File
@@ -1,10 +1,75 @@
#include <websocketpp/config/asio_no_tls_client.hpp>
/*
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the WebSocket++ Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
#include <iostream>
typedef websocketpp::client<websocketpp::config::asio_client> client;
struct deflate_config : public websocketpp::config::asio_client {
typedef deflate_config type;
typedef asio_client base;
typedef base::concurrency_type concurrency_type;
typedef base::request_type request_type;
typedef base::response_type response_type;
typedef base::message_type message_type;
typedef base::con_msg_manager_type con_msg_manager_type;
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef base::alog_type alog_type;
typedef base::elog_type elog_type;
typedef base::rng_type rng_type;
struct transport_config : public base::transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::alog_type alog_type;
typedef type::elog_type elog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
/// permessage_compress extension
struct permessage_deflate_config {};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
};
typedef websocketpp::client<deflate_config> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
@@ -28,16 +93,16 @@ void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
}
int main(int argc, char* argv[]) {
// Create a server endpoint
// Create a server endpoint
client c;
std::string uri = "ws://localhost:9001";
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
if (argc == 2) {
uri = argv[1];
}
try {
try {
// We expect there to be a lot of errors, so suppress them
c.clear_access_channels(websocketpp::log::alevel::all);
c.clear_error_channels(websocketpp::log::elevel::all);
@@ -52,7 +117,7 @@ int main(int argc, char* argv[]) {
client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec);
c.connect(con);
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
c.run();
std::cout << "case count: " << case_count << std::endl;
@@ -74,11 +139,7 @@ int main(int argc, char* argv[]) {
std::cout << "done" << std::endl;
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
+17
View File
@@ -0,0 +1,17 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (ZLIB_FOUND)
init_target (testee_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_zlib()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
endif()
+2 -2
View File
@@ -14,10 +14,10 @@ prgs = []
# if a C++11 environment is available build using that, otherwise use boost
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] + ['z']
prgs += env.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+11 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -27,6 +27,7 @@
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
#include <iostream>
struct testee_config : public websocketpp::config::asio {
@@ -64,6 +65,12 @@ struct testee_config : public websocketpp::config::asio {
websocketpp::log::elevel::none;
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::none;
/// permessage_compress extension
struct permessage_deflate_config {};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
};
typedef websocketpp::server<testee_config> server;
@@ -80,7 +87,7 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
s->send(hdl, msg->get_payload(), msg->get_opcode());
}
void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket & s) {
void on_socket_init(websocketpp::connection_hdl, boost::asio::ip::tcp::socket & s) {
boost::asio::ip::tcp::no_delay option(true);
s.set_option(option);
}
@@ -124,7 +131,7 @@ int main(int argc, char * argv[]) {
typedef websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread_ptr;
std::vector<thread_ptr> ts;
for (size_t i = 0; i < num_threads; i++) {
ts.push_back(thread_ptr(new websocketpp::lib::thread(&server::run, &testee_server)));
ts.push_back(websocketpp::lib::make_shared<websocketpp::lib::thread>(&server::run, &testee_server));
}
for (size_t i = 0; i < num_threads; i++) {
@@ -132,11 +139,7 @@ int main(int argc, char * argv[]) {
}
}
} catch (const std::exception & e) {
} catch (websocketpp::exception const & e) {
std::cout << "exception: " << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << "error code: " << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
}
+2
View File
@@ -9,3 +9,5 @@ build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
+1 -1
View File
@@ -20,4 +20,4 @@ else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
Return('prgs')
+61 -6
View File
@@ -79,6 +79,14 @@ public:
m_error_reason = s.str();
}
void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
m_messages.push_back("<< " + msg->get_payload());
} else {
m_messages.push_back("<< " + websocketpp::utility::to_hex(msg->get_payload()));
}
}
websocketpp::connection_hdl get_hdl() const {
return m_hdl;
}
@@ -91,6 +99,10 @@ public:
return m_status;
}
void record_sent_message(std::string message) {
m_messages.push_back(">> " + message);
}
friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
private:
int m_id;
@@ -99,13 +111,20 @@ private:
std::string m_uri;
std::string m_server;
std::string m_error_reason;
std::vector<std::string> m_messages;
};
std::ostream & operator<< (std::ostream & out, connection_metadata const & data) {
out << "> URI: " << data.m_uri << "\n"
<< "> Status: " << data.m_status << "\n"
<< "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n"
<< "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason);
<< "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason) << "\n";
out << "> Messages Processed: (" << data.m_messages.size() << ") \n";
std::vector<std::string>::const_iterator it;
for (it = data.m_messages.begin(); it != data.m_messages.end(); ++it) {
out << *it << "\n";
}
return out;
}
@@ -119,7 +138,7 @@ public:
m_endpoint.init_asio();
m_endpoint.start_perpetual();
m_thread.reset(new websocketpp::lib::thread(&client::run, &m_endpoint));
m_thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run, &m_endpoint);
}
~websocket_endpoint() {
@@ -155,7 +174,7 @@ public:
}
int new_id = m_next_id++;
connection_metadata::ptr metadata_ptr(new connection_metadata(new_id, con->get_handle(), uri));
connection_metadata::ptr metadata_ptr = websocketpp::lib::make_shared<connection_metadata>(new_id, con->get_handle(), uri);
m_connection_list[new_id] = metadata_ptr;
con->set_open_handler(websocketpp::lib::bind(
@@ -176,6 +195,12 @@ public:
&m_endpoint,
websocketpp::lib::placeholders::_1
));
con->set_message_handler(websocketpp::lib::bind(
&connection_metadata::on_message,
metadata_ptr,
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2
));
m_endpoint.connect(con);
@@ -197,6 +222,24 @@ public:
}
}
void send(int id, std::string message) {
websocketpp::lib::error_code ec;
con_list::iterator metadata_it = m_connection_list.find(id);
if (metadata_it == m_connection_list.end()) {
std::cout << "> No connection found with id " << id << std::endl;
return;
}
m_endpoint.send(metadata_it->second->get_hdl(), message, websocketpp::frame::opcode::text, ec);
if (ec) {
std::cout << "> Error sending message: " << ec.message() << std::endl;
return;
}
metadata_it->second->record_sent_message(message);
}
connection_metadata::ptr get_metadata(int id) const {
con_list::const_iterator metadata_it = m_connection_list.find(id);
if (metadata_it == m_connection_list.end()) {
@@ -230,6 +273,7 @@ int main() {
std::cout
<< "\nCommand List:\n"
<< "connect <ws uri>\n"
<< "send <connection id> <message>\n"
<< "close <connection id> [<close code:default=1000>] [<close reason>]\n"
<< "show <connection id>\n"
<< "help: Display this help text\n"
@@ -240,19 +284,30 @@ int main() {
if (id != -1) {
std::cout << "> Created connection with id " << id << std::endl;
}
} else if (input.substr(0,4) == "send") {
std::stringstream ss(input);
std::string cmd;
int id;
std::string message;
ss >> cmd >> id;
std::getline(ss,message);
endpoint.send(id, message);
} else if (input.substr(0,5) == "close") {
std::stringstream ss(input);
std::string cmd;
int id;
int close_code = websocketpp::close::status::normal;
std::string reason = "";
std::string reason;
ss >> cmd >> id >> close_code;
std::getline(ss,reason);
endpoint.close(id, close_code, reason);
} else if (input.substr(0,4) == "show") {
} else if (input.substr(0,4) == "show") {
int id = atoi(input.substr(5).c_str());
connection_metadata::ptr metadata = endpoint.get_metadata(id);
@@ -267,4 +322,4 @@ int main() {
}
return 0;
}
}
+7 -3
View File
@@ -1,10 +1,12 @@
WebSocket++ (0.3.0-alpha4)
WebSocket++ (0.7.0)
==========================
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
Protocol. It allows integrating WebSocket client and server functionality into
C++ programs. It uses interchangeable network transport modules including one
based on C++ iostreams and one based on Boost Asio.
based on raw char buffers, one based on C++ iostreams, and one based on Asio
(either via Boost or standalone). End users can write additional transport
policies to support other networking or event libraries as needed.
Major Features
==============
@@ -13,7 +15,7 @@ Major Features
* Message/event based interface
* Supports secure WebSockets (TLS), IPv6, and explicit proxies.
* Flexible dependency management (C++11 Standard Library or Boost)
* Interchangeable network transport modules (iostream and Boost Asio)
* Interchangeable network transport modules (raw, iostream, Asio, or custom)
* Portable/cross platform (Posix/Windows, 32/64bit, Intel/ARM/PPC)
* Thread-safe
@@ -31,6 +33,8 @@ http://www.zaphoyd.com/websocketpp/manual/
**GitHub Repository**
https://github.com/zaphoyd/websocketpp/
GitHub pull requests should be submitted to the `develop` branch.
**Announcements Mailing List**
http://groups.google.com/group/websocketpp-announcements/
+9 -10
View File
@@ -16,24 +16,23 @@ Complete & Tested:
- open_handler
- close_handler
- echo_server & echo_server_tls
Implemented, needs more testing
- TLS support
- External io_service support
- TLS support
- exception/error handling
- Timeouts
- Subprotocol negotiation
- validate_handler
- Hybi 00/Hixie 76 legacy protocol support
- Outgoing Proxy Support
- socket_init_handler
- tls_init_handler
- tcp_init_handler
- exception/error handling
- Subprotocol negotiation
- Hybi 00/Hixie 76 legacy protocol support
Ongoing work
- Performance tuning
- Outgoing Proxy Support
- PowerPC support
- Visual Studio / Windows support
- Timeouts
- CMake build/install support
- validate_handler
- http_handler
Future feature roadmap
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (test_connection)
build_test (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
+332 -43
View File
@@ -30,6 +30,10 @@
#include "connection_tu2.hpp"
// Include special debugging transport
//#include <websocketpp/config/minimal_client.hpp>
#include <websocketpp/transport/debug/endpoint.hpp>
// NOTE: these tests currently test against hardcoded output values. I am not
// sure how problematic this will be. If issues arise like order of headers the
// output should be parsed by http::response and have values checked directly
@@ -37,9 +41,9 @@
BOOST_AUTO_TEST_CASE( basic_http_request ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 426 Upgrade Required\r\nServer: " +
std::string(websocketpp::user_agent)+"\r\n\r\n";
std::string(websocketpp::user_agent)+"\r\n\r\n";
std::string o2 = run_server_test(input);
std::string o2 = run_server_test(input);
BOOST_CHECK(o2 == output);
}
@@ -79,16 +83,67 @@ struct stub_config : public websocketpp::config::core {
typedef connection_extension connection_base;
};
struct debug_config_client : public websocketpp::config::core {
typedef debug_config_client type;
typedef core::concurrency_type concurrency_type;
typedef core::request_type request_type;
typedef core::response_type response_type;
typedef core::message_type message_type;
typedef core::con_msg_manager_type con_msg_manager_type;
typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
typedef core::alog_type alog_type;
typedef core::elog_type elog_type;
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
struct transport_config {
typedef type::concurrency_type concurrency_type;
typedef type::elog_type elog_type;
typedef type::alog_type alog_type;
typedef type::request_type request_type;
typedef type::response_type response_type;
/// Controls compile time enabling/disabling of thread syncronization
/// code Disabling can provide a minor performance improvement to single
/// threaded applications
static bool const enable_multithreading = true;
/// Default timer values (in ms)
static const long timeout_socket_pre_init = 5000;
static const long timeout_proxy = 5000;
static const long timeout_socket_post_init = 5000;
static const long timeout_connect = 5000;
static const long timeout_socket_shutdown = 5000;
};
/// Transport Endpoint Component
typedef websocketpp::transport::debug::endpoint<transport_config>
transport_type;
typedef core::endpoint_base endpoint_base;
typedef connection_extension connection_base;
static const websocketpp::log::level elog_level = websocketpp::log::elevel::none;
static const websocketpp::log::level alog_level = websocketpp::log::alevel::none;
};
struct connection_setup {
connection_setup(bool p_is_server) : c(p_is_server, "", alog, elog, rng) {}
websocketpp::lib::error_code ec;
stub_config::alog_type alog;
stub_config::alog_type alog;
stub_config::elog_type elog;
stub_config::rng_type rng;
websocketpp::connection<stub_config> c;
stub_config::rng_type rng;
websocketpp::connection<stub_config> c;
};
typedef websocketpp::client<debug_config_client> debug_client;
typedef websocketpp::server<debug_config_client> debug_server;
/*void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
s->send(hdl, msg->get_payload(), msg->get_opcode());
}*/
@@ -104,12 +159,49 @@ bool validate_set_ua(server* s, websocketpp::connection_hdl hdl) {
}
void http_func(server* s, websocketpp::connection_hdl hdl) {
using namespace websocketpp::http;
server::connection_ptr con = s->get_con_from_hdl(hdl);
std::string res = con->get_resource();
con->set_body(res);
con->set_status(websocketpp::http::status_code::ok);
con->set_status(status_code::ok);
BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok);
BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
}
void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
*deferred = true;
server::connection_ptr con = s->get_con_from_hdl(hdl);
websocketpp::lib::error_code ec = con->defer_http_response();
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
}
void check_on_fail(server* s, websocketpp::lib::error_code ec, bool & called,
websocketpp::connection_hdl hdl)
{
server::connection_ptr con = s->get_con_from_hdl(hdl);
BOOST_CHECK_EQUAL(ec, con->get_ec());
called = true;
}
void on_open_print(server* s, websocketpp::connection_hdl hdl)
{
server::connection_ptr con = s->get_con_from_hdl(hdl);
std::cout << con->get_uri() << std::endl;
}
void fail_on_open(websocketpp::connection_hdl) {
BOOST_CHECK(false);
}
void fail_on_http(websocketpp::connection_hdl) {
BOOST_CHECK(false);
}
BOOST_AUTO_TEST_CASE( connection_extensions ) {
@@ -127,8 +219,8 @@ BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
output+=websocketpp::user_agent;
output+="\r\nUpgrade: websocket\r\n\r\n";
server s;
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
server s;
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
BOOST_CHECK(run_server_test(s,input) == output);
}
@@ -139,19 +231,57 @@ BOOST_AUTO_TEST_CASE( http_request ) {
output+=websocketpp::user_agent;
output+="\r\n\r\n/foo/bar";
server s;
s.set_http_handler(bind(&http_func,&s,::_1));
server s;
s.set_http_handler(bind(&http_func,&s,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
BOOST_AUTO_TEST_CASE( deferred_http_request ) {
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
output+=websocketpp::user_agent;
output+="\r\n\r\n/foo/bar";
server s;
server::connection_ptr con;
bool deferred = false;
s.set_http_handler(bind(&defer_http_func,&s, &deferred,::_1));
s.clear_access_channels(websocketpp::log::alevel::all);
s.clear_error_channels(websocketpp::log::elevel::all);
std::stringstream ostream;
s.register_ostream(&ostream);
con = s.get_connection();
con->start();
BOOST_CHECK(!deferred);
BOOST_CHECK_EQUAL(ostream.str(), "");
con->read_some(input.data(),input.size());
BOOST_CHECK(deferred);
BOOST_CHECK_EQUAL(ostream.str(), "");
con->set_body(con->get_resource());
con->set_status(websocketpp::http::status_code::ok);
websocketpp::lib::error_code ec;
s.send_http_response(con->get_handle(),ec);
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
BOOST_CHECK_EQUAL(ostream.str(), output);
con->send_http_response(ec);
BOOST_CHECK_EQUAL(ec, make_error_code(websocketpp::error::invalid_state));
}
BOOST_AUTO_TEST_CASE( request_no_server_header ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nUpgrade: websocket\r\n\r\n";
server s;
s.set_user_agent("");
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
server s;
s.set_user_agent("");
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
@@ -160,10 +290,10 @@ BOOST_AUTO_TEST_CASE( request_no_server_header_override ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
server s;
s.set_user_agent("");
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
server s;
s.set_user_agent("");
s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
@@ -173,21 +303,21 @@ BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
//std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
std::string ref = "GET / HTTP/1.1\r\nConnection: Upgrade\r\nFoo: Bar\r\nHost: localhost\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\nSec-WebSocket-Version: 13\r\nUpgrade: websocket\r\nUser-Agent: foo\r\n\r\n";
std::string ref = "GET / HTTP/1.1\r\nConnection: Upgrade\r\nFoo: Bar\r\nHost: localhost\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\nSec-WebSocket-Version: 13\r\nUpgrade: websocket\r\nUser-Agent: foo\r\n\r\n";
std::stringstream output;
std::stringstream output;
client e;
e.set_access_channels(websocketpp::log::alevel::none);
client e;
e.set_access_channels(websocketpp::log::alevel::none);
e.set_error_channels(websocketpp::log::elevel::none);
e.set_user_agent("foo");
e.register_ostream(&output);
e.set_user_agent("foo");
e.register_ostream(&output);
client::connection_ptr con;
websocketpp::lib::error_code ec;
con = e.get_connection(uri, ec);
con->append_header("Foo","Bar");
e.connect(con);
client::connection_ptr con;
websocketpp::lib::error_code ec;
con = e.get_connection(uri, ec);
con->append_header("Foo","Bar");
e.connect(con);
BOOST_CHECK_EQUAL(ref, output.str());
}
@@ -207,35 +337,194 @@ BOOST_AUTO_TEST_CASE( set_max_message_size ) {
output.append(frame1, 4);
output.append("A message was too large");
server s;
s.set_user_agent("");
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
server s;
s.set_user_agent("");
s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
s.set_max_message_size(2);
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
BOOST_AUTO_TEST_CASE( websocket_fail_parse_error ) {
std::string input = "asdf\r\n\r\n";
server s;
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::http_parse_error);
bool called = false;
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
run_server_test(s,input,false);
BOOST_CHECK(called);
}
BOOST_AUTO_TEST_CASE( websocket_fail_invalid_version ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: foo\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
server s;
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::invalid_version);
bool called = false;
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
run_server_test(s,input,false);
BOOST_CHECK(called);
}
BOOST_AUTO_TEST_CASE( websocket_fail_unsupported_version ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 12\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
server s;
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
bool called = false;
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
run_server_test(s,input,false);
BOOST_CHECK(called);
}
// BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri ) {
// std::string input = "GET http://345.123.123.123/foo HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
// server s;
// websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
// bool called = false;
// s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
// s.set_open_handler(bind(&on_open_print,&s,::_1));
// std::cout << run_server_test(s,input,true) << std::endl;
// BOOST_CHECK(called);
// }
// BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri_http ) {
// std::string input = "GET http://345.123.123.123/foo HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
// server s;
// websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
// bool called = false;
// s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
// s.set_open_handler(bind(&on_open_print,&s,::_1));
// std::cout << run_server_test(s,input,true) << std::endl;
// BOOST_CHECK(called);
// }
BOOST_AUTO_TEST_CASE( websocket_fail_upgrade_required ) {
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
server s;
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::upgrade_required);
bool called = false;
s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
run_server_test(s,input,false);
BOOST_CHECK(called);
}
// TODO: set max message size in client endpoint test case
// TODO: set max message size mid connection test case
// TODO: [maybe] set max message size in open handler
/*
BOOST_AUTO_TEST_CASE( user_reject_origin ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n";
std::string output = "HTTP/1.1 403 Forbidden\r\nServer: "+websocketpp::USER_AGENT+"\r\n\r\n";
BOOST_CHECK(run_server_test(input) == output);
// BOOST_AUTO_TEST_CASE( user_reject_origin ) {
// std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n";
// std::string output = "HTTP/1.1 403 Forbidden\r\nServer: "+websocketpp::USER_AGENT+"\r\n\r\n";
// BOOST_CHECK(run_server_test(input) == output);
// }
// BOOST_AUTO_TEST_CASE( basic_text_message ) {
// std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
// unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
// input.append(reinterpret_cast<char*>(frames),8);
// std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: "+websocketpp::USER_AGENT+"\r\nUpgrade: websocket\r\n\r\n**";
// BOOST_CHECK( run_server_test(input) == output);
// }
BOOST_AUTO_TEST_CASE( client_handshake_timeout_race1 ) {
debug_client c;
websocketpp::lib::error_code ec;
debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
BOOST_CHECK(!ec);
// This test the case where a handshake times out immediately before the
// handler that would have completed it gets invoked. This situation happens
// when clients are connecting to overloaded servers and on servers that are
// overloaded.
c.connect(con);
con->expire_timer(websocketpp::lib::error_code());
// Fullfil the write to simulate the write completing immediately after
// timer expires
con->fullfil_write();
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
}
BOOST_AUTO_TEST_CASE( basic_text_message ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
debug_client c;
unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
input.append(reinterpret_cast<char*>(frames),8);
websocketpp::lib::error_code ec;
debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: "+websocketpp::USER_AGENT+"\r\nUpgrade: websocket\r\n\r\n**";
BOOST_CHECK(!ec);
BOOST_CHECK( run_server_test(input) == output);
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: ICX+Yqv66kxgM0FcWaLWlFLwTAI=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
// This test the case where a handshake times out immediately before the
// handler that would have completed it gets invoked. This situation happens
// when clients are connecting to overloaded servers and on servers that are
// overloaded.
c.connect(con);
con->fullfil_write();
con->expire_timer(websocketpp::lib::error_code());
// Read valid handshake to simulate receiving the handshake response
// immediately after the timer expires
con->read_all(output.data(),output.size());
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
}
*/
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
debug_server s;
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
debug_server::connection_ptr con = s.get_connection();
con->start();
con->expire_timer(websocketpp::lib::error_code());
// Read handshake immediately after timer expire
con->read_all(input.data(), input.size());
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
}
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race2 ) {
debug_server s;
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
debug_server::connection_ptr con = s.get_connection();
con->start();
con->read_all(input.data(), input.size());
con->expire_timer(websocketpp::lib::error_code());
// Complete write immediately after timer expire
con->fullfil_write();
BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
}
+18 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -31,27 +31,32 @@ void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
s->send(hdl, msg->get_payload(), msg->get_opcode());
}
std::string run_server_test(std::string input) {
std::string run_server_test(std::string input, bool log) {
server test_server;
return run_server_test(test_server,input);
return run_server_test(test_server,input,log);
}
std::string run_server_test(server & s, std::string input) {
std::string run_server_test(server & s, std::string input, bool log) {
server::connection_ptr con;
std::stringstream output;
s.clear_access_channels(websocketpp::log::alevel::all);
s.clear_error_channels(websocketpp::log::elevel::all);
if (log) {
s.set_access_channels(websocketpp::log::alevel::all);
s.set_error_channels(websocketpp::log::elevel::all);
} else {
s.clear_access_channels(websocketpp::log::alevel::all);
s.clear_error_channels(websocketpp::log::elevel::all);
}
s.register_ostream(&output);
s.register_ostream(&output);
con = s.get_connection();
con->start();
con = s.get_connection();
con->start();
std::stringstream channel;
std::stringstream channel;
channel << input;
channel >> *con;
channel << input;
channel >> *con;
return output.str();
return output.str();
}
+4 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -30,6 +30,7 @@
// Test Environment:
// server, no TLS, no locks, iostream based transport
#include <websocketpp/config/debug.hpp>
#include <websocketpp/config/core.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/client.hpp>
@@ -46,5 +47,5 @@ using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg);
std::string run_server_test(std::string input);
std::string run_server_test(server & s, std::string input);
std::string run_server_test(std::string input, bool log = false);
std::string run_server_test(server & s, std::string input, bool log = false);
+17
View File
@@ -0,0 +1,17 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (OPENSSL_FOUND)
init_target (test_endpoint)
build_test (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_openssl ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
endif()
+58 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2015, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -57,6 +57,35 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) {
s.init_asio(&ios);
}
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
BOOST_AUTO_TEST_CASE( move_construct_server_core ) {
websocketpp::server<websocketpp::config::core> s1;
websocketpp::server<websocketpp::config::core> s2(std::move(s1));
}
/*
// temporary disable because library doesn't pass
BOOST_AUTO_TEST_CASE( emplace ) {
std::stringstream out1;
std::stringstream out2;
std::vector<websocketpp::server<websocketpp::config::asio_tls>> v;
v.emplace_back();
v.emplace_back();
v[0].get_alog().set_ostream(&out1);
v[0].get_alog().set_ostream(&out2);
v[0].get_alog().write(websocketpp::log::alevel::app,"devel0");
v[1].get_alog().write(websocketpp::log::alevel::app,"devel1");
BOOST_CHECK( out1.str().size() > 0 );
BOOST_CHECK( out2.str().size() > 0 );
}*/
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
struct endpoint_extension {
endpoint_extension() : extension_value(5) {}
@@ -94,8 +123,33 @@ struct stub_config : public websocketpp::config::core {
BOOST_AUTO_TEST_CASE( endpoint_extensions ) {
websocketpp::server<stub_config> s;
BOOST_CHECK( s.extension_value == 5 );
BOOST_CHECK( s.extension_method() == 5 );
BOOST_CHECK_EQUAL( s.extension_value, 5 );
BOOST_CHECK_EQUAL( s.extension_method(), 5 );
BOOST_CHECK( s.is_server() == true );
BOOST_CHECK( s.is_server() );
}
BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) {
using websocketpp::transport::asio::error::make_error_code;
using websocketpp::transport::asio::error::pass_through;
websocketpp::server<websocketpp::config::asio> server1;
websocketpp::server<websocketpp::config::asio> server2;
websocketpp::lib::error_code ec;
server1.init_asio();
server2.init_asio();
boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456);
server1.listen(ep1, ec);
BOOST_CHECK(!ec);
server2.listen(ep1, ec);
BOOST_REQUIRE_EQUAL(ec, make_error_code(pass_through));
server2.listen(ep2, ec);
BOOST_CHECK(!ec);
}
+22
View File
@@ -0,0 +1,22 @@
# Extension Tests
file (GLOB SOURCE extension.cpp)
init_target (test_extension)
build_executable (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
if ( ZLIB_FOUND )
# Permessage-deflate tests
file (GLOB SOURCE permessage_deflate.cpp)
init_target (test_permessage_deflate)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
link_zlib()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
endif ( ZLIB_FOUND )
+237 -131
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Peter Thorson. All rights reserved.
* Copyright (c) 2013, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -100,10 +100,10 @@ BOOST_AUTO_TEST_CASE( negotiation_invalid_attr ) {
BOOST_CHECK_EQUAL( v.esp.second, "");
}
// Negotiate s2c_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_invalid ) {
// Negotiate server_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_server_no_context_takeover_invalid ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "foo";
v.attr["server_no_context_takeover"] = "foo";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
@@ -111,30 +111,30 @@ BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_invalid ) {
BOOST_CHECK_EQUAL( v.esp.second, "");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover ) {
BOOST_AUTO_TEST_CASE( negotiate_server_no_context_takeover ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["server_no_context_takeover"].clear();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_server_initiated ) {
BOOST_AUTO_TEST_CASE( negotiate_server_no_context_takeover_server_initiated ) {
ext_vars v;
v.exts.enable_s2c_no_context_takeover();
v.exts.enable_server_no_context_takeover();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover");
}
// Negotiate c2s_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_invalid ) {
// Negotiate client_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_client_no_context_takeover_invalid ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "foo";
v.attr["client_no_context_takeover"] = "foo";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
@@ -142,29 +142,29 @@ BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_invalid ) {
BOOST_CHECK_EQUAL( v.esp.second, "");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover ) {
BOOST_AUTO_TEST_CASE( negotiate_client_no_context_takeover ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["client_no_context_takeover"].clear();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_no_context_takeover");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_server_initiated ) {
BOOST_AUTO_TEST_CASE( negotiate_client_no_context_takeover_server_initiated ) {
ext_vars v;
v.exts.enable_c2s_no_context_takeover();
v.exts.enable_client_no_context_takeover();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_no_context_takeover");
}
// Negotiate s2c_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_invalid ) {
// Negotiate server_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_invalid ) {
ext_vars v;
std::vector<std::string> values;
@@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_invalid ) {
std::vector<std::string>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
v.attr["s2c_max_window_bits"] = *it;
v.attr["server_max_window_bits"] = *it;
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
@@ -184,16 +184,16 @@ BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_invalid ) {
}
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_valid ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_valid ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "8";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=8");
v.attr["s2c_max_window_bits"] = "15";
v.attr["server_max_window_bits"] = "15";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
@@ -201,21 +201,21 @@ BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_valid ) {
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( invalid_set_s2c_max_window_bits ) {
BOOST_AUTO_TEST_CASE( invalid_set_server_max_window_bits ) {
ext_vars v;
v.ec = v.exts.set_s2c_max_window_bits(7,pmd_mode::decline);
v.ec = v.exts.set_server_max_window_bits(7,pmd_mode::decline);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
v.ec = v.exts.set_s2c_max_window_bits(16,pmd_mode::decline);
v.ec = v.exts.set_server_max_window_bits(16,pmd_mode::decline);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_decline ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_decline ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::decline);
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::decline);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -223,44 +223,44 @@ BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_decline ) {
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_accept ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_accept ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::accept);
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::accept);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=8");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_largest ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_largest ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::largest);
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::largest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=8");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_smallest ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_smallest ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_max_window_bits(15,pmd_mode::smallest);
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::smallest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=8");
}
// Negotiate s2c_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_invalid ) {
// Negotiate server_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_invalid ) {
ext_vars v;
std::vector<std::string> values;
@@ -270,7 +270,7 @@ BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_invalid ) {
std::vector<std::string>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
v.attr["c2s_max_window_bits"] = *it;
v.attr["client_max_window_bits"] = *it;
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
@@ -279,43 +279,43 @@ BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_invalid ) {
}
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_valid ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_valid ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "";
v.attr["client_max_window_bits"].clear();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
v.attr["c2s_max_window_bits"] = "8";
v.attr["client_max_window_bits"] = "8";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=8");
v.attr["c2s_max_window_bits"] = "15";
v.attr["client_max_window_bits"] = "15";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( invalid_set_c2s_max_window_bits ) {
BOOST_AUTO_TEST_CASE( invalid_set_client_max_window_bits ) {
ext_vars v;
v.ec = v.exts.set_c2s_max_window_bits(7,pmd_mode::decline);
v.ec = v.exts.set_client_max_window_bits(7,pmd_mode::decline);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
v.ec = v.exts.set_c2s_max_window_bits(16,pmd_mode::decline);
v.ec = v.exts.set_client_max_window_bits(16,pmd_mode::decline);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_decline ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_decline ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.attr["client_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_max_window_bits(8,pmd_mode::decline);
v.ec = v.exts.set_client_max_window_bits(8,pmd_mode::decline);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -323,40 +323,40 @@ BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_decline ) {
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_accept ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_accept ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.attr["client_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::accept);
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::accept);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=8");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_largest ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_largest ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.attr["client_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::largest);
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::largest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=8");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_smallest ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_smallest ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.attr["client_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_max_window_bits(15,pmd_mode::smallest);
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::smallest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=8");
}
@@ -364,180 +364,286 @@ BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_smallest ) {
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated1 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_no_context_takeover"] = "";
v.attr["server_no_context_takeover"].clear();
v.attr["client_no_context_takeover"].clear();
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; client_no_context_takeover");
}
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated2 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; s2c_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; server_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated3 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated4 ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["client_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; s2c_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_no_context_takeover; server_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated5 ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["c2s_max_window_bits"] = "10";
v.attr["client_no_context_takeover"].clear();
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_no_context_takeover; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated6 ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "10";
v.attr["c2s_max_window_bits"] = "10";
v.attr["server_max_window_bits"] = "10";
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_max_window_bits=10; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=10; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated1 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["client_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; s2c_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; client_no_context_takeover; server_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated2 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_no_context_takeover"] = "";
v.attr["c2s_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["client_no_context_takeover"].clear();
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; client_no_context_takeover; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated3 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["c2s_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; server_max_window_bits=10; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_three_client_initiated4 ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["c2s_max_window_bits"] = "10";
v.attr["client_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; c2s_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_no_context_takeover; server_max_window_bits=10; client_max_window_bits=10");
}
BOOST_AUTO_TEST_CASE( negotiate_four_client_initiated ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_no_context_takeover"] = "";
v.attr["s2c_max_window_bits"] = "10";
v.attr["c2s_max_window_bits"] = "10";
v.attr["server_no_context_takeover"].clear();
v.attr["client_no_context_takeover"].clear();
v.attr["server_max_window_bits"] = "10";
v.attr["client_max_window_bits"] = "10";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; s2c_no_context_takeover; c2s_no_context_takeover; s2c_max_window_bits=10; c2s_max_window_bits=10");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_no_context_takeover; client_no_context_takeover; server_max_window_bits=10; client_max_window_bits=10");
}
// Compression
/*
BOOST_AUTO_TEST_CASE( compress_data ) {
ext_vars v;
std::string in = "Hello";
std::string out;
std::string in2;
std::string out2;
std::string compress_in = "Hello";
std::string compress_out;
std::string decompress_out;
v.exts.init();
v.exts.init(true);
v.ec = v.exts.compress(in,out);
std::cout << "in : " << websocketpp::utility::to_hex(in) << std::endl;
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
std::cout << "out: " << websocketpp::utility::to_hex(out) << std::endl;
in2 = out;
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(in2.data()),in2.size(),out2);
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(compress_out.data()),compress_out.size(),decompress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
std::cout << "out: " << websocketpp::utility::to_hex(out2) << std::endl;
BOOST_CHECK_EQUAL( out, out2 );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
}
BOOST_AUTO_TEST_CASE( compress_data_multiple ) {
ext_vars v;
v.exts.init(true);
for (int i = 0; i < 2; i++) {
std::string compress_in = "Hello";
std::string compress_out;
std::string decompress_out;
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(compress_out.data()),compress_out.size(),decompress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
}
}
BOOST_AUTO_TEST_CASE( compress_data_large ) {
ext_vars v;
std::string compress_in(600,'*');
std::string compress_out;
std::string decompress_out;
websocketpp::http::attribute_list alist;
alist["server_max_window_bits"] = "8";
v.exts.set_server_max_window_bits(8,websocketpp::extensions::permessage_deflate::mode::smallest);
v.exts.negotiate(alist);
v.exts.init(true);
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(compress_out.data()),compress_out.size(),decompress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
}
BOOST_AUTO_TEST_CASE( compress_data_no_context_takeover ) {
ext_vars v;
std::string compress_in = "Hello";
std::string compress_out1;
std::string compress_out2;
std::string decompress_out;
websocketpp::http::attribute_list alist;
alist["server_no_context_takeover"].clear();
v.exts.enable_server_no_context_takeover();
v.exts.negotiate(alist);
v.exts.init(true);
v.ec = v.exts.compress(compress_in,compress_out1);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(
reinterpret_cast<const uint8_t *>(compress_out1.data()),
compress_out1.size(),
decompress_out
);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
decompress_out.clear();
v.ec = v.exts.compress(compress_in,compress_out2);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(
reinterpret_cast<const uint8_t *>(compress_out2.data()),
compress_out2.size(),
decompress_out
);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
BOOST_CHECK_EQUAL( compress_out1, compress_out2 );
}
BOOST_AUTO_TEST_CASE( compress_empty ) {
ext_vars v;
std::string compress_in;
std::string compress_out;
std::string decompress_out;
v.exts.init(true);
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(compress_out.data()),compress_out.size(),decompress_out);
compress_out.clear();
decompress_out.clear();
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(reinterpret_cast<const uint8_t *>(compress_out.data()),compress_out.size(),decompress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( compress_in, decompress_out );
}
/// @todo: more compression tests
/**
* - compress at different compression levels
*/
// Decompression
BOOST_AUTO_TEST_CASE( decompress_data ) {
ext_vars v;
uint8_t in[12] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00, 0x00, 0x00, 0xff, 0xff};
uint8_t in[11] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00, 0x00, 0x00, 0xff, 0xff};
std::string out;
std::string reference = "Hello";
v.exts.init();
v.exts.init(true);
v.ec = v.exts.decompress(in,12,out);
v.ec = v.exts.decompress(in,11,out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
std::cout << "out: " << websocketpp::utility::to_hex(out) << std::endl;
BOOST_CHECK( false );
BOOST_CHECK_EQUAL( out, reference );
}
*/
+11
View File
@@ -0,0 +1,11 @@
file (GLOB SOURCE_FILES parser.cpp)
init_target (test_http)
build_test (${TARGET_NAME} ${SOURCE_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
+234 -73
View File
@@ -28,6 +28,7 @@
#define BOOST_TEST_MODULE http_parser
#include <boost/test/unit_test.hpp>
#include <iostream>
#include <string>
#include <websocketpp/http/request.hpp>
@@ -54,24 +55,24 @@ BOOST_AUTO_TEST_CASE( is_token_char ) {
// numbers
for (int i = 0x30; i < 0x3a; i++) {
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
}
// upper
for (int i = 0x41; i < 0x5b; i++) {
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
}
// lower
for (int i = 0x61; i < 0x7b; i++) {
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
}
// invalid characters
// lower unprintable
for (int i = 0; i < 33; i++) {
BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
}
// misc
@@ -95,7 +96,7 @@ BOOST_AUTO_TEST_CASE( is_token_char ) {
// upper unprintable and out of ascii range
for (int i = 127; i < 256; i++) {
BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
}
// is not
@@ -114,7 +115,7 @@ BOOST_AUTO_TEST_CASE( extract_token ) {
BOOST_CHECK( ret.second == d1.begin()+3 );
ret = websocketpp::http::parser::extract_token(d2.begin(),d2.end());
BOOST_CHECK( ret.first == "" );
BOOST_CHECK( ret.first.empty() );
BOOST_CHECK( ret.second == d2.begin()+0 );
ret = websocketpp::http::parser::extract_token(d2.begin()+1,d2.end());
@@ -126,7 +127,7 @@ BOOST_AUTO_TEST_CASE( extract_quoted_string ) {
std::string d1 = "\"foo\"";
std::string d2 = "\"foo\\\"bar\\\"baz\"";
std::string d3 = "\"foo\" ";
std::string d4 = "";
std::string d4;
std::string d5 = "foo";
std::pair<std::string,std::string::const_iterator> ret;
@@ -146,11 +147,11 @@ BOOST_AUTO_TEST_CASE( extract_quoted_string ) {
BOOST_CHECK( ret.second == d3.begin()+5 );
ret = extract_quoted_string(d4.begin(),d4.end());
BOOST_CHECK( ret.first == "" );
BOOST_CHECK( ret.first.empty() );
BOOST_CHECK( ret.second == d4.begin() );
ret = extract_quoted_string(d5.begin(),d5.end());
BOOST_CHECK( ret.first == "" );
BOOST_CHECK( ret.first.empty() );
BOOST_CHECK( ret.second == d5.begin() );
}
@@ -184,7 +185,7 @@ BOOST_AUTO_TEST_CASE( extract_all_lws ) {
}
BOOST_AUTO_TEST_CASE( extract_attributes_blank ) {
std::string s = "";
std::string s;
websocketpp::http::attribute_list a;
std::string::const_iterator it;
@@ -208,7 +209,7 @@ BOOST_AUTO_TEST_CASE( extract_attributes_simple ) {
}
BOOST_AUTO_TEST_CASE( extract_parameters ) {
std::string s1 = "";
std::string s1;
std::string s2 = "foo";
std::string s3 = " foo \r\nAbc";
std::string s4 = " \r\n foo ";
@@ -364,6 +365,7 @@ BOOST_AUTO_TEST_CASE( strip_lws ) {
std::string test6 = " \r\n foo ";
std::string test7 = " \t foo ";
std::string test8 = " \t ";
std::string test9 = " \n\r";
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test1), "foo" );
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test2), "foo" );
@@ -373,6 +375,7 @@ BOOST_AUTO_TEST_CASE( strip_lws ) {
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test6), "foo" );
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test7), "foo" );
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test8), "" );
BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test9), "" );
}
BOOST_AUTO_TEST_CASE( case_insensitive_headers ) {
@@ -407,14 +410,14 @@ BOOST_AUTO_TEST_CASE( case_insensitive_headers_overwrite ) {
BOOST_AUTO_TEST_CASE( blank_consume ) {
websocketpp::http::parser::request r;
std::string raw = "";
std::string raw;
bool exception = false;
try {
r.consume(raw.c_str(),raw.size());
r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -429,9 +432,9 @@ BOOST_AUTO_TEST_CASE( blank_request ) {
bool exception = false;
try {
r.consume(raw.c_str(),raw.size());
r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == true );
@@ -446,9 +449,9 @@ BOOST_AUTO_TEST_CASE( bad_request_no_host ) {
bool exception = false;
try {
r.consume(raw.c_str(),raw.size());
r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == true );
@@ -464,10 +467,10 @@ BOOST_AUTO_TEST_CASE( basic_request ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -479,6 +482,62 @@ BOOST_AUTO_TEST_CASE( basic_request ) {
BOOST_CHECK( r.get_header("Host") == "www.example.com" );
}
BOOST_AUTO_TEST_CASE( basic_request_with_body ) {
websocketpp::http::parser::request r;
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 5\r\n\r\nabcdef";
bool exception = false;
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 65 );
BOOST_CHECK( r.ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_method(), "GET" );
BOOST_CHECK_EQUAL( r.get_uri(), "/" );
BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
BOOST_CHECK_EQUAL( r.get_header("Content-Length"), "5" );
BOOST_CHECK_EQUAL( r.get_body(), "abcde" );
}
BOOST_AUTO_TEST_CASE( basic_request_with_body_split ) {
websocketpp::http::parser::request r;
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabc";
std::string raw2 = "def";
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 66 );
BOOST_CHECK( r.ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_method(), "GET" );
BOOST_CHECK_EQUAL( r.get_uri(), "/" );
BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
BOOST_CHECK_EQUAL( r.get_header("Content-Length"), "6" );
BOOST_CHECK_EQUAL( r.get_body(), "abcdef" );
}
BOOST_AUTO_TEST_CASE( trailing_body_characters ) {
websocketpp::http::parser::request r;
@@ -488,9 +547,33 @@ BOOST_AUTO_TEST_CASE( trailing_body_characters ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
BOOST_CHECK( pos == 41 );
BOOST_CHECK( r.ready() == true );
BOOST_CHECK( r.get_version() == "HTTP/1.1" );
BOOST_CHECK( r.get_method() == "GET" );
BOOST_CHECK( r.get_uri() == "/" );
BOOST_CHECK( r.get_header("Host") == "www.example.com" );
}
BOOST_AUTO_TEST_CASE( trailing_body_characters_beyond_max_lenth ) {
websocketpp::http::parser::request r;
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
raw.append(websocketpp::http::max_header_size,'*');
bool exception = false;
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
}
BOOST_CHECK( exception == false );
@@ -512,11 +595,11 @@ BOOST_AUTO_TEST_CASE( basic_split1 ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -538,11 +621,11 @@ BOOST_AUTO_TEST_CASE( basic_split2 ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -557,17 +640,18 @@ BOOST_AUTO_TEST_CASE( basic_split2 ) {
BOOST_AUTO_TEST_CASE( max_header_len ) {
websocketpp::http::parser::request r;
std::string raw(websocketpp::http::max_header_size+1,'*');
std::string raw(websocketpp::http::max_header_size-1,'*');
raw += "\r\n";
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw.c_str(),raw.size());
} catch (const websocketpp::http::exception& e) {
if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
exception = true;
}
if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
exception = true;
}
}
BOOST_CHECK( exception == true );
@@ -583,17 +667,38 @@ BOOST_AUTO_TEST_CASE( max_header_len_split ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw2.c_str(),raw2.size());
} catch (const websocketpp::http::exception& e) {
if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
exception = true;
}
if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
exception = true;
}
}
BOOST_CHECK( exception == true );
}
BOOST_AUTO_TEST_CASE( max_body_len ) {
websocketpp::http::parser::request r;
r.set_max_body_size(5);
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabcdef";
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
} catch (websocketpp::http::exception const & e) {
exception = true;
BOOST_CHECK_EQUAL(e.m_error_code,websocketpp::http::status_code::request_entity_too_large);
}
BOOST_CHECK_EQUAL(r.get_max_body_size(),5);
BOOST_CHECK( exception == true );
}
BOOST_AUTO_TEST_CASE( firefox_full_request ) {
websocketpp::http::parser::request r;
@@ -603,9 +708,9 @@ BOOST_AUTO_TEST_CASE( firefox_full_request ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -636,9 +741,9 @@ BOOST_AUTO_TEST_CASE( bad_method ) {
bool exception = false;
try {
r.consume(raw.c_str(),raw.size());
r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == true );
@@ -652,9 +757,9 @@ BOOST_AUTO_TEST_CASE( bad_header_name ) {
bool exception = false;
try {
r.consume(raw.c_str(),raw.size());
r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == true );
@@ -669,9 +774,9 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -692,9 +797,9 @@ BOOST_AUTO_TEST_CASE( new_http_version1 ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -715,9 +820,9 @@ BOOST_AUTO_TEST_CASE( new_http_version2 ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -740,9 +845,9 @@ BOOST_AUTO_TEST_CASE( new_http_version3 ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == true );
@@ -757,9 +862,9 @@ BOOST_AUTO_TEST_CASE( header_whitespace1 ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -780,9 +885,9 @@ BOOST_AUTO_TEST_CASE( header_whitespace2 ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -803,9 +908,9 @@ BOOST_AUTO_TEST_CASE( header_aggregation ) {
size_t pos = 0;
try {
pos = r.consume(raw.c_str(),raw.size());
pos = r.consume(raw.c_str(),raw.size());
} catch (...) {
exception = true;
exception = true;
}
BOOST_CHECK( exception == false );
@@ -826,10 +931,66 @@ BOOST_AUTO_TEST_CASE( wikipedia_example_response ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 159 );
BOOST_CHECK( r.headers_ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
}
BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing ) {
websocketpp::http::parser::response r;
std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
raw += "a";
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
BOOST_CHECK_EQUAL( pos, 159 );
BOOST_CHECK( r.headers_ready() == true );
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
}
BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing_large ) {
websocketpp::http::parser::response r;
std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
raw.append(websocketpp::http::max_header_size,'*');
bool exception = false;
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -853,10 +1014,10 @@ BOOST_AUTO_TEST_CASE( response_with_non_standard_lws ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -880,10 +1041,10 @@ BOOST_AUTO_TEST_CASE( plain_http_response ) {
size_t pos = 0;
try {
pos += r.consume(raw.c_str(),raw.size());
pos += r.consume(raw.c_str(),raw.size());
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK( exception == false );
@@ -915,10 +1076,10 @@ BOOST_AUTO_TEST_CASE( parse_istream ) {
size_t pos = 0;
try {
pos += r.consume(s);
pos += r.consume(s);
} catch (std::exception &e) {
exception = true;
std::cout << e.what() << std::endl;
exception = true;
std::cout << e.what() << std::endl;
}
BOOST_CHECK_EQUAL( exception, false );
+79 -79
View File
@@ -31,111 +31,111 @@
class scoped_timer {
public:
scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) {
std::cout << "Clock " << i << ": ";
}
~scoped_timer() {
std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start;
scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) {
std::cout << "Clock " << i << ": ";
}
~scoped_timer() {
std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start;
//nanoseconds_per_test
//nanoseconds_per_test
//tests_per_second
//tests_per_second
//1000000000.0/(double(time_taken.count())/1000.0)
//1000000000.0/(double(time_taken.count())/1000.0)
std::cout << 1000000000.0/(double(time_taken.count())/1000.0) << std::endl;
std::cout << 1000000000.0/(double(time_taken.count())/1000.0) << std::endl;
//std::cout << (1.0/double(time_taken.count())) * double(1000000000*1000) << std::endl;
}
//std::cout << (1.0/double(time_taken.count())) * double(1000000000*1000) << std::endl;
}
private:
std::string m_id;
std::chrono::steady_clock::time_point m_start;
std::string m_id;
std::chrono::steady_clock::time_point m_start;
};
int main() {
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
std::string firefox = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
std::string firefox = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
std::string firefox1 = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\n";
std::string firefox1 = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\n";
std::string firefox2 = "Accept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
std::string firefox2 = "Accept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
{
scoped_timer timer("Simplest 1 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
{
scoped_timer timer("Simplest 1 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
try {
r.consume(raw.c_str(),raw.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
try {
r.consume(raw.c_str(),raw.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
{
scoped_timer timer("FireFox, 1 chop, consume old");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
{
scoped_timer timer("FireFox, 1 chop, consume old");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
try {
r.consume2(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
try {
r.consume2(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
{
scoped_timer timer("FireFox, 1 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
{
scoped_timer timer("FireFox, 1 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
try {
r.consume(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
try {
r.consume(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
{
scoped_timer timer("FireFox, 2 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
{
scoped_timer timer("FireFox, 2 chop");
for (int i = 0; i < 1000; i++) {
websocketpp::http::parser::request r;
try {
r.consume(firefox1.c_str(),firefox1.size());
r.consume(firefox2.c_str(),firefox2.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
try {
r.consume(firefox1.c_str(),firefox1.size());
r.consume(firefox2.c_str(),firefox2.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
if (!r.ready()) {
std::cout << "error" << std::endl;
break;
}
}
}
return 0;
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (test_logger)
build_test (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
+65 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -34,6 +34,8 @@
#include <websocketpp/concurrency/none.hpp>
#include <websocketpp/concurrency/basic.hpp>
typedef websocketpp::log::basic<websocketpp::concurrency::basic,websocketpp::log::alevel> basic_access_log_type;
BOOST_AUTO_TEST_CASE( is_token_char ) {
typedef websocketpp::log::basic<websocketpp::concurrency::none,websocketpp::log::elevel> error_log;
@@ -79,3 +81,65 @@ BOOST_AUTO_TEST_CASE( basic_concurrency ) {
//std::cout << "|" << out.str() << "|" << std::endl;
BOOST_CHECK( out.str().size() > 0 );
}
BOOST_AUTO_TEST_CASE( copy_constructor ) {
std::stringstream out;
basic_access_log_type logger1(0xffffffff,&out);
basic_access_log_type logger2(logger1);
logger2.set_channels(0xffffffff);
logger2.write(websocketpp::log::alevel::devel,"devel");
BOOST_CHECK( out.str().size() > 0 );
}
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
BOOST_AUTO_TEST_CASE( move_constructor ) {
std::stringstream out;
basic_access_log_type logger1(0xffffffff,&out);
basic_access_log_type logger2(std::move(logger1));
logger2.set_channels(0xffffffff);
logger2.write(websocketpp::log::alevel::devel,"devel");
BOOST_CHECK( out.str().size() > 0 );
}
// Emplace requires move assignment, which logger doesn't support right now
// due to const members. This is pretty irritating and will probably result in
// the const members being removed. For now though this test will fail to
// compile
/*BOOST_AUTO_TEST_CASE( emplace ) {
std::stringstream out1;
std::stringstream out2;
std::vector<basic_access_log_type> v;
v.emplace_back(websocketpp::log::level(0xffffffff),&out1);
v.emplace_back(websocketpp::log::level(0xffffffff),&out2);
v[0].set_channels(0xffffffff);
v[1].set_channels(0xffffffff);
v[0].write(websocketpp::log::alevel::devel,"devel");
v[1].write(websocketpp::log::alevel::devel,"devel");
BOOST_CHECK( out1.str().size() > 0 );
BOOST_CHECK( out2.str().size() > 0 );
}*/
#endif // #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
// As long as there are const member variables these can't exist
// These remain commented as they are useful for testing the deleted operators
/*BOOST_AUTO_TEST_CASE( copy_assign ) {
basic_access_log_type logger1;
basic_access_log_type logger2;
logger2 = logger1;
}
BOOST_AUTO_TEST_CASE( move_assign ) {
basic_access_log_type logger1;
basic_access_log_type logger2;
logger2 = std::move(logger1);
}*/
+17
View File
@@ -0,0 +1,17 @@
# Test alloc message buffer strategy
file (GLOB SOURCE alloc.cpp)
init_target (test_message_alloc)
build_executable (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
# Test message buffers
file (GLOB SOURCE message.cpp)
init_target (test_message_buffer)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
+43 -43
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -35,62 +35,62 @@
template <template <class> class con_msg_manager>
struct stub {
typedef websocketpp::lib::shared_ptr<stub> ptr;
typedef websocketpp::lib::shared_ptr<stub> ptr;
typedef con_msg_manager<stub> con_msg_man_type;
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
typedef con_msg_manager<stub> con_msg_man_type;
typedef typename con_msg_man_type::ptr con_msg_man_ptr;
typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr;
stub(con_msg_man_ptr manager, websocketpp::frame::opcode::value op, size_t size = 128)
: m_opcode(op)
, m_manager(manager)
, m_size(size) {}
stub(con_msg_man_ptr manager, websocketpp::frame::opcode::value op, size_t size = 128)
: m_opcode(op)
, m_manager(manager)
, m_size(size) {}
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
if (shared) {
return shared->recycle(this);
} else {
return false;
}
}
if (shared) {
return shared->recycle(this);
} else {
return false;
}
}
websocketpp::frame::opcode::value m_opcode;
con_msg_man_weak_ptr m_manager;
size_t m_size;
websocketpp::frame::opcode::value m_opcode;
con_msg_man_weak_ptr m_manager;
size_t m_size;
};
BOOST_AUTO_TEST_CASE( basic_get_message ) {
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
con_msg_man_type::ptr manager(new con_msg_man_type());
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
con_msg_man_type::ptr manager(new con_msg_man_type());
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
BOOST_CHECK(msg);
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
BOOST_CHECK(msg->m_manager.lock() == manager);
BOOST_CHECK(msg->m_size == 512);
BOOST_CHECK(msg);
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
BOOST_CHECK(msg->m_manager.lock() == manager);
BOOST_CHECK(msg->m_size == 512);
}
BOOST_AUTO_TEST_CASE( basic_get_manager ) {
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
typedef websocketpp::message_buffer::alloc::endpoint_msg_manager
<con_msg_man_type> endpoint_manager_type;
typedef stub<websocketpp::message_buffer::alloc::con_msg_manager>
message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_man_type;
typedef websocketpp::message_buffer::alloc::endpoint_msg_manager
<con_msg_man_type> endpoint_manager_type;
endpoint_manager_type em;
con_msg_man_type::ptr manager = em.get_manager();
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
endpoint_manager_type em;
con_msg_man_type::ptr manager = em.get_manager();
message_type::ptr msg = manager->get_message(websocketpp::frame::opcode::TEXT,512);
BOOST_CHECK(msg);
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
BOOST_CHECK(msg->m_manager.lock() == manager);
BOOST_CHECK(msg->m_size == 512);
BOOST_CHECK(msg);
BOOST_CHECK(msg->m_opcode == websocketpp::frame::opcode::TEXT);
BOOST_CHECK(msg->m_manager.lock() == manager);
BOOST_CHECK(msg->m_size == 512);
}
+21 -21
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -35,38 +35,38 @@
template <typename message>
struct stub {
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
typedef websocketpp::lib::shared_ptr<stub> ptr;
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
typedef websocketpp::lib::shared_ptr<stub> ptr;
stub() : recycled(false) {}
stub() : recycled(false) {}
bool recycle(message * msg) {
this->recycled = true;
return false;
}
bool recycle(message *) {
this->recycled = true;
return false;
}
bool recycled;
bool recycled;
};
BOOST_AUTO_TEST_CASE( basic_size_check ) {
typedef websocketpp::message_buffer::message<stub> message_type;
typedef stub<message_type> stub_type;
typedef websocketpp::message_buffer::message<stub> message_type;
typedef stub<message_type> stub_type;
stub_type::ptr s(new stub_type());
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
stub_type::ptr s(new stub_type());
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
BOOST_CHECK(msg->get_payload().capacity() >= 500);
BOOST_CHECK(msg->get_payload().capacity() >= 500);
}
BOOST_AUTO_TEST_CASE( recycle ) {
typedef websocketpp::message_buffer::message<stub> message_type;
typedef stub<message_type> stub_type;
typedef websocketpp::message_buffer::message<stub> message_type;
typedef stub<message_type> stub_type;
stub_type::ptr s(new stub_type());
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
stub_type::ptr s(new stub_type());
message_type::ptr msg(new message_type(s,websocketpp::frame::opcode::TEXT,500));
BOOST_CHECK(s->recycled == false);
BOOST_CHECK(msg->recycle() == false);
BOOST_CHECK(s->recycled == true);
BOOST_CHECK(s->recycled == false);
BOOST_CHECK(msg->recycle() == false);
BOOST_CHECK(s->recycled == true);
}
+4 -4
View File
@@ -54,9 +54,9 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
bool exception;
try {
u = p.get_uri(r);
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
exception = true;
}
BOOST_CHECK(exception == false);
@@ -147,9 +147,9 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
BOOST_CHECK(!p.validate_handshake(r));
try {
u = p.get_uri(r);
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
exception = true;
}
BOOST_CHECK(exception == true);
+59
View File
@@ -0,0 +1,59 @@
# Generic processor tests
file (GLOB SOURCE processor.cpp)
init_target (test_processor)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
# Hybi00 processor tests
file (GLOB SOURCE hybi00.cpp)
init_target (test_processor_hybi00)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
# Hybi07 processor tests
file (GLOB SOURCE hybi07.cpp)
init_target (test_processor_hybi07)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
# Hybi08 processor tests
file (GLOB SOURCE hybi08.cpp)
init_target (test_processor_hybi08)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
if (ZLIB_FOUND)
# Hybi13 processor tests
file (GLOB SOURCE hybi13.cpp)
init_target (test_processor_hybi13)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
link_zlib()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
# Permessage compression extension processor tests
file (GLOB SOURCE extension_permessage_compress.cpp)
init_target (test_processor_extension_permessage_compress)
build_test (${TARGET_NAME} ${SOURCE})
link_boost ()
link_zlib()
final_target ()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "test")
endif ( ZLIB_FOUND )
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
<< websocketpp::utility::to_hex(test_out,test_out_size) << std::endl;
std::string input = "Hello";
std::string output = "";
std::string output;
ec = de.compress(input,output);
BOOST_CHECK( ec == processor::extensions::error::uninitialized );
@@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
<< websocketpp::utility::to_hex(input) << std::endl
<< websocketpp::utility::to_hex(output) << std::endl;
output = "";
output.clear();
ec = de.compress(input,output);
std::cout << ec.message() << std::endl
@@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
<< websocketpp::utility::to_hex(output) << std::endl;
input = output;
output = "";
output.clear();
ec = de.decompress(input,output);
std::cout << ec.message() << std::endl
<< websocketpp::utility::to_hex(input) << std::endl
+19 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -38,15 +38,15 @@
#include <websocketpp/message_buffer/alloc.hpp>
struct stub_config {
typedef websocketpp::http::parser::request request_type;
typedef websocketpp::http::parser::response response_type;
typedef websocketpp::http::parser::request request_type;
typedef websocketpp::http::parser::response response_type;
typedef websocketpp::message_buffer::message
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type;
static const size_t max_message_size = 16000000;
typedef websocketpp::message_buffer::message
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type;
static const size_t max_message_size = 16000000;
};
struct processor_setup {
@@ -55,16 +55,16 @@ struct processor_setup {
, p(false,server,msg_manager) {}
websocketpp::lib::error_code ec;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::request_type req;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::request_type req;
stub_config::response_type res;
websocketpp::processor::hybi00<stub_config> p;
websocketpp::processor::hybi00<stub_config> p;
};
typedef stub_config::message_type::ptr message_ptr;
BOOST_AUTO_TEST_CASE( exact_match ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
}
BOOST_AUTO_TEST_CASE( non_get_method ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
@@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
}
BOOST_AUTO_TEST_CASE( old_http_version ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
@@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
}
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\n\r\n";
@@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
}
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
@@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
}
BOOST_AUTO_TEST_CASE( bad_host ) {
processor_setup env(true);
processor_setup env(true);
websocketpp::uri_ptr u;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
@@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
}
BOOST_AUTO_TEST_CASE( extract_subprotocols ) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
+25 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Peter Thorson. All rights reserved.
* Copyright (c) 2014, Peter Thorson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -40,13 +40,13 @@
#include <websocketpp/random/none.hpp>
struct stub_config {
typedef websocketpp::http::parser::request request_type;
typedef websocketpp::http::parser::response response_type;
typedef websocketpp::http::parser::request request_type;
typedef websocketpp::http::parser::response response_type;
typedef websocketpp::message_buffer::message
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type;
typedef websocketpp::message_buffer::message
<websocketpp::message_buffer::alloc::con_msg_manager> message_type;
typedef websocketpp::message_buffer::alloc::con_msg_manager<message_type>
con_msg_manager_type;
typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
@@ -67,10 +67,10 @@ struct stub_config {
};
BOOST_AUTO_TEST_CASE( exact_match ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
@@ -101,10 +101,10 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
}
BOOST_AUTO_TEST_CASE( non_get_method ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
@@ -119,10 +119,10 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
}
BOOST_AUTO_TEST_CASE( old_http_version ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
@@ -137,10 +137,10 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
}
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
@@ -155,10 +155,10 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
}
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
@@ -173,10 +173,10 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
}
BOOST_AUTO_TEST_CASE( bad_host ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;

Some files were not shown because too many files have changed in this diff Show More