Compare commits

...
Author SHA1 Message Date
Peter Thorson 1dfc144eac Revert "Fix make_shared using the wrong strand type" 2015-11-24 10:04:10 -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 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
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 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 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 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 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 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 beaa6e98cc testee server defaults changes 2014-03-27 07:43:36 -05:00
Peter Thorson 79c2d09200 remove debug logging from critical paths 2014-03-27 07:43:11 -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 002d2d0007 force the offset to be calculated first to avoid confusing MSVC's checked iterators references #342
Thank you tmoers for reporting
2014-03-25 06:15:40 -05:00
Peter Thorson d8b7cf3fdc Merge pull request #343 from zaphoyd/batched_send
Batched send
2014-03-25 06:03:23 -05:00
Peter Thorson b358e2cfe8 update changelog 2014-03-25 05:49:15 -05:00
Peter Thorson 099fdbd4f1 Merge branch 'master' into batched_send 2014-03-25 05:46:12 -05:00
Peter Thorson 19a3713b29 use libc++ for non-c++11 branches on mac os x 2014-03-24 08:07:40 -05:00
Peter Thorson cd534ad18e implements batch sending
rather than writing a single message per trip through the underlying
transport, writes are batched and sent as a group. This drastically
improves the system call / application code ratio and tcp packet
utilization rates when sending lots of small messages
2014-03-24 08:04:23 -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 e2b7a4b9f1 fix whitespace 2014-03-16 09:59:34 -05:00
Peter Thorson e154d955ec Use __cplusplus header to enable C++11 language features 2014-03-16 09:26:51 -05:00
Peter Thorson 2207348abb Merge pull request #340 from dschmidt/master
Use _WIN32 instead of WIN32 preprocessor directive
2014-03-16 09:09:14 -05:00
Dominik Schmidt 77495d4076 Use _WIN32 instead of WIN32 preprocessor directive and fix warnings 2014-03-14 17:42:05 +01:00
Peter Thorson 8752687bc8 Merge pull request #339 from jefferai/master
Add define to allow disabling threading entirely
2014-03-12 13:15:24 -05:00
Jeff Mitchell 0f3a36a630 Add define to allow disabling threading entirely, for when using an
iostream-based client.
2014-03-12 10:46:33 -04:00
Peter Thorson a63f7d8b7b switch all exceptions to be of type websocketpp::exception 2014-03-06 19:35:25 -06:00
Peter Thorson edb26d7721 listen errors are now reported to the caller 2014-03-06 19:01:11 -06:00
Peter Thorson b2d698d3ca include hdl in message actions
This is not strictly necessary for the broadcast server example. As
this example is commonly used as a starting point for new programs the
lack of hdl on message action is a source of surprising behavior.
2014-03-06 11:59:38 -06:00
Peter Thorson 770b32275c updates websocketpp::exception to wrap lib::error_code 2014-03-05 08:30:08 -06:00
Peter Thorson 9d8eced9a1 Refactored server_endpoint to allow end users to access start_accept error states references #335
also more documentation
2014-03-05 08:06:14 -06:00
Peter Thorson fd0c62a8e4 add TLS config and types to asio integration tests 2014-03-05 07:27:41 -06:00
Peter Thorson 1a68f4b907 Merge pull request #335 from aydany/master
Require a valid con before calling terminate
2014-03-05 07:23:19 -06:00
Aydan Yumerefendi c3dfb25181 Merge remote-tracking branch 'upstream/master'
Conflicts:
	websocketpp/roles/server_endpoint.hpp
2014-03-04 21:19:24 -05:00
Aydan Yumerefendi 5a5d8321bd Require a valid con before calling terminate
If get_connection returns null, e.g., if during stop the tls_init
handler is removed from the server, con->terminate will cause a crash.
2014-03-04 21:02:42 -05:00
Peter Thorson b805689f9c whitespace and don't accept if we know the transport isn't listening references #334 2014-03-04 06:45:00 -06:00
Peter Thorson 7eedf25500 Merge pull request #334 from aydany/master
Avoid leak when stopping server
2014-03-04 06:18:34 -06:00
Aydan Yumerefendi 3ca53d0064 Avoid leak when stopping server
If accept fails, e.g., because the server is no longer listening the
connection object is not terminated and it results in a memory leak:
connection -> handler -> connection.
2014-03-03 21:51:56 -05:00
Peter Thorson 5e2fadd826 pass better information about TLS handshake failures 2014-03-03 17:09:55 -06:00
Peter Thorson 840bb6b59e code style and whitespace 2014-03-03 10:32:04 -06:00
Peter Thorson fe00a84f7b Merge pull request #333 from aydany/master
Fix memory leak when init_asio fails
2014-03-03 10:24:11 -06:00
Aydan Yumerefendi 337bf2fb0a Fix memory leak on create
If the socket fails to initialize, e.g., by omitting the tis init
handler, the connection is leaked, since there is a circular reference
between the connection and its async_read/async_write handlers. To fix
this, check the error code, and reset the handler is an error has
occurred.
2014-03-03 11:08:24 -05:00
Peter Thorson c5b5492e5c fix memory leak when a connection fails references #323 2014-03-02 22:12:38 -06:00
Peter Thorson af15537205 add debug header to integration tests 2014-03-02 22:12:14 -06:00
Peter Thorson bdeb4ad680 code style and documentation 2014-03-02 21:39:34 -06:00
Peter Thorson faad2ec854 add copyright info to debug client 2014-03-02 19:43:25 -06:00
Peter Thorson dc06049df9 add debug server example 2014-03-02 19:43:11 -06:00
Peter Thorson 3e53c74c3f Merge pull request #332 from zaphoyd/tutorials
Update examples and tutorials
2014-03-02 19:27:56 -06:00
Peter Thorson a5a30e554e rename app_client to utility_client and set utility_client to be the final step of the utility_client tutorial 2014-03-02 19:21:17 -06:00
Peter Thorson 9c8762c961 rename old utility client to debug client 2014-03-02 19:20:42 -06:00
Peter Thorson 797ce35c5a more renaming and adding license notes 2014-03-02 19:14:59 -06:00
Peter Thorson 30da3a967b renaming and re-titling the app client tutorial to utility client 2014-03-02 19:10:24 -06:00
Peter Thorson e1547bbde8 stray characters 2014-03-02 19:04:13 -06:00
Peter Thorson 37f69cc19b fix typo 2014-03-02 19:03:04 -06:00
Peter Thorson 93d9b5f820 Formatting fixes for app client tutorial step 5 2014-03-02 19:02:11 -06:00
Peter Thorson 98fd183210 Finish app client tutorial step 5 (closing) 2014-03-02 18:53:55 -06:00
Peter Thorson 093806f860 Merge branch 'master' into tutorials 2014-03-02 12:21:32 -06:00
Peter Thorson 1da45144e9 whitespace 2014-03-02 12:21:04 -06:00
Peter Thorson 5f56976290 Add method to look up a human readable string given a close code value 2014-03-02 12:19:50 -06:00
Peter Thorson 40ed74a141 Use clang on OS X by default for building examples and tests 2014-03-02 12:17:03 -06:00
Peter Thorson fbc9db2b5d work on close step 2014-03-02 12:06:37 -06:00
Peter Thorson f87c9d4360 need the line breaks to work here 2014-03-02 08:33:41 -06:00
Peter Thorson 99461184d3 Merge pull request #331 from zaphoyd/tls_short_read
Tls short read related changes references #263
2014-02-28 09:04:59 -06:00
Peter Thorson 9eff0db756 update changelog 2014-02-28 09:05:53 -06:00
Peter Thorson 86325b1838 cleans up the handling of TLS related transport errors
Specifically: TLS short read is separated from other TLS errors. Other
TLS errors are also not separated from generic “pass through” errors.

TLS short read is now considered “expected” during socket shutdown and
is not reported as an error.
2014-02-28 09:02:26 -06:00
Peter Thorson 2d2312a1d7 add socket/security policies to translate asio -> websocketpp error codes
The reason these were added to the socket policies rather than higher
up is that in some cases translating error codes requires information
from headers and libraries that are not present except when certain
socket policies are being used. For example, SSL/TLS related errors can
only be translated using openssl, which is only pulled in with the TLS
socket policy.
2014-02-28 09:00:45 -06:00
Peter Thorson afc28be004 whitespace 2014-02-28 08:27:29 -06:00
Peter Thorson b7c5a2e791 tls short read in state closed is no longer an error 2014-02-28 08:27:14 -06:00
Peter Thorson d36925ce7d Add new generic TLS error code 2014-02-28 08:26:50 -06:00
Peter Thorson 92dfe9ef97 clarify commands section and new members/methods of websocket_endpoint 2014-02-23 15:46:51 -06:00
Peter Thorson 2ab02197fd Fleshes out step 4 (opening connections) 2014-02-23 15:31:54 -06:00
Peter Thorson 89ac45e60a additional work on app client tutorial 2014-02-23 09:34:34 -06:00
Peter Thorson 713a05679c Merge pull request #325 from zaphoyd/max-message-size
error handling changes that ended up on wrong branch
2014-02-18 07:59:20 -06:00
Peter Thorson 0fecf023ef refactor connection error handling code 2014-02-18 08:01:16 -06:00
Peter Thorson ffdf5f842b reclassify action after shutdown as info rather than fatal references #62 2014-02-18 07:59:43 -06:00
Peter Thorson d425caea80 Fix misclassified error log entry 2014-02-18 07:58:49 -06:00
Peter Thorson ce2c1d6e34 whitespace 2014-02-13 11:18:44 -06:00
Peter Thorson 7ceeaa4f9c fix documentation spelling error 2014-02-13 11:10:47 -06:00
Peter Thorson 883410bb77 Fix an issue where custom timeout values weren't being propagated from endpoints to new connections 2014-02-12 15:07:09 -06:00
Peter Thorson 724974c758 Merge pull request #322 from zaphoyd/max-message-size
Adds the ability to specify a max message size
2014-02-10 20:55:02 -06:00
Peter Thorson 1622cdde04 Retry the travis build 2014-02-10 20:51:37 -06:00
Peter Thorson 180543b9e6 Adds the ability to specify a maximum message size 2014-02-10 09:21:07 -06:00
Peter Thorson 7c08cae15b fix bug that caused all error close frames to have a blank code 2014-02-10 09:17:43 -06:00
Peter Thorson 81e0c44b34 update debug config with max_message_size constant 2014-02-10 09:16:47 -06:00
Peter Thorson 722a67a910 add message payload size reservation 2014-02-10 08:39:20 -06:00
Peter Thorson ba6320ba1c Add maximum message size functionality to processors 2014-02-10 08:38:54 -06:00
Peter Thorson d9aa498310 whitespace cleanup 2014-02-10 08:37:47 -06:00
Peter Thorson 47c46a2fbc Fleshes out the remainder of app tutorial step 3 2014-02-07 08:10:10 -06:00
Peter Thorson 9401cf00ce rework app tutorial step 2 2014-02-07 07:26:00 -06:00
Peter Thorson acedd4db49 tutorial formatting 2014-02-07 06:59:28 -06:00
Peter Thorson 91617150e1 more tutorial formatting tests 2014-02-07 06:56:48 -06:00
Peter Thorson c7463afb06 tutorial updates 2014-02-07 06:49:45 -06:00
Peter Thorson ba90910f6e Fix an issue where set_open_handshake_timeout was ignored for servers 2014-02-05 21:00:30 -06:00
Peter Thorson bee2c03aa0 code style updates 2014-02-05 20:56:54 -06:00
Peter Thorson 8e86ddcf5a fix typos in comments 2014-02-02 19:28:23 -06:00
Peter Thorson fe85de763e Adds configurable SO_REUSEADDR option. references #311 2014-02-02 18:12:30 -06:00
Peter Thorson ca97dd1fb8 Switch to c-based tolower rather than c++ to avoid confusing Visual Studio references #287 2014-02-02 17:04:50 -06:00
Peter Thorson c7ec97795a add C++11 nullptr support detection 2014-02-02 17:03:41 -06:00
Peter Thorson 6ee7c368bb remove unused variables 2014-02-02 15:14:12 -06:00
Peter Thorson 2000746be7 correct misc minor warnings 2014-02-02 15:12:42 -06:00
Peter Thorson c84cc110aa Corrects more obscure shadowed variable cases 2 2014-02-02 13:17:17 -06:00
Peter Thorson 09940a5c0b Corrects more obscure shadowed variables cases 2014-02-02 13:12:52 -06:00
Peter Thorson bb21e3cf95 Fix use of variable names that shadow function parameters. references #318 2014-02-02 11:10:39 -06:00
Peter Thorson 5f3b92c9e4 Fix compile time conflict with Visual Studio's MIN/MAX macros. 2014-02-02 10:58:02 -06:00
Peter Thorson 14074666a7 disable some debugging output 2014-02-02 10:55:31 -06:00
Peter Thorson bb431ee0d2 Fix a crash following use of the stop_listening function. 2014-01-26 20:53:17 -06:00
Peter Thorson 373f180638 re-classify some errors with more specific codes and more appropriate logging levels 2014-01-26 20:50:31 -06:00
Peter Thorson 021ac0599c add additional error codes 2014-01-26 20:49:20 -06:00
Peter Thorson e44463583b Fix a crash when parsing empty HTTP headers 2014-01-26 19:39:55 -06:00
Peter Thorson 4393a2562b Add the ability to pause reading on a connection 2014-01-25 18:46:44 -06:00
Peter Thorson 780f7683a4 add typedefs for iostream clients and servers to integration test suite 2014-01-25 18:29:54 -06:00
Peter Thorson 8f359e6d35 typo 2013-12-14 09:37:16 -06:00
Peter Thorson ebb65c81e2 Allow disabling open, close, and pong timers entirely
Set their duration to zero to do this
2013-12-14 09:31:58 -06:00
Peter Thorson c7fda5a960 remove debug output from test 2013-12-14 09:31:58 -06:00
Peter Thorson 6d4514246f separate step 2 and 3 2013-12-14 07:41:21 -06:00
Peter Thorson c2f2cb951b Fixes some calls to empty lib::functions, references #310 2013-12-10 22:02:22 -06:00
Peter Thorson 827f3678bb Fixes a leak of connection objects when using asio transport references #310 2013-11-26 22:05:26 -06:00
Peter Thorson 57cd0e286e roadmap / wishlist for broadcast tutorial 2013-11-25 08:20:52 -06:00
Peter Thorson 87cb5036a4 initial work on app client tutorial 2013-11-25 08:16:14 -06:00
Peter Thorson f05f18b384 clean up chat tutorial a bit 2013-11-25 08:15:20 -06:00
Peter Thorson 01963a23ea working copy of app client tutorial example 2013-11-21 20:17:39 -06:00
Peter Thorson 18036d2b01 sets mutex to mutable to allow use in const accessors references #292 2013-11-05 07:52:31 -06:00
Peter Thorson 17bd89bd80 code style 2013-11-05 07:50:20 -06:00
Peter Thorson f59f301b91 fix typo in testee server 2013-11-04 17:36:55 -06:00
Peter Thorson 319507f4af update testee_server to disable nagle algorithm 2013-11-04 16:50:45 -06:00
Peter Thorson 06cdf43dcf Add start_perpetual and stop_perpetual to asio transport
These may be used to replace manually managed `asio::io_service::work`
objects
2013-11-04 16:50:35 -06:00
Peter Thorson f8f945433f code style 2013-11-04 07:40:11 -06:00
Peter Thorson a4f96cf0c3 groundwork for unclean close options 2013-11-04 07:40:06 -06:00
Peter Thorson 7032e6940f adds tcp pre and post init setting functionality to endpoint 2013-11-03 13:32:17 -06:00
Peter Thorson bfd50e1ee1 locks and spacing 2013-11-03 13:25:21 -06:00
Peter Thorson 415533f7e7 labels changes feature vs bug 2013-11-03 12:44:28 -06:00
Peter Thorson b87bfc068e Allow setting pong and handshake timeouts at runtime 2013-11-03 12:40:55 -06:00
Peter Thorson dbb5f963c8 update testee server to use extended listen backlog 2013-11-03 12:31:54 -06:00
Peter Thorson a1872c3790 Merge branch 'master' of https://github.com/zaphoyd/websocketpp
Conflicts:
	changelog.md
2013-11-02 19:34:01 -05:00
Peter Thorson 8993b34b3d Allows changing the listen backlog queue length 2013-11-02 19:32:38 -05:00
Peter Thorson 7ae83b9efd update changelog 2013-11-02 18:25:55 -05:00
Peter Thorson 430c49d394 splits tcp init into pre and post init 2013-11-02 18:25:21 -05:00
Peter Thorson 3e5404e1b1 split handler allocator into separate one for reads and writes 2013-11-02 18:24:14 -05:00
Peter Thorson 8524a1a272 add program arguments 2013-11-02 18:22:58 -05:00
Peter Thorson 6f79894ea5 add variable port and thread count to testee server 2013-11-02 17:59:55 -05:00
Peter Thorson 5e803b57f7 add uri unit test 2013-11-01 16:05:46 -05:00
Peter Thorson 6a3e886f0b update HTTP parser tests to use more specific test checks 2013-10-25 07:23:30 -05:00
Peter Thorson ac9351f9b3 strips LWS from incoming headers per RFC2616. fixes #301 2013-10-25 07:23:06 -05:00
Peter Thorson 00b5bed0d1 moves base64 code into websocketpp namespace 2013-10-20 15:02:51 -05:00
Peter Thorson 0f6e93a13e removes original copies of header-converted libraries to avoid confusion 2013-10-20 15:02:29 -05:00
Peter Thorson 84efd0425a moves sleep call out of a critical section references #283 2013-10-20 14:44:37 -05:00
Peter Thorson f4d3640870 update changelog 2013-10-20 14:30:54 -05:00
Peter Thorson 6680606523 Merge pull request #297 from evgeni/master
fix "recieve" typo in various places
2013-10-20 12:17:58 -07:00
Peter Thorson 962a090300 update code style and add docs+tests for uri::get_query references #298 2013-10-20 14:15:05 -05:00
Peter Thorson 4d51d990a4 Merge pull request #298 from Banaan/master
add get_query to URI handling
2013-10-20 12:00:54 -07:00
Peter Thorson 362f828767 update changelog 2013-10-20 13:14:12 -05:00
Peter Thorson aa74d2b295 switched asio read and write handler to use a custom allocator 2013-10-20 13:09:37 -05:00
Peter Thorson 746389efab removes some range checking in an inner read loop 2013-10-20 13:05:46 -05:00
Peter Thorson 5894601291 caches callback functions rather than copying them from handler to handler 2013-10-20 13:03:32 -05:00
Peter Thorson 17c9831449 cache the binding of async read and write handler callbacks 2013-10-20 12:57:02 -05:00
Peter Thorson 45a612f44b additional support for compile time disabling of multithreading features 2013-10-20 12:54:59 -05:00
Peter Thorson 2e3dfe7935 disable boundary checking in inner read loop 2013-10-20 12:50:10 -05:00
Peter Thorson 1b453e4679 adjust default read buffer size based on profiling 2013-10-20 12:49:22 -05:00
Peter Thorson 72a3bd6e4e add custom config to testee server to allow easier tuning 2013-10-20 12:48:09 -05:00
Banaan e73f4cdb10 Update uri.hpp
get query of URI method
2013-10-20 19:35:47 +02:00
Evgeni Golov 86fe22334c fix "recieve" typo in various places 2013-10-20 17:19:26 +02:00
Peter Thorson 71e6babd93 statically bind frame read and write handlers 2013-10-16 08:25:10 -05:00
Peter Thorson 8b9fa5db72 add switchable 1 vs 2 thread testee server operation 2013-10-16 08:24:28 -05:00
Peter Thorson 57d8e5cb6b add better clarification to exception printing 2013-10-16 08:24:02 -05:00
Peter Thorson 1e97f6c67c statically bind the async_read_handler 2013-10-16 08:23:42 -05:00
Peter Thorson 5c14c8e71e adds a compile time multithreading switch 2013-10-16 08:22:14 -05:00
Peter Thorson 933533c623 initial notes about tutorials 2013-10-13 12:49:30 -05:00
Peter Thorson 4231edec53 package as alpha4 2013-10-11 06:39:55 -05:00
Peter Thorson 4761938600 bugfix 2013-10-10 14:05:09 -05:00
Peter Thorson bf5f2852f9 updates license information for UTF8 validation logic references #294 2013-10-10 14:00:10 -05:00
Peter Thorson e16972b153 HTTP requests ending normally are no longer logged as errors. references #294 2013-10-10 13:47:01 -05:00
Peter Thorson 3d0d28affc Eliminate spurious expired timers in certain error conditions references #295 2013-10-10 13:45:49 -05:00
Peter Thorson 63cdaec0ba removes unused variable set per static analysis 2013-10-10 13:14:06 -05:00
Peter Thorson 43a258efaa updates changelog 2013-10-10 08:42:13 -05:00
Peter Thorson 3d57d412f7 Updates COPYING file to include all bundled licenses references #294 2013-10-10 08:20:03 -05:00
Peter Thorson 97e5e5fc7b replaces sha1 library with a more clearly licensed project references #294 2013-10-10 08:19:43 -05:00
Peter Thorson ed39a6ab1a Re-introduces strands to asio transport 2013-10-06 14:58:29 -05:00
Peter Thorson 67804061ea update changelog 2013-10-06 11:02:29 -05:00
Peter Thorson b934e71ace adjust transport async_accept and async_connect to use connection_ptr instead of connection_hdl
prevents a newly created connection_ptr from being destroyed
immediately after accepting or connecting.
2013-10-06 10:51:41 -05:00
Peter Thorson 96f7d0f3f2 catch test error condition better 2013-10-06 10:48:23 -05:00
Peter Thorson 013c2da7e8 removes internal connection tracking mechanism from endpoint 2013-10-06 10:47:59 -05:00
Peter Thorson aebdb26dc6 additional debug log detail 2013-10-06 10:34:15 -05:00
Peter Thorson 550365df6a updates iostream tests for new safer/less leaky API 2013-09-28 07:57:38 -05:00
Peter Thorson e91d6f6a45 refactor iostream read completion to remove memory leak 2013-09-28 07:56:41 -05:00
Peter Thorson de6d15c9fc adds documentation notes about when fatal_error and eof methods showed up 2013-09-28 07:56:03 -05:00
Peter Thorson 3035c8dc0a Deprecates iostream transport readsome in favor of read_some
which is more consistent with the naming of the rest of the library.
2013-09-28 07:55:41 -05:00
Peter Thorson c175ec4f42 Adds preliminary signaling to iostream transport of eof and fatal transport errors 2013-09-27 21:24:33 -05:00
Peter Thorson e6319f51a4 Updates transport code to use shared rather than raw pointers. references #293 2013-09-26 07:43:10 -05:00
Peter Thorson d17569fa87 fixes issue where custom headers couldn't be set for client connections 2013-09-25 08:18:46 -05:00
Peter Thorson f22c542a0d update credits for previous fix 2013-08-30 16:34:54 -05:00
Peter Thorson e9cb0b840f fixes a compile error on visual studio when using interrupts 2013-08-30 15:52:26 -05:00
Peter Thorson bd9c9767e1 Updates message buffer documentation and style 2013-08-17 12:16:21 -05:00
Peter Thorson 80133d6d55 fix unit tests 2013-08-15 08:37:29 -05:00
Peter Thorson ac41f467ed Merge branch 'master' of https://github.com/zaphoyd/websocketpp
Conflicts:
	changelog.md
2013-08-15 07:46:48 -05:00
Peter Thorson cab72215aa adds new close codes per IANA registry 2013-08-15 07:46:07 -05:00
Peter Thorson 12d240ff09 fix typo 2013-08-12 11:25:12 -05:00
Peter Thorson 107d3c9bb6 add set_remote_endpoint method to iostream transport 2013-08-12 11:22:45 -05:00
Peter Thorson 49c07296dd iostream transport documentation 2013-08-12 11:22:26 -05:00
Peter Thorson 8475f5f200 add iostream transport set_secure functionality 2013-08-12 11:21:41 -05:00
Peter Thorson 8ef8372af1 transport policy documentation 2013-08-12 11:16:59 -05:00
Peter Thorson 4a10d8ddfd iostream transport docs and code style 2013-08-12 11:16:45 -05:00
Peter Thorson f02c6f1c75 code style 2013-08-05 08:32:43 -05:00
Peter Thorson eb9ab6f70f add constexpr to static logging tests 2013-08-05 08:32:28 -05:00
Peter Thorson a2d92c9a21 style and documentation 2013-08-05 08:28:22 -05:00
Peter Thorson 6e23a6ec3c fix documentation bugs 2013-08-05 08:26:51 -05:00
Peter Thorson c30d000359 fix documentation typos, add client clarification 2013-07-31 22:42:55 -05:00
Peter Thorson ffe59ab078 documentation and code style 2013-07-30 22:13:56 -05:00
Peter Thorson e457467e9b Fix typo in .gitattributes, fixes #280 2013-07-27 11:29:34 -05:00
Peter Thorson 485304b438 Add missing locale include, fixes #281 2013-07-27 11:27:26 -05:00
Peter Thorson 3bab403c1b Refactor asio_transport and add full docs and exception free varient methods 2013-07-27 11:24:24 -05:00
Peter Thorson c017331959 remove trailing whitespace 2013-07-21 07:49:15 -05:00
Peter Thorson df828914c7 remove unneeded code and trailing whitespace 2013-07-21 07:38:27 -05:00
Peter Thorson 2c879ee797 Wrap ioservice run_one method. Fixes #278 2013-07-21 07:00:28 -05:00
Peter Thorson 241cf697f6 Suppress error when shutting down a closed connection 2013-07-17 07:28:26 -05:00
Peter Thorson c6f579a52a remove regex libs from CMAKE files 2013-07-17 07:26:53 -05:00
Peter Thorson 3f08de3d9d alpha3 release 2013-07-16 18:19:35 -05:00
Peter Thorson a9f3821d99 rename echo_client to testee client to better reflect its role 2013-07-14 11:02:59 -05:00
Peter Thorson 2964acd6d7 disable frame payload logging by default 2013-07-14 10:57:05 -05:00
Peter Thorson d564189d4c Merge pull request #274 from hobu/master
Implement conditional cmake configuration for echo_server_tls and add cmake config for print_server and telemetry_client
2013-07-14 08:56:17 -07:00
Peter Thorson ddca46f5d6 update changelog 2013-07-14 10:52:00 -05:00
Peter Thorson 7f062297de complete and clean up sha1 refactoring
move the remainder of documentation and licenses into sha1.hpp. Remove
unused files.
2013-07-14 10:49:40 -05:00
Peter Thorson 1c199aca6e minor refactoring of sha1 code
Update code style to better match project. Add more documentation. Add
some C++ specific features to improve compatibility and reduce warnings
with C++ applications. Add original project unit tests to WebSocket++
test suite.
2013-07-14 10:34:47 -05:00
Peter Thorson b8af39fd82 formatting 2013-07-13 13:29:10 -05:00
Peter Thorson c94621bd29 case insensitive header comparisons fixes #220 and #275 2013-07-13 13:28:56 -05:00
Howard Butler b83b054c7e add CMake config for print_server and telemetry_client 2013-07-11 10:54:43 -05:00
Howard Butler f6bcb86a6c Implement conditional cmake configuration for echo_server_tls 2013-07-10 16:09:38 -05:00
Peter Thorson 28ac69c800 temporary workaround for a g++ compile issue 2013-07-09 21:59:28 -05:00
Peter Thorson b866e4e0ca Refactors URI to be exception and regex free 2013-07-09 16:50:47 -05:00
Peter Thorson cdaf57cf7d update copyright date 2013-07-09 16:45:10 -05:00
Peter Thorson 2d49035a6d remove deprecated constants 2013-07-09 16:44:29 -05:00
Peter Thorson 686b835f3d update changelog 2013-07-08 19:02:14 -05:00
Peter Thorson 8f2c4264e1 Server header/User agent adjustments & tests
Updates behavior to drop the headers if user_agent is set to the empty
string and to allow overriding the Server header from the validate
function. Updates docs and adds a number of tests
2013-07-08 18:07:33 -05:00
Peter Thorson 5c608910d5 fix interface mismatch 2013-07-05 11:44:20 -05:00
Peter Thorson 229698dbb0 add experimental connection get message buffer method 2013-07-05 11:41:47 -05:00
Peter Thorson 6bd1bfd4f2 add basic compression/decompression implimentation 2013-07-03 06:19:08 -05:00
Peter Thorson dbd0fc5372 remove debug printing 2013-07-03 06:16:42 -05:00
Peter Thorson 7454bf68f6 re-enable permessage_deflate test 2013-06-30 19:46:29 -05:00
Peter Thorson 5b7f4a8c14 remove unneeded methods 2013-06-30 19:39:03 -05:00
Peter Thorson 9dd53d2e28 code style 2013-06-30 19:38:50 -05:00
Peter Thorson 915f5c77a8 support c2s_max_window_size 2013-06-30 18:34:21 -05:00
Peter Thorson 36cae596db update documentation 2013-06-30 18:32:37 -05:00
Peter Thorson 407b931395 Add s2c_max_window_bits negotiation 2013-06-29 17:53:53 -05:00
Peter Thorson 25b530b8a8 fix bug that prevented multiple attributes from working 2013-06-27 19:49:13 -05:00
Peter Thorson 038a9aee58 setting and negotiation of c2s_no_context_takeover 2013-06-27 19:48:48 -05:00
Peter Thorson 9749c0a3d5 enable server initiated s2c_no_context_takeover 2013-06-27 19:02:28 -05:00
Peter Thorson c7b1ddd9fa permessage-deflate negotiation of s2c_no_context_takeover 2013-06-27 18:35:32 -05:00
Peter Thorson 7a0d9c0238 cleanup permessage deflate extension 2013-06-25 21:07:46 -05:00
Peter Thorson cb08f07cb0 add combination error code / string type 2013-06-25 20:59:29 -05:00
Peter Thorson 743cd7a713 HTTP cleanup and documentation 2013-06-25 20:57:30 -05:00
Peter Thorson 88fe1bfb1c Fix issue where pong timeout handler always fired 2013-06-24 14:59:19 -05:00
Peter Thorson 5fd65a934b fix typo 2013-06-24 13:35:25 -05:00
Peter Thorson bb1420fe06 endpoint code style 2013-06-24 13:33:06 -05:00
Peter Thorson 0264b63fc3 Add ping and pong endpoint wrapper methods 2013-06-24 13:32:56 -05:00
Peter Thorson 256f8325e8 spelling, documentation, and style 2013-06-23 21:06:33 -05:00
Peter Thorson ce410a9428 transport documentation and style 2013-06-23 19:41:48 -05:00
Peter Thorson 573dedcb9d transport code style 2013-06-23 16:26:37 -05:00
Peter Thorson 4f8b2bdc98 transport documentation & style 2013-06-23 16:18:03 -05:00
Peter Thorson 330d564ded Flags 64 bit literals in frame unit tests references #264 2013-06-22 20:10:49 -05:00
Peter Thorson 161a5b169a Merge pull request #262 from breyed/streamed-timestamp
Write timestamp directly to output stream
2013-06-22 17:59:03 -07:00
Peter Thorson 7d36965149 Add accessor for raw http requests references #266 2013-06-22 10:59:26 -05:00
Peter Thorson de5684aef3 add test fail handler 2013-06-22 10:50:28 -05:00
Peter Thorson fd93ad89cb update documentation and code style 2013-06-16 21:08:53 -05:00
Peter Thorson 6d620aa1e8 add documentation & update code style 2013-06-15 12:46:39 -05:00
Peter Thorson 816fe6410d update documentation & code style 2013-06-15 12:39:57 -05:00
Peter Thorson f3c65ab609 documentation 2013-06-15 12:34:11 -05:00
Peter Thorson c938d9fd15 use strict masking for incoming messages references #264 2013-06-14 21:55:14 -05:00
Peter Thorson 0b764bdc62 add byte_mask_circ 2013-06-14 21:49:24 -05:00
Peter Thorson 86e2f364de fix readme 2013-06-14 21:48:46 -05:00
Peter Thorson 54dd4c8084 look up version rather than hardcode 2013-06-14 21:48:29 -05:00
Peter Thorson cae30acf91 update byte mask to use separate input & output types references #264
In particular this allows const iterators to be use for the input types.
2013-06-12 20:52:48 -05:00
Peter Thorson 24c1804e40 update documentation 2013-06-12 19:23:05 -05:00
breyed 8c6a360600 Write timestamp directly to output stream
This uses put_time (if supported) to avoid having to first write the timestamp to a temporary buffer and then copy it to the stream.
2013-06-09 18:28:19 -05:00
Peter Thorson 5c35535ffd update changelog 2013-06-09 18:26:41 -05:00
Peter Thorson 3256c72d98 Merge pull request #261 from breyed/master
added guards to avoid macro definition when used with boost_config.hpp
2013-06-09 16:24:09 -07:00
breyed 07ab02407f added guards to avoid macro definition when used with boost_config.hpp 2013-06-09 18:03:49 -05:00
Peter Thorson edc0057a03 update unit test 2013-06-09 17:39:49 -05:00
Peter Thorson 9161119b4d bump version to alpha2 2013-06-09 17:24:24 -05:00
Peter Thorson 7db60e3429 fix poor server handling of double close frames fixes #259 2013-06-09 17:03:14 -05:00
Peter Thorson 3c0b8a81b0 Fix handling of spurious frames after close. Fixes #258 2013-06-09 16:41:04 -05:00
Peter Thorson b812fd001b Change default HTTP response error code to 426
Changes default HTTP response error code when no http_handler is
defined from 500/Internal Server Error to 426/Upgrade Required
2013-06-09 16:20:53 -05:00
Peter Thorson 3a43986d9e add documentation & normalize code style 2013-06-09 14:58:32 -05:00
Peter Thorson 64b1b52297 adds documentation on locations of version info 2013-06-09 11:07:19 -05:00
Peter Thorson dc048ed021 test use of doxygen todo command 2013-06-09 11:05:48 -05:00
Peter Thorson 60b167bcb7 updates changelog 2013-06-09 09:27:08 -05:00
Peter Thorson e680ca1ef4 add comment + TODO regarding VSPP warning 2013-06-09 09:25:30 -05:00
Peter Thorson 21d79e28c6 maybe fix markdown # escape? 2013-06-09 09:20:31 -05:00
Peter Thorson d25a254e81 remove logger dynamic allocation 2013-06-09 09:20:04 -05:00
Peter Thorson 3e144cfd75 Merge pull request #257 from zaphoyd/experimental
merge last bit of changes from experimental to master
2013-06-09 07:15:12 -07:00
Peter Thorson 096a7dbaa8 escape # in readme 2013-06-09 08:58:15 -05:00
Peter Thorson 577591aaa1 readme updates 2013-06-09 08:55:53 -05:00
Peter Thorson a401a4448d update version information to 0.3.0-alpha1 2013-06-09 08:46:54 -05:00
Peter Thorson ace76f54f9 update docs for 0.3.x in master branch fixes #197 2013-06-09 08:31:05 -05:00
Peter Thorson 1eaa1b790f update travis for 0.3.x in master 2013-06-09 08:30:03 -05:00
221 changed files with 19748 additions and 9883 deletions

No files matched your search

+2 -2
View File
@@ -1,7 +1,7 @@
# Lineendings
*.sln eol=crlf
*.vcproj eol=crlf
*.vcxproj* eol=crfl
*.vcxproj* eol=crlf
# Whitespace rules
# strict (no trailing, no tabs)
@@ -15,4 +15,4 @@
*.txt whitespace=trailing-space,space-before-tab,cr-at-eol
# special files which must ignore whitespace
*.patch whitespace=-trailing-space
*.patch whitespace=-trailing-space
+10
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,9 @@ examples/wsperf/wsperf_client
*.out
*.log
*.opensdf
*.sdf
*.vcxproj
*.vcxproj.filters
*.user
install
+5 -2
View File
@@ -2,7 +2,7 @@ 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
env:
global:
- BOOST_INCLUDES=/usr/include
@@ -10,11 +10,14 @@ env:
script: scons -j 2 && scons test
branches:
only:
- master
- permessage-deflate
- experimental
- 0.3.x-cmake
- develop
notifications:
recipients:
- travis@zaphoyd.com
email:
on_success: change
on_failure: always
on_failure: always
+19 -12
View File
@@ -9,8 +9,8 @@ project (websocketpp)
cmake_minimum_required (VERSION 2.6)
set (WEBSOCKETPP_MAJOR_VERSION 0)
set (WEBSOCKETPP_MINOR_VERSION 2)
set (WEBSOCKETPP_PATCH_VERSION 99)
set (WEBSOCKETPP_MINOR_VERSION 6)
set (WEBSOCKETPP_PATCH_VERSION 0)
set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION})
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
@@ -70,7 +70,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
############ 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,12 +87,19 @@ 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
if (MSVC)
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
set (WEBSOCKETPP_BOOST_LIBS system thread)
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL /Gy /GF /Ox /Ob2 /Ot /Oi /MP /arch:SSE2 /fp:fast")
set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG /INCREMENTAL:NO /OPT:REF /OPT:ICF")
add_definitions (/W3 /wd4996 /wd4995 /wd4355)
@@ -104,9 +111,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_BOOST_LIBS system thread regex)
set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-std=c++0x")
set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
set (WEBSOCKETPP_BOOST_LIBS system thread)
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 ()
@@ -115,8 +122,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
execute_process (COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion" OUTPUT_VARIABLE GCC_VERSION)
if ("${GCC_VERSION}" STRGREATER "4.4.0")
message("* C++11 support partially enabled due to GCC version ${GCC_VERSION}")
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
add_definitions (-D_WEBSOCKETPP_NO_CPP11_REGEX_)
set (WEBSOCKETPP_BOOST_LIBS system thread)
endif ()
endif ()
@@ -127,8 +133,8 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
else()
set (WEBSOCKETPP_PLATFORM_LIBS pthread)
endif()
set (WEBSOCKETPP_PLATFORM_TSL_LIBS ssl crypto)
set (WEBSOCKETPP_BOOST_LIBS system thread regex)
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)
add_definitions (-DNDEBUG -Wall -Wno-padded) # todo: should we use CMAKE_C_FLAGS for these?
@@ -205,6 +211,7 @@ if (BUILD_TESTS OR BUILD_EXAMPLES)
message (FATAL_ERROR "Failed to find required dependency: boost")
endif ()
find_package(OpenSSL)
endif()
############ Add projects
+127 -5
View File
@@ -1,4 +1,6 @@
Copyright (c) 2013, Peter Thorson. All rights reserved.
Main Library:
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:
@@ -11,13 +13,133 @@ modification, are permitted provided that the following conditions are met:
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
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.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Bundled Libraries:
****** Base 64 Library (base64/base64.hpp) ******
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
single header suitable for use as a header only library. This conversion was
done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to
the code are redistributed under the same license as the original, which is
listed below.
base64.cpp and base64.h
Copyright (C) 2004-2008 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
****** SHA1 Library (sha1/sha1.hpp) ******
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the shallsha1
library (http://code.google.com/p/smallsha1/) into a single header suitable for
use as a header only library. This conversion was done by Peter Thorson
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
under the same license as the original, which is listed below.
Copyright (c) 2011, Micael Hildenborg
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 Micael Hildenborg 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 Micael Hildenborg ''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 Micael Hildenborg 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.
****** MD5 Library (common/md5.hpp) ******
md5.hpp is a reformulation of the md5.h and md5.c code from
http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to
function as a component of a header only library. This conversion was done by
Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
changes are released under the same license as the original (listed below)
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
****** UTF8 Validation logic (utf8_validation.hpp) ******
utf8_validation.hpp is adapted from code originally written by Bjoern Hoehrmann
<bjoern@hoehrmann.de>. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for
details.
The original license:
Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+6 -5
View File
@@ -32,9 +32,7 @@ PROJECT_NAME = "websocketpp"
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = "0.3.0-dev"
PROJECT_NUMBER = "0.6.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
@@ -670,7 +668,10 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = websocketpp
INPUT = websocketpp \
readme.md \
changelog.md \
roadmap.md
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -971,7 +972,7 @@ HTML_COLORSTYLE_GAMMA = 148
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
+44 -50
View File
@@ -79,6 +79,8 @@ elif env['PLATFORM'] == 'posix':
env.Append(CCFLAGS = ['-Wall'])
#env['LINKFLAGS'] = ''
elif env['PLATFORM'] == 'darwin':
if not os.environ.has_key('CXX'):
env['CXX'] = "clang++"
if env.has_key('DEBUG'):
env.Append(CCFLAGS = ['-g', '-O0'])
else:
@@ -98,11 +100,28 @@ else:
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
@@ -128,26 +147,21 @@ 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++'):
# TODO: check g++ version
# g++ STL lacks support for <regex>
GCC_VERSION = commands.getoutput(env_cpp11['CXX'] + ' -dumpversion')
if GCC_VERSION > "4.4.0":
print "C++11 build environment partially enabled"
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_','_WEBSOCKETPP_NO_CPP11_REGEX_'])
# libstdc++ does not yet support <regex>
# boost regex is a drop in replacement
polyfill_libs += boostlibs(['regex'],env_cpp11)
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
else:
print "C++11 build environment is not supported on this version of G++"
elif env_cpp11['CXX'].startswith('clang++'):
print "C++11 build environment enabled"
env.Append(CXXFLANGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++'])
env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x','-stdlib=libc++'],LINKFLAGS = ['-stdlib=libc++'],TOOLSET = ['clang++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
# look for optional second boostroot compiled with clang's libc++ STL library
@@ -163,21 +177,21 @@ else:
print "C++11 build environment disabled"
# 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
# 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
# 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/'
@@ -209,28 +223,38 @@ if not env['PLATFORM'].startswith('win'):
# Main test application
#main = SConscript('#/examples/dev/SConscript',variant_dir = builddir + 'dev',duplicate = 0)
# testee_server
testee_server = SConscript('#/examples/testee_server/SConscript',variant_dir = builddir + 'testee_server',duplicate = 0)
# echo_server
echo_server = SConscript('#/examples/echo_server/SConscript',variant_dir = builddir + 'echo_server',duplicate = 0)
# echo_server_tls
if not env['PLATFORM'].startswith('win'):
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)
# echo_client
echo_client = SConscript('#/examples/echo_client/SConscript',variant_dir = builddir + 'echo_client',duplicate = 0)
# testee_server
testee_server = SConscript('#/examples/testee_server/SConscript',variant_dir = builddir + 'testee_server',duplicate = 0)
# 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)
# debug_client
debug_client = SConscript('#/examples/debug_client/SConscript',variant_dir = builddir + 'debug_client',duplicate = 0)
# debug_server
debug_server = SConscript('#/examples/debug_server/SConscript',variant_dir = builddir + 'debug_server',duplicate = 0)
# 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)
if not env['PLATFORM'].startswith('win'):
# iostream_server
iostream_server = SConscript('#/examples/iostream_server/SConscript',variant_dir = builddir + 'iostream_server',duplicate = 0)
@@ -240,33 +264,3 @@ if not env['PLATFORM'].startswith('win'):
# print_server
print_server = SConscript('#/examples/print_server/SConscript',variant_dir = builddir + 'print_server',duplicate = 0)
#
#wsperf = SConscript('#/examples/wsperf/SConscript',
# variant_dir = builddir + 'wsperf',
# duplicate = 0)
#echo_server = SConscript('#/examples/echo_server/SConscript',
# variant_dir = builddir + 'echo_server',
# duplicate = 0)
#if tls_build:
# echo_server_tls = SConscript('#/examples/echo_server_tls/SConscript',
# variant_dir = builddir + 'echo_server_tls',
# duplicate = 0)
#echo_client = SConscript('#/examples/echo_client/SConscript',
# variant_dir = builddir + 'echo_client',
# duplicate = 0)
#chat_client = SConscript('#/examples/chat_client/SConscript',
# variant_dir = builddir + 'chat_client',
# duplicate = 0)
#chat_server = SConscript('#/examples/chat_server/SConscript',
# variant_dir = builddir + 'chat_server',
# duplicate = 0)
#concurrent_server = SConscript('#/examples/concurrent_server/SConscript',
# variant_dir = builddir + 'concurrent_server',
# duplicate = 0)
+279 -2
View File
@@ -1,2 +1,279 @@
0.3.0b1 - 2013-05-??
- Initial Release
HEAD
0.6.0
- 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.
- Feature: Allows changing the listen backlog queue length.
- Feature: Split tcp init into pre and post init.
- Feature: Adds URI method to extract query string from URI. Thank you Banaan
for code. #298
- Feature: Adds a compile time switch to asio transport config to disable
certain multithreading features (some locks, asio strands)
- Feature: Adds the ability to pause reading on a connection. Paused connections
will not read more data from their socket, allowing TCP flow control to work
without blocking the main thread.
- Feature: Adds the ability to specify whether or not to use the `SO_REUSEADDR`
TCP socket option. The default for this value has been changed from `true` to
`false`.
- 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
buffer sizes based on profiling, caching of handler binding for async
reads/writes, non-malloc allocators for read/write handlers, disabling of a
number of questionably useful range sanity checks in tight inner loops.
- Improvement: Cleaned up the handling of TLS related errors. TLS errors will
now be reported with more detail on the info channel rather than all being
`tls_short_read` or `pass_through`. In addition, many cases where a TLS short
read was in fact expected are no longer classified as errors. Expected TLS
short reads and quasi-expected socket shutdown related errors will no longer
be reported as unclean WebSocket shutdowns to the application. Information
about them will remain in the info error channel for debugging purposes.
- Improvement: `start_accept` and `listen` errors are now reported to the caller
either via an exception or an ec parameter.
- Improvement: Outgoing writes are now batched for improved message throughput
and reduced system call and TCP frame overhead.
- Bug: Fix some cases of calls to empty lib::function objects.
- Bug: Fix memory leak of connection objects due to cached handlers holding on to
reference counted pointers. #310 Thank you otaras for reporting.
- Bug: Fix issue with const endpoint accessors (such as `get_user_agent`) not
compiling due to non-const mutex use. #292 Thank you logofive for reporting.
- Bug: Fix handler allocation crash with multithreaded `io_service`.
- Bug: Fixes incorrect whitespace handling in header parsing. #301 Thank you
Wolfram Schroers for reporting
- Bug: Fix a crash when parsing empty HTTP headers. Thank you Thingol for
reporting.
- Bug: Fix a crash following use of the `stop_listening` function. Thank you
Thingol for reporting.
- Bug: Fix use of variable names that shadow function parameters. The library
should compile cleanly with -Wshadow now. Thank you giszo for reporting. #318
- Bug: Fix an issue where `set_open_handshake_timeout` was ignored by server
code. Thank you Robin Rowe for reporting.
- Bug: Fix an issue where custom timeout values weren't being propagated from
endpoints to new connections.
- Bug: Fix a number of memory leaks related to server connection failures. #323
#333 #334 #335 Thank you droppy and aydany for reporting and patches.
reporting.
- Compatibility: Fix compile time conflict with Visual Studio's MIN/MAX macros.
Thank you Robin Rowe for reporting.
- Documentation: Examples and test suite build system now defaults to clang on
OS X
0.3.0-alpha4 - 2013-10-11
- HTTP requests ending normally are no longer logged as errors. Thank you Banaan
for reporting. #294
- Eliminates spurious expired timers in certain error conditions. Thank you
Banaan for reporting. #295
- Consolidates all bundled library licenses into the COPYING file. #294
- Updates bundled sha1 library to one with a cleaner interface and more
straight-forward license. Thank you lotodore for reporting and Evgeni Golov
for reviewing. #294
- Re-introduces strands to asio transport, allowing `io_service` thread pools to
be used (with some limitations).
- Removes endpoint code that kept track of a connection list that was never used
anywhere. Removes a lock and reduces connection creation/deletion complexity
from O(log n) to O(1) in the number of connections.
- A number of internal changes to transport APIs
- Deprecates iostream transport `readsome` in favor of `read_some` which is more
consistent with the naming of the rest of the library.
- Adds preliminary signaling to iostream transport of eof and fatal transport
errors
- Updates transport code to use shared pointers rather than raw pointers to
prevent asio from retaining pointers to connection methods after the
connection goes out of scope. #293 Thank you otaras for reporting.
- Fixes an issue where custom headers couldn't be set for client connections
Thank you Jerry Win and Wolfram Schroers for reporting.
- Fixes a compile error on visual studio when using interrupts. Thank you Javier
Rey Neira for reporting this.
- Adds new 1012 and 1013 close codes per IANA registry
- Add `set_remote_endpoint` method to iostream transport.
- Add `set_secure` method to iostream transport.
- Fix typo in .gitattributes file. Thank you jstarasov for reporting this. #280
- Add missing locale include. Thank you Toninoso for reporting this. #281
- Refactors `asio_transport` endpoint and adds full documentation and exception
free varients of all methods.
- Removes `asio_transport` endpoint method cancel(). Use `stop_listen()` instead
- Wrap internal `io_service` `run_one()` method
- Suppress error when trying to shut down a connection that was already closed
0.3.0-alpha3 - 2013-07-16
- Minor refactor to bundled sha1 library
- HTTP header comparisons are now case insensitive. #220, #275
- Refactors URI to be exception free and not use regular expressions. This
eliminates the dependency on boost or C++11 regex libraries allowing native
C++11 usage on GCC 4.4 and higher and significantly reduces staticly built
binary sizes.
- Updates handling of Server and User-Agent headers to better handle custom
settings and allow suppression of these headers for security purposes.
- Fix issue where pong timeout handler always fired. Thank you Steven Klassen
for reporting this bug.
- Add ping and pong endpoint wrapper methods
- Add `get_request()` pass through method to connection to allow calling methods
specific to the HTTP policy in use.
- Fix issue compile error with `WEBSOCKETPP_STRICT_MASKING` enabled and another
issue where `WEBSOCKETPP_STRICT_MASKING` was not applied to incoming messages.
Thank you Petter Norby for reporting and testing these bugs. #264
- Add additional macro guards for use with boost_config. Thank you breyed
for testing and code. #261
0.3.0-alpha2 - 2013-06-09
- Fix a regression that caused servers being sent two close frames in a row
to end a connection uncleanly. #259
- Fix a regression that caused spurious frames following a legitimate close
frames to erroneously trigger handlers. #258
- 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
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
for testing and code. #257
0.3.0-alpha1 - 2013-06-09
- Initial Release
+4
View File
@@ -72,3 +72,7 @@ endmacro ()
macro (link_boost)
target_link_libraries (${TARGET_NAME} ${Boost_LIBRARIES})
endmacro ()
macro (link_openssl)
target_link_libraries (${TARGET_NAME} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
endmacro ()
+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:
@@ -20,55 +20,55 @@ class print_server {
public:
print_server() : m_next_sessionid(1) {
m_server.init_asio();
m_server.set_open_handler(bind(&print_server::on_open,this,::_1));
m_server.set_close_handler(bind(&print_server::on_close,this,::_1));
m_server.set_message_handler(bind(&print_server::on_message,this,::_1,::_2));
}
void on_open(connection_hdl hdl) {
connection_data data;
data.sessionid = m_next_sessionid++;
data.name = "";
m_connections[hdl] = data;
}
void on_close(connection_hdl hdl) {
connection_data& data = get_data_from_hdl(hdl);
std::cout << "Closing connection " << data.name
std::cout << "Closing connection " << data.name
<< " with sessionid " << data.sessionid << std::endl;
m_connections.erase(hdl);
}
void on_message(connection_hdl hdl, server::message_ptr msg) {
connection_data& data = get_data_from_hdl(hdl);
if (data.name == "") {
data.name = msg->get_payload();
std::cout << "Setting name of connection with sessionid "
std::cout << "Setting name of connection with sessionid "
<< data.sessionid << " to " << data.name << std::endl;
} else {
std::cout << "Got a message from connection " << data.name
std::cout << "Got a message from connection " << data.name
<< " with sessionid " << data.sessionid << std::endl;
}
}
connection_data& get_data_from_hdl(connection_hdl hdl) {
auto it = m_connections.find(hdl);
if (it == m_connections.end()) {
// this connection is not in the list. This really shouldn't happen
// and probably means something else is wrong.
throw std::invalid_argument("No data available for session");
}
return it->second;
}
void run(uint16_t port) {
m_server.listen(port);
m_server.start_accept();
@@ -85,4 +85,4 @@ private:
int main() {
print_server server;
server.run(9002);
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','thread','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system','thread'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+41 -43
View File
@@ -3,6 +3,7 @@
#include <websocketpp/server.hpp>
#include <iostream>
#include <set>
/*#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
@@ -34,44 +35,41 @@ enum action_type {
struct action {
action(action_type t, connection_hdl h) : type(t), hdl(h) {}
action(action_type t, server::message_ptr m) : type(t), msg(m) {}
action(action_type t, connection_hdl h, server::message_ptr m)
: type(t), hdl(h), msg(m) {}
action_type type;
websocketpp::connection_hdl hdl;
server::message_ptr msg;
};
class broadcast_server {
public:
broadcast_server() {
// Initialize Asio Transport
m_server.init_asio();
// Register handler callbacks
m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
m_server.set_close_handler(bind(&broadcast_server::on_close,this,::_1));
m_server.set_message_handler(bind(&broadcast_server::on_message,this,::_1,::_2));
}
void run(uint16_t port) {
// listen on specified port
m_server.listen(port);
// Start the server accept loop
m_server.start_accept();
// Start the ASIO io_service run loop
m_server.start_accept();
// 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;
@@ -79,7 +77,7 @@ public:
lock.unlock();
m_action_cond.notify_one();
}
void on_close(connection_hdl hdl) {
unique_lock<mutex> lock(m_action_lock);
//std::cout << "on_close" << std::endl;
@@ -87,38 +85,38 @@ public:
lock.unlock();
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,msg));
m_actions.push(action(MESSAGE,hdl,msg));
lock.unlock();
m_action_cond.notify_one();
}
void process_messages() {
while(1) {
unique_lock<mutex> lock(m_action_lock);
while(m_actions.empty()) {
m_action_cond.wait(lock);
}
action a = m_actions.front();
m_actions.pop();
lock.unlock();
if (a.type == SUBSCRIBE) {
unique_lock<mutex> lock(m_connection_lock);
unique_lock<mutex> con_lock(m_connection_lock);
m_connections.insert(a.hdl);
} else if (a.type == UNSUBSCRIBE) {
unique_lock<mutex> lock(m_connection_lock);
unique_lock<mutex> con_lock(m_connection_lock);
m_connections.erase(a.hdl);
} else if (a.type == MESSAGE) {
unique_lock<mutex> lock(m_connection_lock);
unique_lock<mutex> con_lock(m_connection_lock);
con_list::iterator it;
for (it = m_connections.begin(); it != m_connections.end(); ++it) {
m_server.send(*it,a.msg);
@@ -129,30 +127,30 @@ 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;
std::queue<action> m_actions;
mutex m_action_lock;
mutex m_connection_lock;
condition_variable m_action_cond;
};
int main() {
try {
broadcast_server server;
// Start a thread to run the processing loop
thread t(bind(&broadcast_server::process_messages,&server));
// Run the asio loop with the main thread
server.run(9002);
t.join();
} catch (std::exception & e) {
std::cout << e.what() << std::endl;
}
try {
broadcast_server 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);
t.join();
} catch (websocketpp::exception const & e) {
std::cout << e.what() << std::endl;
}
}
+24
View File
@@ -0,0 +1,24 @@
## Debug 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('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
prgs += env.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+166
View File
@@ -0,0 +1,166 @@
/*
* 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.
*/
/** ====== WARNING ========
* This example is presently used as a scratch space. It may or may not be broken
* at any given time.
*/
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <chrono>
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_tls_client::message_type::ptr message_ptr;
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
typedef client::connection_ptr connection_ptr;
class perftest {
public:
typedef perftest type;
typedef std::chrono::duration<int,std::micro> dur_type;
perftest () {
m_endpoint.set_access_channels(websocketpp::log::alevel::all);
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
// Initialize ASIO
m_endpoint.init_asio();
// 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_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) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
if (ec) {
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
}
//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();
m_endpoint.run();
}
void on_socket_init(websocketpp::connection_hdl) {
m_socket_init = std::chrono::high_resolution_clock::now();
}
context_ptr on_tls_init(websocketpp::connection_hdl) {
m_tls_init = std::chrono::high_resolution_clock::now();
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;
}
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) {
m_message = std::chrono::high_resolution_clock::now();
m_endpoint.close(hdl,websocketpp::close::status::going_away,"");
}
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;
std::cout << "TLS Init: " << std::chrono::duration_cast<dur_type>(m_tls_init-m_start).count() << std::endl;
std::cout << "Open: " << std::chrono::duration_cast<dur_type>(m_open-m_start).count() << std::endl;
std::cout << "Message: " << std::chrono::duration_cast<dur_type>(m_message-m_start).count() << std::endl;
std::cout << "Close: " << std::chrono::duration_cast<dur_type>(m_close-m_start).count() << std::endl;
}
private:
client m_endpoint;
std::chrono::high_resolution_clock::time_point m_start;
std::chrono::high_resolution_clock::time_point m_socket_init;
std::chrono::high_resolution_clock::time_point m_tls_init;
std::chrono::high_resolution_clock::time_point m_open;
std::chrono::high_resolution_clock::time_point m_message;
std::chrono::high_resolution_clock::time_point m_close;
};
int main(int argc, char* argv[]) {
std::string uri = "wss://echo.websocket.org";
if (argc == 2) {
uri = argv[1];
}
try {
perftest endpoint;
endpoint.start(uri);
} 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;
}
}
@@ -1,11 +1,10 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (echo_client)
init_target (debug_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
+23
View File
@@ -0,0 +1,23 @@
## Debug server 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('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+174
View File
@@ -0,0 +1,174 @@
/*
* 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.
*/
/** ====== WARNING ========
* This example is presently used as a scratch space. It may or may not be broken
* at any given time.
*/
#include <websocketpp/config/debug_asio_no_tls.hpp>
// Custom logger
#include <websocketpp/logger/syslog.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
////////////////////////////////////////////////////////////////////////////////
///////////////// 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;
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()
<< " 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;
}
}
int main() {
// Create a server endpoint
server echo_server;
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
echo_server.init_asio();
echo_server.set_reuse_addr(true);
// 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
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;
}
}
+170 -170
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;
}
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_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_close(connection_ptr con) {
std::cout << "handler on_close" << std::endl;
}
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 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_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;
}
};*/
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());
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;
std::random_device dev;
key.i = 0x12345678;
double m = 18094238402394.0824923;
/*std::cout << "Some Math" << std::endl;
{
boost::timer::auto_cpu_timer t;
for (int i = 0; i < foo; i++) {
m /= 1.001;
}
}*/
std::cout << m << std::endl;
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');
}
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);
}
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 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);
}
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;
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;
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);
}
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;
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;
/*server::handler::ptr h(new handler());
server test_server(h);
server::connection_ptr con;
std::stringstream output;
test_server.register_ostream(&output);
con = test_server.get_connection();
con->start();
//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 input2;
input2 << "messageabc2";
input2 >> *con;
std::stringstream input3;
input3 << "messageabc3";
input3 >> *con;
std::stringstream input4;
input4 << "close";
input4 >> *con;
std::cout << "connection output:" << std::endl;
std::cout << output.str() << std::endl;*/
con_msg_man_type::ptr manager = websocketpp::lib::make_shared<con_msg_man_type>();
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;
std::random_device dev;
key.i = 0x12345678;
double m = 18094238402394.0824923;
/*std::cout << "Some Math" << std::endl;
{
boost::timer::auto_cpu_timer t;
for (int i = 0; i < foo; i++) {
m /= 1.001;
}
}*/
std::cout << m << std::endl;
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');
}
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);
}
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 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);
}
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;
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;
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);
}
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;
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;
/*server::handler::ptr h(new handler());
server test_server(h);
server::connection_ptr con;
std::stringstream output;
test_server.register_ostream(&output);
con = test_server.get_connection();
con->start();
//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 input2;
input2 << "messageabc2";
input2 >> *con;
std::stringstream input3;
input3 << "messageabc3";
input3 >> *con;
std::stringstream input4;
input4 << "close";
input4 >> *con;
std::cout << "connection output:" << std::endl;
std::cout << output.str() << std::endl;*/
}
+1 -1
View File
@@ -1,4 +1,4 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+8 -8
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,16 +22,16 @@
* 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.
*
*
*/
#ifndef WEBSOCKETPP_ECHO_SERVER_HANDLER_HPP
#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
+19 -14
View File
@@ -15,45 +15,50 @@ 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()
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 (const websocketpp::lib::error_code& e) {
std::cout << "Echo failed because: " << e
std::cout << "Echo failed because: " << e
<< "(" << e.message() << ")" << std::endl;
}
}
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
echo_server.init_asio();
// Register our message handler
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
// 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;
}
+15
View File
@@ -0,0 +1,15 @@
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 ()
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-----
+15
View File
@@ -0,0 +1,15 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
if (OPENSSL_FOUND)
init_target (echo_server_tls)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
link_openssl()
final_target ()
endif()
+1 -1
View File
@@ -18,7 +18,7 @@ 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_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
prgs += env.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+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-----
+63 -20
View File
@@ -15,58 +15,101 @@ typedef websocketpp::config::asio::message_type::ptr message_ptr;
typedef websocketpp::lib::shared_ptr<boost::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()
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
std::cout << "Echo failed because: " << e
<< "(" << e.message() << ")" << std::endl;
}
}
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) {
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<boost::asio::ssl::context>(boost::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(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::no_sslv3 |
boost::asio::ssl::context::no_tlsv1 |
boost::asio::ssl::context::single_dh_use);
} else {
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);
// 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);
// Start the server accept loop
echo_server.start_accept();
// Listen on port 9002
echo_server.listen(9002);
// Start the ASIO io_service run loop
echo_server.run();
// Start the server accept loop
echo_server.start_accept();
// 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-----
+4 -4
View File
@@ -17,12 +17,12 @@ void custom_on_msg(server & s, connection_hdl hdl, server::message_ptr msg) {
void default_on_msg(server & s, connection_hdl hdl, server::message_ptr msg) {
std::cout << "Message sent to default handler" << std::endl;
if (msg->get_payload() == "upgrade") {
// Upgrade our connection_hdl to a full connection_ptr
server::connection_ptr con = s.get_con_from_hdl(hdl);
// Change the on message handler for this connection only to
// Change the on message handler for this connection only to
// custom_on_mesage
con->set_message_handler(bind(&custom_on_msg,ref(s),::_1,::_2));
std::cout << "Upgrading connection to custom handler" << std::endl;
@@ -39,4 +39,4 @@ int main() {
s.start_accept();
s.run();
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+31 -33
View File
@@ -17,75 +17,73 @@ 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) {
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
s->get_alog().write(websocketpp::log::alevel::app,
"Text Message Received: "+msg->get_payload());
s->get_alog().write(websocketpp::log::alevel::app,
"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()));
}
s->get_alog().write(websocketpp::log::alevel::app,
"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());
s->get_alog().write(websocketpp::log::alevel::app,
"Echo Failed: "+e.message());
}
}
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);
s.set_access_channels(websocketpp::log::alevel::disconnect);
s.set_access_channels(websocketpp::log::alevel::app);
// Log to a file rather than stdout, as we are using stdout for real
// Log to a file rather than stdout, as we are using stdout for real
// output
log.open("output.log");
s.get_alog().set_ostream(&log);
s.get_elog().set_ostream(&log);
// print all output to stdout
s.register_ostream(&std::cout);
// Register our message handler
s.set_message_handler(bind(&on_message,&s,::_1,::_2));
server::connection_ptr con = s.get_connection();
con->start();
// C++ iostream's don't support the idea of asynchronous i/o. As such
// there are two input strategies demonstrated here. Buffered I/O will
// read from stdin in chunks until EOF. This works very well for
// C++ iostream's don't support the idea of asynchronous i/o. As such
// there are two input strategies demonstrated here. Buffered I/O will
// read from stdin in chunks until EOF. This works very well for
// replaying canned connections as would be done in automated testing.
//
// If the server is being used live however, assuming input is being
// piped from elsewhere in realtime, this strategy will result in small
// messages being buffered forever. The non-buffered strategy below
// reads characters from stdin one at a time. This is inefficient and
// for more serious uses should be replaced with a platform specific
// If the server is being used live however, assuming input is being
// piped from elsewhere in realtime, this strategy will result in small
// messages being buffered forever. The non-buffered strategy below
// reads characters from stdin one at a time. This is inefficient and
// for more serious uses should be replaced with a platform specific
// asyncronous i/o technique like select, poll, IOCP, etc
bool buffered_io = false;
if (buffered_io) {
std::cin >> *con;
con->eof();
} else {
char a;
while(std::cin.get(a)) {
con->readsome(&a,1);
con->read_some(&a,1);
}
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();
}
}
+10
View File
@@ -0,0 +1,10 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (print_server)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+1 -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,20 +13,20 @@ class broadcast_server {
public:
broadcast_server() {
m_server.init_asio();
m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
m_server.set_close_handler(bind(&broadcast_server::on_close,this,::_1));
m_server.set_message_handler(bind(&broadcast_server::on_message,this,::_1,::_2));
}
void on_open(connection_hdl hdl) {
m_connections.insert(hdl);
}
void on_close(connection_hdl hdl) {
m_connections.erase(hdl);
}
void on_message(connection_hdl hdl, server::message_ptr msg) {
for (auto it : m_connections) {
m_server.send(it,msg);
@@ -48,4 +48,4 @@ private:
int main() {
broadcast_server server;
server.run(9002);
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
+2 -2
View File
@@ -1,4 +1,4 @@
## Main development example
## SIP client example
##
Import('env')
@@ -17,7 +17,7 @@ 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)
else:
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+21 -25
View File
@@ -6,7 +6,7 @@
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/thread.hpp>
typedef websocketpp::client<websocketpp::config::asio_client> client;
@@ -21,12 +21,12 @@ typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
client sip_client;
bool received;
bool received;
void on_open(client* c, websocketpp::connection_hdl hdl) {
// now it is safe to use the connection
std::cout << "connection ready" << std::endl;
received=false;
// Send a SIP OPTIONS message to the server:
std::string SIP_msg="OPTIONS sip:carol@chicago.com SIP/2.0\r\nVia: SIP/2.0/WS df7jal23ls0d.invalid;rport;branch=z9hG4bKhjhs8ass877\r\nMax-Forwards: 70\r\nTo: <sip:carol@chicago.com>\r\nFrom: Alice <sip:alice@atlanta.com>;tag=1928301774\r\nCall-ID: a84b4c76e66710\r\nCSeq: 63104 OPTIONS\r\nContact: <sip:alice@pc33.atlanta.com>\r\nAccept: application/sdp\r\nContent-Length: 0\r\n\r\n";
@@ -35,32 +35,32 @@ void on_open(client* c, websocketpp::connection_hdl hdl) {
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
client::connection_ptr con = sip_client.get_con_from_hdl(hdl);
std::cout << "Received a reply:" << std::endl;
fwrite(msg->get_payload().c_str(), msg->get_payload().size(), 1, stdout);
received=true;
}
int main(int argc, char* argv[]) {
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
try {
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
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);
// Initialize ASIO
sip_client.init_asio();
// Register our handlers
sip_client.set_open_handler(bind(&on_open,&sip_client,::_1));
sip_client.set_message_handler(bind(&on_message,&sip_client,::_1,::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = sip_client.get_connection(uri, ec);
@@ -68,21 +68,17 @@ int main(int argc, char* argv[]) {
con->add_subprotocol("sip");
sip_client.connect(con);
// Start the ASIO io_service run loop
// Start the ASIO io_service run loop
sip_client.run();
while(!received) {
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
}
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;
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
@@ -14,20 +14,20 @@ using websocketpp::lib::ref;
bool validate(server & s, connection_hdl hdl) {
server::connection_ptr con = s.get_con_from_hdl(hdl);
std::cout << "Cache-Control: " << con->get_request_header("Cache-Control") << std::endl;
const std::vector<std::string> & subp_requests = con->get_requested_subprotocols();
std::vector<std::string>::const_iterator it;
for (it = subp_requests.begin(); it != subp_requests.end(); ++it) {
std::cout << "Requested: " << *it << std::endl;
}
if (subp_requests.size() > 0) {
con->select_subprotocol(subp_requests[0]);
}
return true;
}
@@ -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;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (telemetry_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+53 -47
View File
@@ -9,123 +9,129 @@
/**
* The telemetry client connects to a WebSocket server and sends a message every
* second containing an integer count. This example can be used as the basis for
* programs where a client connects and pushes data for logging, stress/load
* programs where a client connects and pushes data for logging, stress/load
* testing, etc.
*/
class telemetry_client {
public:
typedef websocketpp::client<websocketpp::config::asio_client> client;
typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
telemetry_client() : m_open(false),m_done(false) {
// set up access channels to only log interesting things
m_client.clear_access_channels(websocketpp::log::alevel::all);
m_client.set_access_channels(websocketpp::log::alevel::connect);
m_client.set_access_channels(websocketpp::log::alevel::disconnect);
m_client.set_access_channels(websocketpp::log::alevel::app);
// Initialize the Asio transport policy
m_client.init_asio();
// 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
// Grab a handle for this connection so we can talk to it in a thread
// safe manor after the event loop starts.
m_hdl = con->get_handle();
// Queue the connection. No DNS queries or network connections will be
// made until the io_service event loop is run.
m_client.connect(con);
// Create a thread to run the ASIO io_service event loop
websocketpp::lib::thread asio_thread(&client::run, &m_client);
// Create a thread to run the telemetry loop
websocketpp::lib::thread telemetry_thread(&telemetry_client::telemetry_loop,this);
asio_thread.join();
telemetry_thread.join();
}
// The open handler will signal that we are ready to start sending telemetry
void on_open(websocketpp::connection_hdl hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
void on_open(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection opened, starting telemetry!");
scoped_lock guard(m_lock);
m_open = true;
}
// The close handler will signal that we should stop sending telemetry
void on_close(websocketpp::connection_hdl hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
void on_close(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection closed, stopping telemetry!");
scoped_lock guard(m_lock);
m_done = true;
}
// The fail handler will signal that we should stop sending telemetry
void on_fail(websocketpp::connection_hdl hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
void on_fail(websocketpp::connection_hdl) {
m_client.get_alog().write(websocketpp::log::alevel::app,
"Connection failed, stopping telemetry!");
scoped_lock guard(m_lock);
m_done = true;
}
void telemetry_loop() {
uint64_t count = 0;
std::stringstream val;
websocketpp::lib::error_code ec;
while(1) {
bool wait = false;
{
scoped_lock guard(m_lock);
// If the connection has been closed, stop generating telemetry
if (m_done) {break;}
// If the connection hasn't been opened yet wait a bit and retry
if (!m_open) {
sleep(1);
continue;
wait = true;
}
}
if (wait) {
sleep(1);
continue;
}
val.str("");
val << "count is " << count++;
m_client.get_alog().write(websocketpp::log::alevel::app, val.str());
m_client.send(m_hdl,val.str(),websocketpp::frame::opcode::text,ec);
// The most likely error that we will get is that the connection is
// not in the right state. Usually this means we tried to send a
// message to a connection that was closed or in the process of
// closing. While many errors here can be easily recovered from,
// not in the right state. Usually this means we tried to send a
// message to a connection that was closed or in the process of
// closing. While many errors here can be easily recovered from,
// 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());
m_client.get_alog().write(websocketpp::log::alevel::app,
"Send Error: "+ec.message());
break;
}
sleep(1);
}
}
@@ -139,12 +145,12 @@ private:
int main(int argc, char* argv[]) {
telemetry_client c;
std::string uri = "ws://localhost:9002";
if (argc == 2) {
uri = argv[1];
}
c.run(uri);
}
+10
View File
@@ -0,0 +1,10 @@
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 ()
@@ -15,9 +15,9 @@ 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('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
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,204 @@
#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;
typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
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_uri()->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;
}
+11
View File
@@ -0,0 +1,11 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (testee_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
+23
View File
@@ -0,0 +1,23 @@
## Autobahn test 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]
prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
@@ -17,9 +17,10 @@ int case_count = 0;
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
client::connection_ptr con = c->get_con_from_hdl(hdl);
if (con->get_resource() == "/getCaseCount") {
std::cout << "Detected " << msg->get_payload() << " test cases." << std::endl;
std::cout << "Detected " << msg->get_payload() << " test cases."
<< std::endl;
case_count = atoi(msg->get_payload().c_str());
} else {
c->send(hdl, msg->get_payload(), msg->get_opcode());
@@ -27,56 +28,53 @@ void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) {
}
int main(int argc, char* argv[]) {
// Create a server endpoint
client echo_client;
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
try {
// Create a server endpoint
client c;
std::string uri = "ws://localhost:9001";
if (argc == 2) {
uri = argv[1];
}
try {
// We expect there to be a lot of errors, so suppress them
echo_client.clear_access_channels(websocketpp::log::alevel::all);
echo_client.clear_error_channels(websocketpp::log::elevel::all);
c.clear_access_channels(websocketpp::log::alevel::all);
c.clear_error_channels(websocketpp::log::elevel::all);
// Initialize ASIO
echo_client.init_asio();
c.init_asio();
// Register our handlers
echo_client.set_message_handler(bind(&on_message,&echo_client,::_1,::_2));
c.set_message_handler(bind(&on_message,&c,::_1,::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = echo_client.get_connection(uri+"/getCaseCount", ec);
echo_client.connect(con);
// Start the ASIO io_service run loop
echo_client.run();
client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec);
c.connect(con);
// Start the ASIO io_service run loop
c.run();
std::cout << "case count: " << case_count << std::endl;
for (int i = 1; i <= case_count; i++) {
echo_client.reset();
c.reset();
std::stringstream url;
url << uri << "/runCase?case=" << i << "&agent=WebSocket++/0.3.0-dev";
con = echo_client.get_connection(url.str(), ec);
echo_client.connect(con);
echo_client.run();
url << uri << "/runCase?case=" << i << "&agent="
<< websocketpp::user_agent;
con = c.get_connection(url.str(), ec);
c.connect(con);
c.run();
}
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;
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex'],env) + [platform_libs] + [polyfill_libs]
ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+77 -15
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:
@@ -29,7 +29,44 @@
#include <websocketpp/server.hpp>
#include <iostream>
typedef websocketpp::server<websocketpp::config::asio> server;
struct testee_config : public websocketpp::config::asio {
// pull default settings from our core config
typedef websocketpp::config::asio core;
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 core::rng_type rng_type;
typedef core::endpoint_base endpoint_base;
static bool const enable_multithreading = true;
struct transport_config : public core::transport_config {
typedef core::concurrency_type concurrency_type;
typedef core::elog_type elog_type;
typedef core::alog_type alog_type;
typedef core::request_type request_type;
typedef core::response_type response_type;
static bool const enable_multithreading = true;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
static const websocketpp::log::level elog_level =
websocketpp::log::elevel::none;
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::none;
};
typedef websocketpp::server<testee_config> server;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
@@ -43,34 +80,59 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
s->send(hdl, msg->get_payload(), msg->get_opcode());
}
int main() {
// Create a server endpoint
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);
}
int main(int argc, char * argv[]) {
// Create a server endpoint
server testee_server;
try {
short port = 9002;
size_t num_threads = 1;
if (argc == 3) {
port = atoi(argv[1]);
num_threads = atoi(argv[2]);
}
try {
// Total silence
testee_server.clear_access_channels(websocketpp::log::alevel::all);
testee_server.clear_error_channels(websocketpp::log::alevel::all);
// Initialize ASIO
testee_server.init_asio();
testee_server.set_reuse_addr(true);
// Register our message handler
testee_server.set_message_handler(bind(&on_message,&testee_server,::_1,::_2));
testee_server.set_socket_init_handler(bind(&on_socket_init,::_1,::_2));
// Listen on port 9002
testee_server.listen(9002);
// Listen on specified port with extended listen backlog
testee_server.set_listen_backlog(8192);
testee_server.listen(port);
// Start the server accept loop
testee_server.start_accept();
// Start the ASIO io_service run loop
testee_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;
// Start the ASIO io_service run loop
if (num_threads == 1) {
testee_server.run();
} else {
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(websocketpp::lib::make_shared<websocketpp::lib::thread>(&server::run, &testee_server));
}
for (size_t i = 0; i < num_threads; i++) {
ts[i]->join();
}
}
} catch (websocketpp::exception const & e) {
std::cout << "exception: " << e.what() << std::endl;
}
}
+11
View File
@@ -0,0 +1,11 @@
file (GLOB SOURCE_FILES *.cpp)
file (GLOB HEADER_FILES *.hpp)
init_target (utility_client)
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
link_boost ()
final_target ()
+2 -3
View File
@@ -6,7 +6,6 @@ Import('env_cpp11')
Import('boostlibs')
Import('platform_libs')
Import('polyfill_libs')
Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
@@ -15,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] + [tls_libs]
ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
prgs += env_cpp11.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
else:
ALL_LIBS = boostlibs(['system','regex','random'],env) + [platform_libs] + [polyfill_libs] + [tls_libs]
ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
Return('prgs')
+304 -105
View File
@@ -1,126 +1,325 @@
/**
* This example is presently used as a scratch space. It may or may not be broken
* at any given time.
/*
* 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.
*/
#include <websocketpp/config/asio_client.hpp>
// **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 <chrono>
#include <map>
#include <string>
#include <sstream>
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;
using websocketpp::lib::bind;
// pull out the type of messages sent by our config
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
typedef client::connection_ptr connection_ptr;
class perftest {
class connection_metadata {
public:
typedef perftest type;
typedef std::chrono::duration<int,std::micro> dur_type;
perftest () {
m_endpoint.set_access_channels(websocketpp::log::alevel::all);
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
// Initialize ASIO
m_endpoint.init_asio();
// 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_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));
}
void start(std::string uri) {
websocketpp::lib::error_code ec;
client::connection_ptr con = m_endpoint.get_connection(uri, ec);
if (ec) {
m_endpoint.get_alog().write(websocketpp::log::alevel::app,ec.message());
}
//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();
m_endpoint.run();
}
void on_socket_init(websocketpp::connection_hdl hdl) {
m_socket_init = std::chrono::high_resolution_clock::now();
}
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
m_tls_init = std::chrono::high_resolution_clock::now();
context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;
try {
ctx->set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::no_sslv2 |
boost::asio::ssl::context::single_dh_use);
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
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();
}
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()));
}
return ctx;
}
websocketpp::connection_hdl get_hdl() const {
return m_hdl;
}
void on_open(websocketpp::connection_hdl hdl) {
m_open = std::chrono::high_resolution_clock::now();
m_endpoint.send(hdl, "", websocketpp::frame::opcode::text);
int get_id() const {
return m_id;
}
void on_message(websocketpp::connection_hdl hdl, message_ptr msg) {
m_message = std::chrono::high_resolution_clock::now();
m_endpoint.close(hdl,websocketpp::close::status::going_away,"");
std::string get_status() const {
return m_status;
}
void on_close(websocketpp::connection_hdl 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;
std::cout << "TLS Init: " << std::chrono::duration_cast<dur_type>(m_tls_init-m_start).count() << std::endl;
std::cout << "Open: " << std::chrono::duration_cast<dur_type>(m_open-m_start).count() << std::endl;
std::cout << "Message: " << std::chrono::duration_cast<dur_type>(m_message-m_start).count() << std::endl;
std::cout << "Close: " << std::chrono::duration_cast<dur_type>(m_close-m_start).count() << std::endl;
void record_sent_message(std::string message) {
m_messages.push_back(">> " + message);
}
friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
private:
client m_endpoint;
std::chrono::high_resolution_clock::time_point m_start;
std::chrono::high_resolution_clock::time_point m_socket_init;
std::chrono::high_resolution_clock::time_point m_tls_init;
std::chrono::high_resolution_clock::time_point m_open;
std::chrono::high_resolution_clock::time_point m_message;
std::chrono::high_resolution_clock::time_point m_close;
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::vector<std::string> m_messages;
};
int main(int argc, char* argv[]) {
std::string uri = "wss://echo.websocket.org";
if (argc == 2) {
uri = argv[1];
}
try {
perftest endpoint;
endpoint.start(uri);
} 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;
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) << "\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;
}
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 = websocketpp::lib::make_shared<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 = 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(
&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
));
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);
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;
}
}
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()) {
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"
<< "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"
<< "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,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 = "";
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;
}
+16 -23
View File
@@ -1,22 +1,12 @@
WebSocket++ (0.3.x branch)
WebSocket++ (0.6.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.
*This branch is no longer "experimental". It represents the current edge release
of the WebSocket++ library. The API of 0.3.x has some significant changes from
0.2.x, so care should be taken when upgrading.*
*This branch's API is relatively stable now. Features implemented so far are
unlikely to change (except where explicitly noted). New features will be added
regularly until parity with the 0.2 branch is reached.*
*This is the preferred branch for new projects, especially those that involve
multithreaded servers. It is better tested and documented. The 0.3.x API will
be the basis for the 1.0 release.*
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
==============
@@ -25,30 +15,33 @@ 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)
* Portable, cross platform and architecture design
* Interchangeable network transport modules (raw, iostream, Asio, or custom)
* Portable/cross platform (Posix/Windows, 32/64bit, Intel/ARM/PPC)
* Thread-safe
Get Involved
============
[![Build Status](https://travis-ci.org/zaphoyd/websocketpp.png)](https://travis-ci.org/zaphoyd/websocketpp)
**Project Website**
**Project Website**
http://www.zaphoyd.com/websocketpp/
**User Manual**
**User Manual**
http://www.zaphoyd.com/websocketpp/manual/
**GitHub Repository**
**GitHub Repository**
https://github.com/zaphoyd/websocketpp/
**Announcements Mailing List**
GitHub pull requests should be submitted to the `develop` branch.
**Announcements Mailing List**
http://groups.google.com/group/websocketpp-announcements/
**IRC Channel**
#websocketpp (freenode)
**IRC Channel**
#websocketpp (freenode)
**Discussion / Development / Support Mailing List / Forum**
**Discussion / Development / Support Mailing List / Forum**
http://groups.google.com/group/websocketpp/
Author
+22 -24
View File
@@ -8,38 +8,36 @@ Complete & Tested:
- GCC support
- 64 bit support
- 32 bit support
Implimented, needs more testing
- TLS support
- echo_server & echo_server_tls
- External io_service support
- socket_init_handler
- tls_init_handler
- Logging
- Client role
- message_handler
- ping_handler
- pong_handler
- tcp_init_handler
- exception/error handling
- Logging
- Client role
- Subprotocol negotiation
- Hybi 00/Hixie 76 legacy protocol support
- Performance tuning
- Outgoing Proxy Support
- PowerPC support
- Visual Studio / Windows support
Implimented, API not finalized
- open_handler
- close_handler
- echo_server & echo_server_tls
- 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
Ongoing work
- Performance tuning
- PowerPC support
- Visual Studio / Windows support
- CMake build/install support
- http_handler
Needs work:
- Timeouts
Non-release blocking feature roadmap
Future feature roadmap
- Extension support
- permessage_compress extension
- Message buffer pool
- CMake build/install support
- flow control
- tutorials & documentation
+1 -1
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs]
objs = env.Object('connection_boost.o', ["connection.cpp"], LIBS = BOOST_LIBS)
objs = env.Object('connection_tu2_boost.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS)
+405 -42
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE connection
@@ -30,31 +30,35 @@
#include "connection_tu2.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
// 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
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 500 Internal Server Error\r\nServer: " +
std::string(websocketpp::user_agent)+"\r\n\r\n";
std::string o2 = run_server_test(input);
std::string output = "HTTP/1.1 426 Upgrade Required\r\nServer: " +
std::string(websocketpp::user_agent)+"\r\n\r\n";
std::string o2 = run_server_test(input);
BOOST_CHECK(o2 == output);
}
struct connection_extension {
connection_extension() : extension_value(5) {}
int extension_method() {
return extension_value;
}
bool is_server() const {
return false;
}
int extension_value;
};
@@ -72,24 +76,74 @@ struct stub_config : public websocketpp::config::core {
typedef core::elog_type elog_type;
typedef core::rng_type rng_type;
typedef core::transport_type transport_type;
typedef core::endpoint_base endpoint_base;
typedef connection_extension connection_base;
};
struct connection_setup {
connection_setup(bool server)
: c(server,"",alog,elog,rng) {}
struct debug_config_client : public websocketpp::config::core {
typedef debug_config_client type;
websocketpp::lib::error_code ec;
stub_config::alog_type alog;
stub_config::elog_type elog;
stub_config::rng_type rng;
websocketpp::connection<stub_config> c;
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::elog_type elog;
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());
}*/
@@ -98,21 +152,59 @@ void validate_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg)
s->send(hdl, msg->get_payload(), msg->get_opcode());
}
bool validate_set_ua(server* s, websocketpp::connection_hdl hdl) {
server::connection_ptr con = s->get_con_from_hdl(hdl);
con->replace_header("Server","foo");
return true;
}
void http_func(server* s, websocketpp::connection_hdl hdl) {
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);
}
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 ) {
connection_setup env(true);
BOOST_CHECK( env.c.extension_value == 5 );
BOOST_CHECK( env.c.extension_method() == 5 );
BOOST_CHECK( env.c.is_server() == true );
}
@@ -121,10 +213,10 @@ BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: ";
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);
}
@@ -133,30 +225,301 @@ BOOST_AUTO_TEST_CASE( http_request ) {
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;
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));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
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));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
std::string uri = "ws://localhost";
//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::stringstream output;
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);
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());
}
BOOST_AUTO_TEST_CASE( set_max_message_size ) {
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\n\r\n";
// After the handshake, add a single frame with a message that is too long.
char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
input.append(frame0, 10);
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";
// After the handshake, add a single frame with a close message with message too big
// error code.
char frame1[4] = {char(0x88), 0x19, 0x03, char(0xf1)};
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));
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( 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**";
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( client_handshake_timeout_race2 ) {
debug_client c;
websocketpp::lib::error_code ec;
debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
BOOST_CHECK(!ec);
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));
}
+30 -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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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 "connection_tu2.hpp"
@@ -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);
s.register_ostream(&output);
con = s.get_connection();
con->start();
std::stringstream channel;
channel << input;
channel >> *con;
return output.str();
}
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);
con = s.get_connection();
con->start();
std::stringstream channel;
channel << input;
channel >> *con;
return output.str();
}
+14 -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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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 <iostream>
@@ -30,27 +30,22 @@
// 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>
typedef websocketpp::server<websocketpp::config::core> server;
/// NOTE: the "server" config is being used for the client here because we don't
/// want to pull in the real RNG. A better way to do this might be a custom
/// client config with the RNG explicitly stubbed out.
typedef websocketpp::client<websocketpp::config::core> client;
typedef websocketpp::config::core::message_type::ptr message_ptr;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
/*class echo_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;
}
};*/
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);
+1 -1
View File
@@ -11,7 +11,7 @@ Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs] + [tls_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + [tls_libs]
objs = env.Object('endpoint_boost.o', ["endpoint.cpp"], LIBS = BOOST_LIBS)
prgs = env.Program('test_endpoint_boost', ["endpoint_boost.o"], LIBS = BOOST_LIBS)
+70 -16
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE endpoint
@@ -57,17 +57,46 @@ 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) {}
int extension_method() {
return extension_value;
}
bool is_server() const {
return false;
}
int extension_value;
};
@@ -85,17 +114,42 @@ struct stub_config : public websocketpp::config::core {
typedef core::elog_type elog_type;
typedef core::rng_type rng_type;
typedef core::transport_type transport_type;
typedef endpoint_extension endpoint_base;
};
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( s.is_server() == true );
BOOST_CHECK_EQUAL( s.extension_value, 5 );
BOOST_CHECK_EQUAL( s.extension_method(), 5 );
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);
}
+6 -2
View File
@@ -10,14 +10,18 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','system','regex'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + ['z']
objs = env.Object('extension_boost.o', ["extension.cpp"], LIBS = BOOST_LIBS)
objs += env.Object('permessage_deflate_boost.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS)
prgs = env.Program('test_extension_boost', ["extension_boost.o"], LIBS = BOOST_LIBS)
prgs += env.Program('test_permessage_deflate_boost', ["permessage_deflate_boost.o"], LIBS = BOOST_LIBS)
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
objs += env_cpp11.Object('extension_stl.o', ["extension.cpp"], LIBS = BOOST_LIBS_CPP11)
objs += env_cpp11.Object('permessage_deflate_stl.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS_CPP11)
prgs += env_cpp11.Program('test_extension_stl', ["extension_stl.o"], LIBS = BOOST_LIBS_CPP11)
prgs += env_cpp11.Program('test_permessage_deflate_stl', ["permessage_deflate_stl.o"], LIBS = BOOST_LIBS_CPP11)
Return('prgs')
+5 -5
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE extension
+543
View File
@@ -0,0 +1,543 @@
/*
* Copyright (c) 2011, 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.
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE permessage_deflate
#include <boost/test/unit_test.hpp>
#include <websocketpp/error.hpp>
#include <websocketpp/extensions/extension.hpp>
#include <websocketpp/extensions/permessage_deflate/disabled.hpp>
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
#include <string>
#include <websocketpp/utilities.hpp>
#include <iostream>
class config {};
typedef websocketpp::extensions::permessage_deflate::enabled<config> enabled_type;
typedef websocketpp::extensions::permessage_deflate::disabled<config> disabled_type;
struct ext_vars {
enabled_type exts;
enabled_type extc;
websocketpp::lib::error_code ec;
websocketpp::err_str_pair esp;
websocketpp::http::attribute_list attr;
};
namespace pmde = websocketpp::extensions::permessage_deflate::error;
namespace pmd_mode = websocketpp::extensions::permessage_deflate::mode;
// Ensure the disabled extension behaves appropriately disabled
BOOST_AUTO_TEST_CASE( disabled_is_disabled ) {
disabled_type exts;
BOOST_CHECK( !exts.is_implemented() );
}
BOOST_AUTO_TEST_CASE( disabled_is_off ) {
disabled_type exts;
BOOST_CHECK( !exts.is_enabled() );
}
// Ensure the enabled version actually works
BOOST_AUTO_TEST_CASE( enabled_is_enabled ) {
ext_vars v;
BOOST_CHECK( v.exts.is_implemented() );
BOOST_CHECK( v.extc.is_implemented() );
}
BOOST_AUTO_TEST_CASE( enabled_starts_disabled ) {
ext_vars v;
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK( !v.extc.is_enabled() );
}
BOOST_AUTO_TEST_CASE( negotiation_empty_attr ) {
ext_vars v;
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( negotiation_invalid_attr ) {
ext_vars v;
v.attr["foo"] = "bar";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attributes) );
BOOST_CHECK_EQUAL( v.esp.second, "");
}
// Negotiate s2c_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_invalid ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "foo";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
BOOST_CHECK_EQUAL( v.esp.second, "");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover ) {
ext_vars v;
v.attr["s2c_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_AUTO_TEST_CASE( negotiate_s2c_no_context_takeover_server_initiated ) {
ext_vars v;
v.exts.enable_s2c_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");
}
// Negotiate c2s_no_context_takeover
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_invalid ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "foo";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
BOOST_CHECK_EQUAL( v.esp.second, "");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover ) {
ext_vars v;
v.attr["c2s_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_AUTO_TEST_CASE( negotiate_c2s_no_context_takeover_server_initiated ) {
ext_vars v;
v.exts.enable_c2s_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");
}
// Negotiate s2c_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_invalid ) {
ext_vars v;
std::vector<std::string> values;
values.push_back("");
values.push_back("foo");
values.push_back("7");
values.push_back("16");
std::vector<std::string>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
v.attr["s2c_max_window_bits"] = *it;
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
BOOST_CHECK_EQUAL( v.esp.second, "");
}
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_valid ) {
ext_vars v;
v.attr["s2c_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");
v.attr["s2c_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_s2c_max_window_bits ) {
ext_vars v;
v.ec = v.exts.set_s2c_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);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_decline ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_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() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_accept ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_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_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_largest ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_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_AUTO_TEST_CASE( negotiate_s2c_max_window_bits_smallest ) {
ext_vars v;
v.attr["s2c_max_window_bits"] = "8";
v.ec = v.exts.set_s2c_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");
}
// Negotiate s2c_max_window_bits
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_invalid ) {
ext_vars v;
std::vector<std::string> values;
values.push_back("foo");
values.push_back("7");
values.push_back("16");
std::vector<std::string>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
v.attr["c2s_max_window_bits"] = *it;
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( !v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, pmde::make_error_code(pmde::invalid_attribute_value) );
BOOST_CHECK_EQUAL( v.esp.second, "");
}
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_valid ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "";
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.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");
v.attr["c2s_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 ) {
ext_vars v;
v.ec = v.exts.set_c2s_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);
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_decline ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_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() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_accept ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_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_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_largest ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_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_AUTO_TEST_CASE( negotiate_c2s_max_window_bits_smallest ) {
ext_vars v;
v.attr["c2s_max_window_bits"] = "8";
v.ec = v.exts.set_c2s_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");
}
// Combinations with 2
BOOST_AUTO_TEST_CASE( negotiate_two_client_initiated1 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_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; c2s_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.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_AUTO_TEST_CASE( negotiate_two_client_initiated3 ) {
ext_vars v;
v.attr["s2c_no_context_takeover"] = "";
v.attr["c2s_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_AUTO_TEST_CASE( negotiate_two_client_initiated4 ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["s2c_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_AUTO_TEST_CASE( negotiate_two_client_initiated5 ) {
ext_vars v;
v.attr["c2s_no_context_takeover"] = "";
v.attr["c2s_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_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.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_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.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_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.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_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.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_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.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_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.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");
}
// Compression
/*
BOOST_AUTO_TEST_CASE( compress_data ) {
ext_vars v;
std::string in = "Hello";
std::string out;
std::string in2;
std::string out2;
v.exts.init();
v.ec = v.exts.compress(in,out);
std::cout << "in : " << websocketpp::utility::to_hex(in) << std::endl;
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);
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_AUTO_TEST_CASE( decompress_data ) {
ext_vars v;
uint8_t in[12] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00, 0x00, 0x00, 0xff, 0xff};
std::string out;
v.exts.init();
v.ec = v.exts.decompress(in,12,out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
std::cout << "out: " << websocketpp::utility::to_hex(out) << std::endl;
BOOST_CHECK( false );
}
*/
+1 -1
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','regex'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework'],env) + [platform_libs]
objs = env.Object('parser_boost.o', ["parser.cpp"], LIBS = BOOST_LIBS)
prgs = env.Program('test_http_boost', ["parser_boost.o"], LIBS = BOOST_LIBS)
+486 -252
View File
File diff suppressed because it is too large. Load diff
+108 -108
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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/http/parser.hpp>
@@ -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;
//nanoseconds_per_test
//tests_per_second
//1000000000.0/(double(time_taken.count())/1000.0)
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;
}
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
//tests_per_second
//1000000000.0/(double(time_taken.count())/1000.0)
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;
}
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 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 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;
try {
r.consume(raw.c_str(),raw.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
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;
try {
r.consume2(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
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;
try {
r.consume(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
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;
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;
}
}
}
return 0;
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 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";
{
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;
}
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;
try {
r.consume2(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
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;
try {
r.consume(firefox.c_str(),firefox.size());
} catch (...) {
std::cout << "exception" << std::endl;
}
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;
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;
}
}
}
return 0;
}
+1 -1
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs]
objs = env.Object('logger_basic_boost.o', ["basic.cpp"], LIBS = BOOST_LIBS)
prgs = env.Program('logger_basic_boost', ["logger_basic_boost.o"], LIBS = BOOST_LIBS)
+81 -17
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE basic_log
@@ -34,18 +34,20 @@
#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;
error_log elog;
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::info ) == true );
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::warn ) == true );
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::rerror ) == true );
BOOST_CHECK( elog.static_test(websocketpp::log::elevel::fatal ) == true );
elog.set_channels(websocketpp::log::elevel::info);
elog.write(websocketpp::log::elevel::info,"Information");
elog.write(websocketpp::log::elevel::warn,"A warning");
elog.write(websocketpp::log::elevel::rerror,"A error");
@@ -54,13 +56,13 @@ BOOST_AUTO_TEST_CASE( is_token_char ) {
BOOST_AUTO_TEST_CASE( access_clear ) {
typedef websocketpp::log::basic<websocketpp::concurrency::none,websocketpp::log::alevel> access_log;
std::stringstream out;
access_log logger(0xffffffff,&out);
// clear all channels
logger.clear_channels(0xffffffff);
// writes shouldn't happen
logger.write(websocketpp::log::alevel::devel,"devel");
//std::cout << "|" << out.str() << "|" << std::endl;
@@ -69,13 +71,75 @@ BOOST_AUTO_TEST_CASE( access_clear ) {
BOOST_AUTO_TEST_CASE( basic_concurrency ) {
typedef websocketpp::log::basic<websocketpp::concurrency::basic,websocketpp::log::alevel> access_log;
std::stringstream out;
access_log logger(0xffffffff,&out);
logger.set_channels(0xffffffff);
logger.write(websocketpp::log::alevel::devel,"devel");
//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);
}*/
+51 -51
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE message_buffer_alloc
@@ -35,62 +35,62 @@
template <template <class> class con_msg_manager>
struct stub {
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 websocketpp::lib::shared_ptr<stub> 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) {}
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;
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
stub(con_msg_man_ptr manager, websocketpp::frame::opcode::value op, size_t size = 128)
: m_opcode(op)
, m_manager(manager)
, m_size(size) {}
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;
bool recycle() {
con_msg_man_ptr shared = m_manager.lock();
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;
};
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;
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);
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;
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);
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);
}
+28 -28
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE message
@@ -35,38 +35,38 @@
template <typename message>
struct stub {
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
typedef websocketpp::lib::shared_ptr<stub> ptr;
stub() : recycled(false) {}
typedef websocketpp::lib::weak_ptr<stub> weak_ptr;
typedef websocketpp::lib::shared_ptr<stub> ptr;
bool recycle(message * msg) {
this->recycled = true;
return false;
}
stub() : recycled(false) {}
bool recycled;
bool recycle(message *) {
this->recycled = true;
return false;
}
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));
BOOST_CHECK(msg->get_payload().capacity() >= 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_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);
}
+36 -36
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_00_processor
@@ -40,37 +40,37 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
websocketpp::http::parser::request r;
websocketpp::http::parser::response response;
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
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";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
BOOST_CHECK(p.validate_handshake(r));
websocketpp::uri_ptr u;
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);
BOOST_CHECK(u->get_secure() == false);
BOOST_CHECK(u->get_host() == "www.example.com");
BOOST_CHECK(u->get_resource() == "/");
BOOST_CHECK(u->get_port() == websocketpp::URI_DEFAULT_PORT);
p.process_handshake(r,response);
BOOST_CHECK(response.get_header("Connection") == "Upgrade");
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
BOOST_CHECK(response.get_header("Sec-WebSocket-Origin") == "http://example.com");
BOOST_CHECK(response.get_header("Sec-WebSocket-Location") == "ws://www.example.com/");
BOOST_CHECK(response.get_header("Sec-WebSocket-Key3") == "n`9eBk9z$R8pOtVb");
}
@@ -78,12 +78,12 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
BOOST_AUTO_TEST_CASE( non_get_method ) {
websocketpp::http::parser::request r;
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
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";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
BOOST_CHECK(!p.validate_handshake(r));
@@ -92,12 +92,12 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
BOOST_AUTO_TEST_CASE( old_http_version ) {
websocketpp::http::parser::request r;
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
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";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
BOOST_CHECK(!p.validate_handshake(r));
@@ -106,12 +106,12 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
websocketpp::http::parser::request r;
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
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";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
BOOST_CHECK(!p.validate_handshake(r));
@@ -120,12 +120,12 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
websocketpp::http::parser::request r;
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
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";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
BOOST_CHECK(!p.validate_handshake(r));
@@ -136,21 +136,21 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
websocketpp::uri_ptr u;
bool exception = false;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
r.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
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);
}
}
+4 -4
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','regex','system'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system'],env) + [platform_libs] + ['z']
objs = env.Object('test_processor_boost.o', ["processor.cpp"], LIBS = BOOST_LIBS)
objs += env.Object('test_hybi13_boost.o', ["hybi13.cpp"], LIBS = BOOST_LIBS)
@@ -27,8 +27,8 @@ prgs += env.Program('test_hybi00_boost', ["test_hybi00_boost.o"], LIBS = BOOST_L
prgs += env.Program('test_extension_permessage_compress_boost', ["test_extension_permessage_compress_boost.o"], LIBS = BOOST_LIBS + ['z'])
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
# no C++11 features are used in processor so there are no C++11 versions of
BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
# no C++11 features are used in processor so there are no C++11 versions of
# these tests.
objs += env_cpp11.Object('test_processor_stl.o', ["processor.cpp"], LIBS = BOOST_LIBS_CPP11)
objs += env_cpp11.Object('test_hybi13_stl.o', ["hybi13.cpp"], LIBS = BOOST_LIBS_CPP11)
@@ -36,7 +36,7 @@ if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
objs += env_cpp11.Object('test_hybi07_stl.o', ["hybi07.cpp"], LIBS = BOOST_LIBS_CPP11)
objs += env_cpp11.Object('test_hybi00_stl.o', ["hybi00.cpp"], LIBS = BOOST_LIBS_CPP11)
objs += env_cpp11.Object('test_extension_permessage_compress_stl.o', ["extension_permessage_compress.cpp"], LIBS = BOOST_LIBS_CPP11 + ['z'])
prgs += env_cpp11.Program('test_processor_stl', ["test_processor_stl.o"], LIBS = BOOST_LIBS_CPP11)
prgs += env_cpp11.Program('test_hybi13_stl', ["test_hybi13_stl.o"], LIBS = BOOST_LIBS_CPP11)
prgs += env_cpp11.Program('test_hybi08_stl', ["test_hybi08_stl.o"], LIBS = BOOST_LIBS_CPP11)
@@ -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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE extension_permessage_deflate
@@ -38,7 +38,7 @@
struct config {
typedef websocketpp::http::parser::request request_type;
};
typedef websocketpp::extensions::permessage_deflate::enabled<config>
typedef websocketpp::extensions::permessage_deflate::enabled<config>
compressor_type;
using namespace websocketpp;
@@ -50,23 +50,23 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
neg_ret = compressor.negotiate(attributes);
BOOST_CHECK_EQUAL( neg_ret.first,
BOOST_CHECK_EQUAL( neg_ret.first,
extensions::permessage_deflate::error::invalid_parameters );*/
/**
* Window size is primarily controlled by the writer. A stream can only be
* read by a window size equal to or greater than the one use to compress
* it initially. The default windows size is also the maximum window size.
* it initially. The default windows size is also the maximum window size.
* Thus:
*
* Outbound window size can be limited unilaterally under the assumption
* that the opposite end will be using the default (maximum size which can
* read anything)
*
* Inbound window size must be limited by asking the remote endpoint to
* Inbound window size must be limited by asking the remote endpoint to
* do so and it agreeing.
*
* Context takeover is also primarily controlled by the writer. If the
*
* Context takeover is also primarily controlled by the writer. If the
* compressor does not clear its context between messages then the reader
* can't either.
*
@@ -81,17 +81,17 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
* - whether or not to request that the server disallow context takeover
*
* Server must answer in the following ways
* - If client requested a window size limit, is the window size limit
* - If client requested a window size limit, is the window size limit
* acceptable?
* - If client allows window limit requests, should we send one?
* - If client requested no context takeover, should we accept?
*
*
*
*
*
*
* All Defaults
* Req: permessage-compress; method=deflate
* Ans: permessage-compress; method=deflate
*
*
* # Client wants to limit the size of inbound windows from server
* permessage-compress; method="deflate; s2c_max_window_bits=8, deflate"
* Ans: permessage-compress; method="deflate; s2c_max_window_bits=8"
@@ -99,13 +99,13 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
* Ans: permessage-compress; method=deflate
*
* # Server wants to limit the size of inbound windows from client
* Client:
* Client:
* permessage-compress; method="deflate; c2s_max_window_bits, deflate"
*
*
* Server:
* permessage-compress; method="deflate; c2s_max_window_bits=8"
*
* # Client wants to
*
* # Client wants to
*
*
*
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
*
*
*/
@@ -144,30 +144,30 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
attributes.push_back(http::parser::attribute("s2c_max_window_bits","9"));
ec = d.init(attributes);
BOOST_CHECK( !ec);
attributes.clear();
ec = d.init(attributes);
BOOST_CHECK( !ec);
processor::extensions::deflate_engine de;
unsigned char test_in[] = "HelloHelloHelloHello";
unsigned char test_out[30];
uLongf test_out_size = 30;
int ret;
ret = compress(test_out, &test_out_size, test_in, 20);
ret = compress(test_out, &test_out_size, test_in, 20);
std::cout << ret << std::endl
<< websocketpp::utility::to_hex(test_in,20) << std::endl
<< websocketpp::utility::to_hex(test_out,test_out_size) << std::endl;
std::string input = "Hello";
std::string output = "";
ec = de.compress(input,output);
BOOST_CHECK( ec == processor::extensions::error::uninitialized );
//std::cout << ec.message() << websocketpp::utility::to_hex(output) << std::endl;
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE( deflate_init ) {
std::cout << ec.message() << std::endl
<< websocketpp::utility::to_hex(input) << std::endl
<< websocketpp::utility::to_hex(output) << std::endl;
output = "";
ec = de.compress(input,output);
+62 -60
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_00_processor
@@ -38,167 +38,169 @@
#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;
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 {
processor_setup(bool server)
processor_setup(bool server)
: msg_manager(new stub_config::con_msg_manager_type())
, 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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
env.ec = env.p.validate_handshake(env.req);
BOOST_CHECK(!env.ec);
websocketpp::uri_ptr u;
BOOST_CHECK_NO_THROW( u = env.p.get_uri(env.req) );
BOOST_CHECK_EQUAL(u->get_secure(), false);
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
BOOST_CHECK_EQUAL(u->get_resource(), "/");
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::URI_DEFAULT_PORT);
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
env.p.process_handshake(env.req,"",env.res);
BOOST_CHECK_EQUAL(env.res.get_header("Connection"), "Upgrade");
BOOST_CHECK_EQUAL(env.res.get_header("Upgrade"), "WebSocket");
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Origin"), "http://example.com");
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Location"), "ws://www.example.com/");
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Key3"), "n`9eBk9z$R8pOtVb");
}
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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_http_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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
}
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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
}
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";
env.req.consume(handshake.c_str(),handshake.size());
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK( !env.p.validate_handshake(env.req) );
BOOST_CHECK_THROW( u = env.p.get_uri(env.req), websocketpp::uri_exception );
BOOST_CHECK( !env.p.get_uri(env.req)->get_valid() );
}
BOOST_AUTO_TEST_CASE( extract_subprotocols ) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
BOOST_CHECK_EQUAL( subps.size(), 0 );
}
BOOST_AUTO_TEST_CASE( prepare_data_frame_null ) {
processor_setup env(true);
message_ptr in = env.msg_manager->get_message();
message_ptr out = env.msg_manager->get_message();
message_ptr invalid;
// empty pointers arguements should return sane error
// empty pointers arguements should return sane error
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,invalid), websocketpp::processor::error::invalid_arguments );
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(in,invalid), websocketpp::processor::error::invalid_arguments );
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,out), websocketpp::processor::error::invalid_arguments );
// test valid opcodes
// text (1) should be the only valid opcode
for (int i = 0; i < 0xF; i++) {
in->set_opcode(websocketpp::frame::opcode::value(i));
env.ec = env.p.prepare_data_frame(in,out);
if (i != 1) {
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
} else {
BOOST_CHECK_NE( env.ec, websocketpp::processor::error::invalid_opcode );
}
}
/*
* TODO: tests for invalid UTF8
char buf[2] = {0x00, 0x00};
@@ -213,15 +215,15 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame_null ) {
BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
processor_setup env(true);
message_ptr in = env.msg_manager->get_message();
message_ptr out = env.msg_manager->get_message();
in->set_opcode(websocketpp::frame::opcode::text);
in->set_payload("foo");
env.ec = env.p.prepare_data_frame(in,out);
unsigned char raw_header[1] = {0x00};
unsigned char raw_payload[4] = {0x66,0x6f,0x6f,0xff};
+69 -80
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_07_processor
@@ -40,21 +40,23 @@
#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;
static const size_t max_message_size = 16000000;
/// Extension related config
static const bool enable_extensions = false;
/// Extension specific config
/// permessage_compress_config
struct permessage_deflate_config {
typedef stub_config::request_type request_type;
@@ -65,56 +67,51 @@ 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;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
BOOST_CHECK(!ec);
websocketpp::uri_ptr u;
bool exception = false;
try {
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
}
BOOST_CHECK(exception == false);
BOOST_CHECK(u->get_secure() == false);
BOOST_CHECK(u->get_host() == "www.example.com");
BOOST_CHECK(u->get_resource() == "/");
BOOST_CHECK(u->get_port() == websocketpp::uri_default_port);
u = p.get_uri(r);
BOOST_CHECK(u->get_valid());
BOOST_CHECK(!u->get_secure());
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
BOOST_CHECK_EQUAL(u->get_resource(), "/");
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
p.process_handshake(r,"",response);
BOOST_CHECK(response.get_header("Connection") == "upgrade");
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
BOOST_CHECK_EQUAL(response.get_header("Connection"), "upgrade");
BOOST_CHECK_EQUAL(response.get_header("Upgrade"), "websocket");
BOOST_CHECK_EQUAL(response.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
}
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;
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -122,17 +119,17 @@ 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;
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -140,17 +137,17 @@ 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;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -158,17 +155,17 @@ 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;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -176,29 +173,21 @@ 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::uri_ptr u;
bool exception = false;
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
BOOST_CHECK( !ec );
try {
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
}
BOOST_CHECK(exception == true);
BOOST_CHECK( !p.get_uri(r)->get_valid() );
}
+61 -69
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_08_processor
@@ -40,21 +40,23 @@
#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;
static const size_t max_message_size = 16000000;
/// Extension related config
static const bool enable_extensions = false;
/// Extension specific config
/// permessage_deflate_config
struct permessage_deflate_config {
typedef stub_config::request_type request_type;
@@ -65,56 +67,51 @@ 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::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
BOOST_CHECK(!ec);
websocketpp::uri_ptr u;
bool exception = false;
try {
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
}
BOOST_CHECK(exception == false);
u = p.get_uri(r);
BOOST_CHECK(u->get_valid() == true);
BOOST_CHECK(u->get_secure() == false);
BOOST_CHECK(u->get_host() == "www.example.com");
BOOST_CHECK(u->get_resource() == "/");
BOOST_CHECK(u->get_port() == websocketpp::uri_default_port);
p.process_handshake(r,"",response);
BOOST_CHECK(response.get_header("Connection") == "upgrade");
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
}
BOOST_AUTO_TEST_CASE( non_get_method ) {
stub_config::request_type r;
stub_config::request_type r;
stub_config::response_type response;
stub_config::rng_type rng;
stub_config::con_msg_manager_type::ptr msg_manager;
stub_config::con_msg_manager_type::ptr msg_manager;
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -122,17 +119,17 @@ 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::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -140,17 +137,17 @@ 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::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -158,17 +155,17 @@ 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::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
@@ -176,30 +173,25 @@ 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::hybi08<stub_config> p(false,true,msg_manager,rng);
websocketpp::uri_ptr u;
bool exception = false;
websocketpp::lib::error_code ec;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
ec = p.validate_handshake(r);
BOOST_CHECK( !ec );
try {
u = p.get_uri(r);
} catch (const websocketpp::uri_exception& e) {
exception = true;
}
BOOST_CHECK(exception == true);
u = p.get_uri(r);
BOOST_CHECK( !u->get_valid() );
}
+291 -260
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_13_processor
@@ -43,16 +43,16 @@
#include <websocketpp/extensions/permessage_deflate/enabled.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;
struct permessage_deflate_config {
typedef stub_config::request_type request_type;
};
@@ -60,27 +60,29 @@ struct stub_config {
typedef websocketpp::extensions::permessage_deflate::disabled
<permessage_deflate_config> permessage_deflate_type;
static const size_t max_message_size = 16000000;
static const bool enable_extensions = false;
};
struct stub_config_ext {
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;
struct permessage_deflate_config {
typedef stub_config_ext::request_type request_type;
};
typedef websocketpp::extensions::permessage_deflate::enabled
<permessage_deflate_config> permessage_deflate_type;
static const size_t max_message_size = 16000000;
static const bool enable_extensions = true;
};
@@ -90,89 +92,89 @@ typedef stub_config::message_type::ptr message_ptr;
// Set up a structure that constructs new copies of all of the support structure
// for using connection processors
struct processor_setup {
processor_setup(bool server)
processor_setup(bool server)
: msg_manager(new con_msg_manager_type())
, p(false,server,msg_manager,rng) {}
websocketpp::lib::error_code ec;
con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::request_type req;
con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::request_type req;
stub_config::response_type res;
websocketpp::processor::hybi13<stub_config> p;
websocketpp::processor::hybi13<stub_config> p;
};
struct processor_setup_ext {
processor_setup_ext(bool server)
processor_setup_ext(bool server)
: msg_manager(new con_msg_manager_type())
, p(false,server,msg_manager,rng) {}
websocketpp::lib::error_code ec;
con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::request_type req;
con_msg_manager_type::ptr msg_manager;
stub_config::rng_type rng;
stub_config::request_type req;
stub_config::response_type res;
websocketpp::processor::hybi13<stub_config_ext> p;
websocketpp::processor::hybi13<stub_config_ext> p;
};
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\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK(!env.p.validate_handshake(env.req));
websocketpp::uri_ptr u;
BOOST_CHECK_NO_THROW( u = env.p.get_uri(env.req) );
BOOST_CHECK_EQUAL(u->get_secure(), false);
BOOST_CHECK_EQUAL(u->get_host(), "www.example.com");
BOOST_CHECK_EQUAL(u->get_resource(), "/");
BOOST_CHECK_EQUAL(u->get_port(), websocketpp::uri_default_port);
env.p.process_handshake(env.req,"",env.res);
BOOST_CHECK_EQUAL(env.res.get_header("Connection"), "upgrade");
BOOST_CHECK_EQUAL(env.res.get_header("Upgrade"), "websocket");
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
}
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-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK( env.p.validate_handshake(env.req) == websocketpp::processor::error::invalid_http_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-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::invalid_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-Version: 13\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
@@ -180,27 +182,27 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
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-Version: 13\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
BOOST_CHECK_EQUAL( env.p.validate_handshake(env.req), websocketpp::processor::error::missing_required_header );
}
BOOST_AUTO_TEST_CASE( bad_host ) {
processor_setup env(true);
processor_setup env(true);
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
env.req.consume(handshake.c_str(),handshake.size());
BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
BOOST_CHECK( !env.p.validate_handshake(env.req) );
BOOST_CHECK_THROW( env.p.get_uri(env.req), websocketpp::uri_exception );
BOOST_CHECK( !env.p.validate_handshake(env.req) );
BOOST_CHECK( !env.p.get_uri(env.req)->get_valid() );
}
// FRAME TESTS TO DO
@@ -218,249 +220,249 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
// 0x81 0x80
BOOST_AUTO_TEST_CASE( frame_empty_binary_unmasked ) {
uint8_t frame[2] = {0x82, 0x00};
uint8_t frame[2] = {0x82, 0x00};
// all in one chunk
processor_setup env1(false);
// all in one chunk
processor_setup env1(false);
size_t ret1 = env1.p.consume(frame,2,env1.ec);
BOOST_CHECK_EQUAL( ret1, 2 );
BOOST_CHECK( !env1.ec );
BOOST_CHECK_EQUAL( env1.p.ready(), true );
// two separate chunks
processor_setup env2(false);
size_t ret1 = env1.p.consume(frame,2,env1.ec);
BOOST_CHECK_EQUAL( env2.p.consume(frame,1,env2.ec), 1 );
BOOST_CHECK( !env2.ec );
BOOST_CHECK_EQUAL( env2.p.ready(), false );
BOOST_CHECK_EQUAL( ret1, 2 );
BOOST_CHECK( !env1.ec );
BOOST_CHECK_EQUAL( env1.p.ready(), true );
BOOST_CHECK_EQUAL( env2.p.consume(frame+1,1,env2.ec), 1 );
BOOST_CHECK( !env2.ec );
BOOST_CHECK_EQUAL( env2.p.ready(), true );
// two separate chunks
processor_setup env2(false);
BOOST_CHECK_EQUAL( env2.p.consume(frame,1,env2.ec), 1 );
BOOST_CHECK( !env2.ec );
BOOST_CHECK_EQUAL( env2.p.ready(), false );
BOOST_CHECK_EQUAL( env2.p.consume(frame+1,1,env2.ec), 1 );
BOOST_CHECK( !env2.ec );
BOOST_CHECK_EQUAL( env2.p.ready(), true );
}
BOOST_AUTO_TEST_CASE( frame_small_binary_unmasked ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[4] = {0x82, 0x02, 0x2A, 0x2A};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,4,env.ec), 4 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
message_ptr foo = env.p.get_message();
uint8_t frame[4] = {0x82, 0x02, 0x2A, 0x2A};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload(), "**" );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,4,env.ec), 4 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
message_ptr foo = env.p.get_message();
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload(), "**" );
}
BOOST_AUTO_TEST_CASE( frame_extended_binary_unmasked ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
frame[0] = 0x82;
frame[1] = 0x7E;
frame[2] = 0x00;
frame[3] = 0x7E;
std::fill_n(frame+4,126,0x2A);
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
frame[0] = 0x82;
frame[1] = 0x7E;
frame[2] = 0x00;
frame[3] = 0x7E;
std::fill_n(frame+4,126,0x2A);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
message_ptr foo = env.p.get_message();
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
message_ptr foo = env.p.get_message();
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
}
BOOST_AUTO_TEST_CASE( frame_jumbo_binary_unmasked ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
std::fill_n(frame+4,126,0x2A);
uint8_t frame[130] = {0x82, 0x7E, 0x00, 0x7E};
std::fill_n(frame+4,126,0x2A);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
message_ptr foo = env.p.get_message();
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,130,env.ec), 130 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
message_ptr foo = env.p.get_message();
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( foo->get_payload().size(), 126 );
}
BOOST_AUTO_TEST_CASE( control_frame_too_large ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[130] = {0x88, 0x7E, 0x00, 0x7E};
std::fill_n(frame+4,126,0x2A);
uint8_t frame[130] = {0x88, 0x7E, 0x00, 0x7E};
std::fill_n(frame+4,126,0x2A);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,130,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::control_too_big );
BOOST_CHECK_EQUAL( env.p.ready(), false );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,130,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::control_too_big );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
BOOST_AUTO_TEST_CASE( rsv_bits_used ) {
uint8_t frame[3][2] = {{0x90, 0x00},
{0xA0, 0x00},
{0xC0, 0x00}};
uint8_t frame[3][2] = {{0x90, 0x00},
{0xA0, 0x00},
{0xC0, 0x00}};
for (int i = 0; i < 3; i++) {
processor_setup env(false);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_rsv_bit );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
for (int i = 0; i < 3; i++) {
processor_setup env(false);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_rsv_bit );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
}
BOOST_AUTO_TEST_CASE( reserved_opcode_used ) {
uint8_t frame[10][2] = {{0x83, 0x00},
{0x84, 0x00},
{0x85, 0x00},
{0x86, 0x00},
{0x87, 0x00},
{0x8B, 0x00},
{0x8C, 0x00},
{0x8D, 0x00},
{0x8E, 0x00},
{0x8F, 0x00}};
uint8_t frame[10][2] = {{0x83, 0x00},
{0x84, 0x00},
{0x85, 0x00},
{0x86, 0x00},
{0x87, 0x00},
{0x8B, 0x00},
{0x8C, 0x00},
{0x8D, 0x00},
{0x8E, 0x00},
{0x8F, 0x00}};
for (int i = 0; i < 10; i++) {
processor_setup env(false);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
for (int i = 0; i < 10; i++) {
processor_setup env(false);
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame[i],2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
}
BOOST_AUTO_TEST_CASE( fragmented_control_message ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[2] = {0x08, 0x00};
uint8_t frame[2] = {0x08, 0x00};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::fragmented_control );
BOOST_CHECK_EQUAL( env.p.ready(), false );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::fragmented_control );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
BOOST_AUTO_TEST_CASE( fragmented_binary_message ) {
processor_setup env0(false);
processor_setup env1(false);
processor_setup env0(false);
processor_setup env1(false);
uint8_t frame0[6] = {0x02, 0x01, 0x2A, 0x80, 0x01, 0x2A};
uint8_t frame1[8] = {0x02, 0x01, 0x2A, 0x89, 0x00, 0x80, 0x01, 0x2A};
uint8_t frame0[6] = {0x02, 0x01, 0x2A, 0x80, 0x01, 0x2A};
uint8_t frame1[8] = {0x02, 0x01, 0x2A, 0x89, 0x00, 0x80, 0x01, 0x2A};
// read fragmented message in one chunk
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame0,6,env0.ec), 6 );
// read fragmented message in one chunk
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame0,6,env0.ec), 6 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
// read fragmented message in two chunks
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame0,3,env0.ec), 3 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), false );
BOOST_CHECK_EQUAL( env0.p.consume(frame0+3,3,env0.ec), 3 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
// read fragmented message with control message in between
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame1,8,env0.ec), 5 );
// read fragmented message in two chunks
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame0,3,env0.ec), 3 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_opcode(), websocketpp::frame::opcode::PING);
BOOST_CHECK_EQUAL( env0.p.consume(frame1+5,3,env0.ec), 3 );
BOOST_CHECK_EQUAL( env0.p.ready(), false );
BOOST_CHECK_EQUAL( env0.p.consume(frame0+3,3,env0.ec), 3 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
// read fragmented message with control message in between
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env0.p.consume(frame1,8,env0.ec), 5 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_opcode(), websocketpp::frame::opcode::PING);
BOOST_CHECK_EQUAL( env0.p.consume(frame1+5,3,env0.ec), 3 );
BOOST_CHECK( !env0.ec );
BOOST_CHECK_EQUAL( env0.p.ready(), true );
BOOST_CHECK_EQUAL( env0.p.get_message()->get_payload(), "**" );
// read lone continuation frame
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env0.p.consume(frame0+3,3,env0.ec), 0);
BOOST_CHECK_EQUAL( env0.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env0.p.consume(frame0+3,3,env0.ec), 0);
BOOST_CHECK_EQUAL( env0.ec, websocketpp::processor::error::invalid_continuation );
// read two start frames in a row
BOOST_CHECK_EQUAL( env1.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env1.p.consume(frame0,3,env1.ec), 3);
BOOST_CHECK_EQUAL( env1.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env1.p.consume(frame0,3,env1.ec), 3);
BOOST_CHECK( !env1.ec );
BOOST_CHECK_GT( env1.p.consume(frame0,3,env1.ec), 0);
BOOST_CHECK_GT( env1.p.consume(frame0,3,env1.ec), 0);
BOOST_CHECK_EQUAL( env1.ec, websocketpp::processor::error::invalid_continuation );
}
BOOST_AUTO_TEST_CASE( unmasked_client_frame ) {
processor_setup env(true);
processor_setup env(true);
uint8_t frame[2] = {0x82, 0x00};
uint8_t frame[2] = {0x82, 0x00};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_required );
BOOST_CHECK_EQUAL( env.p.ready(), false );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,2,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_required );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
BOOST_AUTO_TEST_CASE( masked_server_frame ) {
processor_setup env(false);
processor_setup env(false);
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,8,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_forbidden );
BOOST_CHECK_EQUAL( env.p.ready(), false );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_GT( env.p.consume(frame,8,env.ec), 0 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::masking_forbidden );
BOOST_CHECK_EQUAL( env.p.ready(), false );
}
BOOST_AUTO_TEST_CASE( frame_small_binary_masked ) {
processor_setup env(true);
processor_setup env(true);
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
uint8_t frame[8] = {0x82, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xD5};
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,8,env.ec), 8 );
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame,8,env.ec), 8 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
}
BOOST_AUTO_TEST_CASE( masked_fragmented_binary_message ) {
processor_setup env(true);
uint8_t frame0[14] = {0x02, 0x81, 0xAB, 0x23, 0x98, 0x45, 0x81,
0x80, 0x81, 0xB8, 0x34, 0x12, 0xFF, 0x92};
uint8_t frame0[14] = {0x02, 0x81, 0xAB, 0x23, 0x98, 0x45, 0x81,
0x80, 0x81, 0xB8, 0x34, 0x12, 0xFF, 0x92};
// read fragmented message in one chunk
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame0,14,env.ec), 14 );
// read fragmented message in one chunk
BOOST_CHECK_EQUAL( env.p.get_message(), message_ptr() );
BOOST_CHECK_EQUAL( env.p.consume(frame0,14,env.ec), 14 );
BOOST_CHECK( !env.ec );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
BOOST_CHECK_EQUAL( env.p.ready(), true );
BOOST_CHECK_EQUAL( env.p.get_message()->get_payload(), "**" );
}
BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
processor_setup env(true);
processor_setup env(true);
message_ptr in = env.msg_manager->get_message();
message_ptr out = env.msg_manager->get_message();
message_ptr invalid;
// empty pointers arguements should return sane error
// empty pointers arguements should return sane error
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(invalid,invalid), websocketpp::processor::error::invalid_arguments );
BOOST_CHECK_EQUAL( env.p.prepare_data_frame(in,invalid), websocketpp::processor::error::invalid_arguments );
@@ -471,43 +473,73 @@ BOOST_AUTO_TEST_CASE( prepare_data_frame ) {
// control opcodes should return an error, data ones shouldn't
for (int i = 0; i < 0xF; i++) {
in->set_opcode(websocketpp::frame::opcode::value(i));
env.ec = env.p.prepare_data_frame(in,out);
if (websocketpp::frame::opcode::is_control(in->get_opcode())) {
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::invalid_opcode );
} else {
BOOST_CHECK_NE( env.ec, websocketpp::processor::error::invalid_opcode );
}
}
//in.set_payload("foo");
//e = prepare_data_frame(in,out);
}
BOOST_AUTO_TEST_CASE( single_frame_message_too_large ) {
processor_setup env(true);
env.p.set_max_message_size(3);
uint8_t frame0[10] = {0x82, 0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01};
// read message that is one byte too large
BOOST_CHECK_EQUAL( env.p.consume(frame0,10,env.ec), 6 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
}
BOOST_AUTO_TEST_CASE( multiple_frame_message_too_large ) {
processor_setup env(true);
env.p.set_max_message_size(4);
uint8_t frame0[8] = {0x02, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01};
uint8_t frame1[9] = {0x80, 0x83, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
// read first message frame with size under the limit
BOOST_CHECK_EQUAL( env.p.consume(frame0,8,env.ec), 8 );
BOOST_CHECK( !env.ec );
// read second message frame that puts the size over the limit
BOOST_CHECK_EQUAL( env.p.consume(frame1,9,env.ec), 6 );
BOOST_CHECK_EQUAL( env.ec, websocketpp::processor::error::message_too_big );
}
BOOST_AUTO_TEST_CASE( client_handshake_request ) {
processor_setup env(false);
websocketpp::uri_ptr u(new websocketpp::uri("ws://localhost/"));
env.p.client_handshake_request(env.req,u, std::vector<std::string>());
BOOST_CHECK_EQUAL( env.req.get_method(), "GET" );
BOOST_CHECK_EQUAL( env.req.get_version(), "HTTP/1.1");
BOOST_CHECK_EQUAL( env.req.get_uri(), "/");
BOOST_CHECK_EQUAL( env.req.get_header("Host"), "localhost");
BOOST_CHECK_EQUAL( env.req.get_header("Sec-WebSocket-Version"), "13");
BOOST_CHECK_EQUAL( env.req.get_header("Connection"), "Upgrade");
BOOST_CHECK_EQUAL( env.req.get_header("Upgrade"), "websocket");
}
// TODO:
// TODO:
// test cases
// - adding headers
// - adding Upgrade header
@@ -524,48 +556,48 @@ BOOST_AUTO_TEST_CASE( client_handshake_request ) {
BOOST_AUTO_TEST_CASE( client_handshake_response_404 ) {
processor_setup env(false);
std::string res = "HTTP/1.1 404 Not Found\r\n\r\n";
env.res.consume(res.data(),res.size());
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::invalid_http_status );
}
BOOST_AUTO_TEST_CASE( client_handshake_response_no_upgrade ) {
processor_setup env(false);
std::string res = "HTTP/1.1 101 Switching Protocols\r\n\r\n";
env.res.consume(res.data(),res.size());
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
}
BOOST_AUTO_TEST_CASE( client_handshake_response_no_connection ) {
processor_setup env(false);
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\n\r\n";
env.res.consume(res.data(),res.size());
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
}
BOOST_AUTO_TEST_CASE( client_handshake_response_no_accept ) {
processor_setup env(false);
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\n\r\n";
env.res.consume(res.data(),res.size());
BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
}
BOOST_AUTO_TEST_CASE( client_handshake_response ) {
processor_setup env(false);
env.req.append_header("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
env.res.consume(res.data(),res.size());
BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) );
}
@@ -576,7 +608,7 @@ BOOST_AUTO_TEST_CASE( extensions_disabled ) {
std::pair<websocketpp::lib::error_code,std::string> neg_results;
neg_results = env.p.negotiate_extensions(env.req);
BOOST_CHECK_EQUAL( neg_results.first, websocketpp::processor::error::extensions_disabled );
BOOST_CHECK_EQUAL( neg_results.second, "" );
}
@@ -588,7 +620,7 @@ BOOST_AUTO_TEST_CASE( extension_negotiation_blank ) {
std::pair<websocketpp::lib::error_code,std::string> neg_results;
neg_results = env.p.negotiate_extensions(env.req);
BOOST_CHECK( !neg_results.first );
BOOST_CHECK_EQUAL( neg_results.second, "" );
}
@@ -600,36 +632,36 @@ BOOST_AUTO_TEST_CASE( extension_negotiation_unknown ) {
std::pair<websocketpp::lib::error_code,std::string> neg_results;
neg_results = env.p.negotiate_extensions(env.req);
BOOST_CHECK( !neg_results.first );
BOOST_CHECK_EQUAL( neg_results.second, "" );
}
BOOST_AUTO_TEST_CASE( extract_subprotocols_empty ) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
BOOST_CHECK_EQUAL( subps.size(), 0 );
}
BOOST_AUTO_TEST_CASE( extract_subprotocols_one ) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
env.req.replace_header("Sec-WebSocket-Protocol","foo");
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
BOOST_REQUIRE_EQUAL( subps.size(), 1 );
BOOST_CHECK_EQUAL( subps[0], "foo" );
}
BOOST_AUTO_TEST_CASE( extract_subprotocols_multiple ) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
env.req.replace_header("Sec-WebSocket-Protocol","foo,bar");
BOOST_CHECK( !env.p.extract_subprotocols(env.req,subps) );
BOOST_REQUIRE_EQUAL( subps.size(), 2 );
BOOST_CHECK_EQUAL( subps[0], "foo" );
@@ -637,26 +669,25 @@ BOOST_AUTO_TEST_CASE( extract_subprotocols_multiple ) {
}
BOOST_AUTO_TEST_CASE( extract_subprotocols_invalid) {
processor_setup env(true);
processor_setup env(true);
std::vector<std::string> subps;
env.req.replace_header("Sec-WebSocket-Protocol","foo,bar,,,,");
BOOST_CHECK_EQUAL( env.p.extract_subprotocols(env.req,subps), websocketpp::processor::error::make_error_code(websocketpp::processor::error::subprotocol_parse_error) );
BOOST_CHECK_EQUAL( subps.size(), 0 );
}
/*BOOST_AUTO_TEST_CASE( extension_negotiation_permessage_deflate ) {
BOOST_AUTO_TEST_CASE( extension_negotiation_permessage_deflate ) {
processor_setup_ext env(true);
env.req.replace_header("Sec-WebSocket-Extensions","permessage-deflate; foo; bar=\"x x\"");
env.req.replace_header("Sec-WebSocket-Extensions",
"permessage-deflate; c2s_max_window_bits");
std::pair<websocketpp::lib::error_code,std::string> neg_results;
neg_results = env.p.negotiate_extensions(env.req);
std::cout << neg_results.first.message() << neg_results.second << std::endl;
BOOST_CHECK( !neg_results.first );
BOOST_CHECK_EQUAL( neg_results.second, "permessage-deflate" );
}*/
}
+35 -35
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE processors
@@ -36,100 +36,100 @@
BOOST_AUTO_TEST_CASE( exact_match ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
}
BOOST_AUTO_TEST_CASE( non_match ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(!websocketpp::processor::is_websocket_handshake(r));
}
BOOST_AUTO_TEST_CASE( ci_exact_match ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: UpGrAde\r\nUpgrade: WebSocket\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
}
BOOST_AUTO_TEST_CASE( non_exact_match1 ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade,foo\r\nUpgrade: websocket,foo\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
}
BOOST_AUTO_TEST_CASE( non_exact_match2 ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: keep-alive,Upgrade,foo\r\nUpgrade: foo,websocket,bar\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
}
BOOST_AUTO_TEST_CASE( version_blank ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 0);
}
BOOST_AUTO_TEST_CASE( version_7 ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 7);
}
BOOST_AUTO_TEST_CASE( version_8 ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 8);
}
BOOST_AUTO_TEST_CASE( version_13 ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 13);
}
BOOST_AUTO_TEST_CASE( version_non_numeric ) {
websocketpp::http::parser::request r;
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: abc\r\n\r\n";
r.consume(handshake.c_str(),handshake.size());
BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
}
+1 -1
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','random'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','random','system'],env) + [platform_libs]
objs = env.Object('random_none_boost.o', ["none.cpp"], LIBS = BOOST_LIBS)
objs += env.Object('random_device_boost.o', ["random_device.cpp"], LIBS = BOOST_LIBS)
+9 -9
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE random_none
@@ -33,8 +33,8 @@
BOOST_AUTO_TEST_CASE( does_it_compile ) {
websocketpp::random::none::int_generator<int32_t> rng;
int32_t foo = rng();
BOOST_CHECK( foo == 0 );
}
}
+9 -9
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE random_device
@@ -36,15 +36,15 @@
BOOST_AUTO_TEST_CASE( compiles ) {
websocketpp::random::random_device::int_generator<int32_t,websocketpp::concurrency::none> rng;
bool e = false;
try {
int32_t foo = rng();
std::cout << foo << std::endl;
} catch (...) {
e = true;
}
BOOST_CHECK( e == false );
}
+1 -1
View File
@@ -10,7 +10,7 @@ Import('polyfill_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','system','regex','random'],env) + [platform_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system','random'],env) + [platform_libs]
objs = env.Object('client_boost.o', ["client.cpp"], LIBS = BOOST_LIBS)
objs += env.Object('server_boost.o', ["server.cpp"], LIBS = BOOST_LIBS)
+41 -41
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE client
@@ -52,11 +52,11 @@ struct stub_config : public websocketpp::config::core {
//typedef core::rng_type rng_type;
typedef websocketpp::random::random_device::int_generator<uint32_t,concurrency_type> rng_type;
typedef core::transport_type transport_type;
typedef core::endpoint_base endpoint_base;
static const websocketpp::log::level elog_level = websocketpp::log::elevel::none;
static const websocketpp::log::level alog_level = websocketpp::log::alevel::none;
};
@@ -67,27 +67,27 @@ typedef client::connection_ptr connection_ptr;
BOOST_AUTO_TEST_CASE( invalid_uri ) {
client c;
websocketpp::lib::error_code ec;
connection_ptr con = c.get_connection("foo", ec);
BOOST_CHECK_EQUAL( ec , websocketpp::error::make_error_code(websocketpp::error::invalid_uri) );
}
BOOST_AUTO_TEST_CASE( unsecure_endpoint ) {
client c;
websocketpp::lib::error_code ec;
connection_ptr con = c.get_connection("wss://localhost/", ec);
BOOST_CHECK_EQUAL( ec , websocketpp::error::make_error_code(websocketpp::error::endpoint_not_secure) );
}
BOOST_AUTO_TEST_CASE( get_connection ) {
client c;
websocketpp::lib::error_code ec;
connection_ptr con = c.get_connection("ws://localhost/", ec);
BOOST_CHECK( con );
BOOST_CHECK_EQUAL( con->get_host() , "localhost" );
BOOST_CHECK_EQUAL( con->get_port() , 80 );
@@ -100,69 +100,69 @@ BOOST_AUTO_TEST_CASE( connect_con ) {
websocketpp::lib::error_code ec;
std::stringstream out;
std::string o;
c.register_ostream(&out);
connection_ptr con = c.get_connection("ws://localhost/", ec);
c.connect(con);
o = out.str();
websocketpp::http::parser::request r;
r.consume(o.data(),o.size());
BOOST_CHECK( r.ready() );
BOOST_CHECK_EQUAL( r.get_method(), "GET");
BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1");
BOOST_CHECK_EQUAL( r.get_uri(), "/");
BOOST_CHECK_EQUAL( r.get_header("Host"), "localhost");
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Version"), "13");
BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade");
BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket");
// Key is randomly generated & User-Agent will change so just check that
// they are not empty.
BOOST_CHECK_NE( r.get_header("Sec-WebSocket-Key"), "");
BOOST_CHECK_NE( r.get_header("User-Agent"), "" );
// connection should have written out an opening handshake request and be in
// the read response internal state
// TODO: more tests related to reading the HTTP response
std::stringstream channel2;
channel2 << "e\r\n\r\n";
channel2 >> *con;
channel2 << "e\r\n\r\n";
channel2 >> *con;
}
BOOST_AUTO_TEST_CASE( select_subprotocol ) {
client c;
websocketpp::lib::error_code ec;
using websocketpp::error::make_error_code;
connection_ptr con = c.get_connection("ws://localhost/", ec);
BOOST_CHECK( con );
con->select_subprotocol("foo",ec);
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::server_only) );
BOOST_CHECK_THROW( con->select_subprotocol("foo") , websocketpp::lib::error_code );
BOOST_CHECK_THROW( con->select_subprotocol("foo") , websocketpp::exception );
}
BOOST_AUTO_TEST_CASE( add_subprotocols_invalid ) {
client c;
websocketpp::lib::error_code ec;
using websocketpp::error::make_error_code;
connection_ptr con = c.get_connection("ws://localhost/", ec);
BOOST_CHECK( con );
con->add_subprotocol("",ec);
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
BOOST_CHECK_THROW( con->add_subprotocol("") , websocketpp::lib::error_code );
BOOST_CHECK_THROW( con->add_subprotocol("") , websocketpp::exception );
con->add_subprotocol("foo,bar",ec);
BOOST_CHECK_EQUAL( ec , make_error_code(websocketpp::error::invalid_subprotocol) );
BOOST_CHECK_THROW( con->add_subprotocol("foo,bar") , websocketpp::lib::error_code );
BOOST_CHECK_THROW( con->add_subprotocol("foo,bar") , websocketpp::exception );
}
BOOST_AUTO_TEST_CASE( add_subprotocols ) {
@@ -170,23 +170,23 @@ BOOST_AUTO_TEST_CASE( add_subprotocols ) {
websocketpp::lib::error_code ec;
std::stringstream out;
std::string o;
c.register_ostream(&out);
connection_ptr con = c.get_connection("ws://localhost/", ec);
BOOST_CHECK( con );
con->add_subprotocol("foo",ec);
BOOST_CHECK( !ec );
BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") );
c.connect(con);
o = out.str();
websocketpp::http::parser::request r;
r.consume(o.data(),o.size());
BOOST_CHECK( r.ready() );
BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar");
}
+80 -80
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE server
@@ -56,9 +56,9 @@ using websocketpp::lib::bind;
typedef core::elog_type elog_type;
typedef core::rng_type rng_type;
typedef core::transport_type transport_type;
typedef core::endpoint_base endpoint_base;
};*/
@@ -66,20 +66,20 @@ using websocketpp::lib::bind;
std::string run_server_test(server& s, std::string input) {
server::connection_ptr con;
std::stringstream output;
s.register_ostream(&output);
s.clear_access_channels(websocketpp::log::alevel::all);
s.register_ostream(&output);
s.clear_access_channels(websocketpp::log::alevel::all);
s.clear_error_channels(websocketpp::log::elevel::all);
con = s.get_connection();
con->start();
std::stringstream channel;
channel << input;
channel >> *con;
return output.str();
con = s.get_connection();
con->start();
std::stringstream channel;
channel << input;
channel >> *con;
return output.str();
}
/* handler library*/
@@ -91,28 +91,28 @@ bool validate_func_subprotocol(server* s, std::string* out, std::string accept,
websocketpp::connection_hdl hdl)
{
server::connection_ptr con = s->get_con_from_hdl(hdl);
std::stringstream o;
const std::vector<std::string> & protocols = con->get_requested_subprotocols();
std::vector<std::string>::const_iterator it;
for (it = protocols.begin(); it != protocols.end(); ++it) {
o << *it << ",";
}
*out = o.str();
if (accept != "") {
con->select_subprotocol(accept);
}
return true;
}
void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_hdl hdl) {
server::connection_ptr con = s->get_con_from_hdl(hdl);
*out = con->get_subprotocol();
}
@@ -120,21 +120,21 @@ void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_
BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
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: test\r\nUpgrade: websocket\r\n\r\n";
server s;
s.set_user_agent("test");
server s;
s.set_user_agent("test");
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: a\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 400 Bad Request\r\nServer: test\r\n\r\n";
server s;
s.set_user_agent("test");
//s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
//s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
@@ -142,10 +142,10 @@ BOOST_AUTO_TEST_CASE( unimplemented_websocket_version ) {
std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 14\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
std::string output = "HTTP/1.1 400 Bad Request\r\nSec-WebSocket-Version: 0,7,8,13\r\nServer: test\r\n\r\n";
server s;
server s;
s.set_user_agent("test");
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
}
@@ -153,13 +153,13 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_empty ) {
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\nSec-WebSocket-Protocol: foo\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
std::string subprotocol;
server s;
std::string subprotocol;
server s;
s.set_user_agent("test");
s.set_open_handler(bind(&open_func_subprotocol,&s,&subprotocol,::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&subprotocol,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
BOOST_CHECK_EQUAL(subprotocol, "");
}
@@ -168,15 +168,15 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
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\nSec-WebSocket-Protocol: foo\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
std::string validate;
std::string open;
server s;
std::string validate;
std::string open;
server s;
s.set_user_agent("test");
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
BOOST_CHECK_EQUAL(validate, "foo,");
BOOST_CHECK_EQUAL(open, "");
@@ -186,15 +186,15 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_one ) {
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\nSec-WebSocket-Protocol: foo\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
std::string validate;
std::string open;
server s;
std::string validate;
std::string open;
server s;
s.set_user_agent("test");
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
BOOST_CHECK_EQUAL(validate, "foo,");
BOOST_CHECK_EQUAL(open, "foo");
@@ -204,33 +204,33 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
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\nSec-WebSocket-Protocol: foo\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
std::string validate;
std::string open;
server s;
std::string validate;
std::string open;
server s;
s.set_user_agent("test");
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo2",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
std::string o;
BOOST_CHECK_THROW(o = run_server_test(s,input), websocketpp::lib::error_code);
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo2",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
std::string o;
BOOST_CHECK_THROW(o = run_server_test(s,input), websocketpp::exception);
}
BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
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\nSec-WebSocket-Protocol: foo, bar\r\n\r\n";
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: bar\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
std::string validate;
std::string open;
server s;
std::string validate;
std::string open;
server s;
s.set_user_agent("test");
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"bar",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"bar",::_1));
s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
BOOST_CHECK_EQUAL(validate, "foo,bar,");
BOOST_CHECK_EQUAL(open, "bar");
@@ -239,9 +239,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
/*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: test\r\n\r\n";
server s;
s.set_user_agent("test");
BOOST_CHECK(run_server_test(s,input) == output);
}*/
+1 -1
View File
@@ -11,7 +11,7 @@ Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','regex','random'],env) + [platform_libs] + [tls_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','random','chrono'],env) + [platform_libs] + [tls_libs]
objs = env.Object('boost_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS)
prgs = env.Program('test_boost_integration', ["boost_integration.o"], LIBS = BOOST_LIBS)
+1 -1
View File
@@ -11,7 +11,7 @@ Import('tls_libs')
env = env.Clone ()
env_cpp11 = env_cpp11.Clone ()
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','regex'],env) + [platform_libs] + [tls_libs]
BOOST_LIBS = boostlibs(['unit_test_framework','system','thread','chrono'],env) + [platform_libs] + [tls_libs]
objs = env.Object('base_boost.o', ["base.cpp"], LIBS = BOOST_LIBS)
objs += env.Object('timers_boost.o', ["timers.cpp"], LIBS = BOOST_LIBS)
+10 -10
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE transport_asio_base
@@ -34,16 +34,16 @@
BOOST_AUTO_TEST_CASE( blank_error ) {
websocketpp::lib::error_code ec;
BOOST_CHECK( !ec );
}
BOOST_AUTO_TEST_CASE( asio_error ) {
using websocketpp::transport::asio::error::make_error_code;
using websocketpp::transport::asio::error::general;
websocketpp::lib::error_code ec = make_error_code(general);
BOOST_CHECK( ec == general );
BOOST_CHECK( ec.value() == 1 );
}
}
+29 -28
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE transport_asio_timers
@@ -52,12 +52,12 @@
// Accept a connection, read data, and discard until EOF
void run_dummy_server(int port) {
using boost::asio::ip::tcp;
try {
try {
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
tcp::socket socket(io_service);
acceptor.accept(socket);
for (;;) {
char data[512];
@@ -94,7 +94,9 @@ struct config {
typedef websocketpp::http::parser::request request_type;
typedef websocketpp::http::parser::response response_type;
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
static const bool enable_multithreading = true;
static const long timeout_socket_pre_init = 1000;
static const long timeout_proxy = 1000;
static const long timeout_socket_post_init = 1000;
@@ -105,27 +107,27 @@ struct config {
// Mock context that does no validation
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
context_ptr on_tls_init(websocketpp::connection_hdl) {
return context_ptr(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
}
// Mock connection
struct mock_con: public websocketpp::transport::asio::connection<config> {
typedef websocketpp::transport::asio::connection<config> base;
mock_con(bool a, config::alog_type& b, config::elog_type& c) : base(a,b,c) {}
void start() {
base::init(websocketpp::lib::bind(&mock_con::handle_start,this,
websocketpp::lib::placeholders::_1));
}
void handle_start(const websocketpp::lib::error_code& ec) {
using websocketpp::transport::asio::socket::make_error_code;
using websocketpp::transport::asio::socket::error::tls_handshake_timeout;
BOOST_CHECK_EQUAL( ec, make_error_code(tls_handshake_timeout) );
base::cancel_socket();
}
};
@@ -135,19 +137,20 @@ typedef websocketpp::lib::shared_ptr<mock_con> connection_ptr;
struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
typedef websocketpp::transport::asio::endpoint<config> base;
mock_endpoint() {
alog.set_channels(websocketpp::log::alevel::all);
base::init_logging(&alog,&elog);
init_asio();
}
void connect(std::string u) {
m_con.reset(new mock_con(false,alog,elog));
websocketpp::uri_ptr uri(new websocketpp::uri(u));
BOOST_CHECK( uri->get_valid() );
BOOST_CHECK_EQUAL( base::init(m_con), websocketpp::lib::error_code() );
base::async_connect(
m_con,
uri,
@@ -155,19 +158,17 @@ struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
&mock_endpoint::handle_connect,
this,
m_con,
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2
websocketpp::lib::placeholders::_1
)
);
}
void handle_connect(connection_ptr con, websocketpp::connection_hdl,
const websocketpp::lib::error_code & ec)
void handle_connect(connection_ptr con, websocketpp::lib::error_code const & ec)
{
BOOST_CHECK( !ec );
con->start();
}
connection_ptr m_con;
config::alog_type alog;
config::elog_type elog;
@@ -178,9 +179,9 @@ BOOST_AUTO_TEST_CASE( tls_handshake_timeout ) {
websocketpp::lib::thread timer(websocketpp::lib::bind(&run_test_timer,5000));
dummy_server.detach();
timer.detach();
mock_endpoint endpoint;
endpoint.set_tls_init_handler(&on_tls_init);
endpoint.connect("wss://localhost:9005");
endpoint.run();
}
}
+21 -21
View File
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE hybi_util
@@ -36,15 +36,15 @@
BOOST_AUTO_TEST_CASE( circshift_0 ) {
if (sizeof(size_t) == 8) {
size_t test = 0x0123456789abcdef;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0);
BOOST_CHECK( test == 0x0123456789abcdef);
} else {
size_t test = 0x01234567;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,0);
BOOST_CHECK( test == 0x01234567);
}
}
@@ -52,15 +52,15 @@ BOOST_AUTO_TEST_CASE( circshift_0 ) {
BOOST_AUTO_TEST_CASE( circshift_1 ) {
if (sizeof(size_t) == 8) {
size_t test = 0x0123456789abcdef;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1);
BOOST_CHECK( test == 0xef0123456789abcd);
} else {
size_t test = 0x01234567;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,1);
BOOST_CHECK( test == 0x67012345);
}
}
@@ -68,15 +68,15 @@ BOOST_AUTO_TEST_CASE( circshift_1 ) {
BOOST_AUTO_TEST_CASE( circshift_2 ) {
if (sizeof(size_t) == 8) {
size_t test = 0x0123456789abcdef;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2);
BOOST_CHECK( test == 0xcdef0123456789ab);
} else {
size_t test = 0x01234567;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,2);
BOOST_CHECK( test == 0x45670123);
}
}
@@ -84,15 +84,15 @@ BOOST_AUTO_TEST_CASE( circshift_2 ) {
BOOST_AUTO_TEST_CASE( circshift_3 ) {
if (sizeof(size_t) == 8) {
size_t test = 0x0123456789abcdef;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3);
BOOST_CHECK( test == 0xabcdef0123456789);
} else {
size_t test = 0x01234567;
test = websocketpp::processor::hybi_util::circshift_prepared_key(test,3);
BOOST_CHECK( test == 0x23456701);
}
}
+311 -55
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE transport_integration
@@ -30,45 +30,90 @@
#include <websocketpp/common/thread.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/config/core.hpp>
#include <websocketpp/config/core_client.hpp>
#include <websocketpp/config/asio.hpp>
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/config/debug_asio.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/client.hpp>
struct config : public websocketpp::config::asio_client {
typedef config type;
typedef websocketpp::config::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;
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
typedef websocketpp::transport::asio::basic_socket::endpoint
socket_type;
};
typedef websocketpp::transport::asio::endpoint<transport_config>
typedef websocketpp::transport::asio::endpoint<transport_config>
transport_type;
//static const websocketpp::log::level elog_level = websocketpp::log::elevel::all;
//static const websocketpp::log::level alog_level = websocketpp::log::alevel::all;
/// Length of time before an opening handshake is aborted
static const long timeout_open_handshake = 500;
/// Length of time before a closing handshake is aborted
static const long timeout_close_handshake = 500;
/// Length of time to wait for a pong after a ping
static const long timeout_pong = 500;
};
struct config_tls : public websocketpp::config::asio_tls_client {
typedef config type;
typedef websocketpp::config::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;
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 websocketpp::log::level elog_level = websocketpp::log::elevel::all;
//static const websocketpp::log::level alog_level = websocketpp::log::alevel::all;
/// Length of time before an opening handshake is aborted
static const long timeout_open_handshake = 500;
/// Length of time before a closing handshake is aborted
@@ -80,10 +125,25 @@ struct config : public websocketpp::config::asio_client {
typedef websocketpp::server<config> server;
typedef websocketpp::client<config> client;
typedef websocketpp::server<config_tls> server_tls;
typedef websocketpp::client<config_tls> client_tls;
typedef websocketpp::server<websocketpp::config::core> iostream_server;
typedef websocketpp::client<websocketpp::config::core_client> iostream_client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
template <typename T>
void close_after_timeout(T & e, websocketpp::connection_hdl hdl, long timeout) {
sleep(timeout);
websocketpp::lib::error_code ec;
e.close(hdl,websocketpp::close::status::normal,"",ec);
BOOST_CHECK(!ec);
}
void run_server(server * s, int port, bool log = false) {
if (log) {
s->set_access_channels(websocketpp::log::alevel::all);
@@ -94,6 +154,7 @@ void run_server(server * s, int port, bool log = false) {
}
s->init_asio();
s->set_reuse_addr(true);
s->listen(port);
s->start_accept();
@@ -108,9 +169,11 @@ void run_client(client & c, std::string uri, bool log = false) {
c.clear_access_channels(websocketpp::log::alevel::all);
c.clear_error_channels(websocketpp::log::elevel::all);
}
c.init_asio();
websocketpp::lib::error_code ec;
c.init_asio(ec);
c.set_reuse_addr(true);
BOOST_CHECK(!ec);
client::connection_ptr con = c.get_connection(uri,ec);
BOOST_CHECK( !ec );
c.connect(con);
@@ -118,14 +181,50 @@ void run_client(client & c, std::string uri, bool log = false) {
c.run();
}
void run_client_and_mark(client * c, bool * flag, websocketpp::lib::mutex * mutex) {
c->run();
BOOST_CHECK( true );
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(*mutex);
*flag = true;
BOOST_CHECK( true );
}
void run_time_limited_client(client & c, std::string uri, long timeout,
bool log)
{
if (log) {
c.set_access_channels(websocketpp::log::alevel::all);
c.set_error_channels(websocketpp::log::elevel::all);
} else {
c.clear_access_channels(websocketpp::log::alevel::all);
c.clear_error_channels(websocketpp::log::elevel::all);
}
c.init_asio();
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri,ec);
BOOST_CHECK( !ec );
c.connect(con);
websocketpp::lib::thread tthread(websocketpp::lib::bind(
&close_after_timeout<client>,
websocketpp::lib::ref(c),
con->get_handle(),
timeout
));
tthread.detach();
c.run();
}
void run_dummy_server(int port) {
using boost::asio::ip::tcp;
try {
try {
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
tcp::socket socket(io_service);
acceptor.accept(socket);
for (;;) {
char data[512];
@@ -147,14 +246,14 @@ void run_dummy_server(int port) {
void run_dummy_client(std::string port) {
using boost::asio::ip::tcp;
try {
try {
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", port);
tcp::resolver::iterator iterator = resolver.resolve(query);
tcp::socket socket(io_service);
boost::asio::connect(socket, iterator);
for (;;) {
char data[512];
@@ -174,12 +273,13 @@ void run_dummy_client(std::string port) {
}
}
bool on_ping(websocketpp::connection_hdl, std::string payload) {
bool on_ping(server * s, websocketpp::connection_hdl, std::string) {
s->get_alog().write(websocketpp::log::alevel::app,"got ping");
return false;
}
void cancel_on_open(server * s, websocketpp::connection_hdl hdl) {
s->cancel();
void cancel_on_open(server * s, websocketpp::connection_hdl) {
s->stop_listening();
}
void stop_on_close(server * s, websocketpp::connection_hdl hdl) {
@@ -192,23 +292,35 @@ void stop_on_close(server * s, websocketpp::connection_hdl hdl) {
template <typename T>
void ping_on_open(T * c, std::string payload, websocketpp::connection_hdl hdl) {
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
con->ping(payload);
websocketpp::lib::error_code ec;
con->ping(payload,ec);
BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
}
void fail_on_pong(websocketpp::connection_hdl hdl, std::string payload) {
void fail_on_pong(websocketpp::connection_hdl, std::string) {
BOOST_FAIL( "expected no pong handler" );
}
void fail_on_open(websocketpp::connection_hdl hdl) {
void fail_on_pong_timeout(websocketpp::connection_hdl, std::string) {
BOOST_FAIL( "expected no pong timeout" );
}
void req_pong(std::string expected_payload, websocketpp::connection_hdl,
std::string payload)
{
BOOST_CHECK_EQUAL( expected_payload, payload );
}
void fail_on_open(websocketpp::connection_hdl) {
BOOST_FAIL( "expected no open handler" );
}
void delay(websocketpp::connection_hdl hdl, long duration) {
void delay(websocketpp::connection_hdl, long duration) {
sleep(duration);
}
template <typename T>
void check_ec(T * c, websocketpp::lib::error_code ec,
void check_ec(T * c, websocketpp::lib::error_code ec,
websocketpp::connection_hdl hdl)
{
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
@@ -218,7 +330,7 @@ void check_ec(T * c, websocketpp::lib::error_code ec,
}
template <typename T>
void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
websocketpp::connection_hdl hdl)
{
typename T::connection_ptr con = e->get_con_from_hdl(hdl);
@@ -229,7 +341,7 @@ void check_ec_and_stop(T * e, websocketpp::lib::error_code ec,
}
template <typename T>
void req_pong_timeout(T * c, std::string expected_payload,
void req_pong_timeout(T * c, std::string expected_payload,
websocketpp::connection_hdl hdl, std::string payload)
{
typename T::connection_ptr con = c->get_con_from_hdl(hdl);
@@ -248,31 +360,55 @@ void run_test_timer(long value) {
BOOST_FAIL( "Test timed out" );
}
BOOST_AUTO_TEST_CASE( pong_no_timeout ) {
server s;
client c;
s.set_close_handler(bind(&stop_on_close,&s,::_1));
// send a ping when the connection is open
c.set_open_handler(bind(&ping_on_open<client>,&c,"foo",::_1));
// require that a pong with matching payload is received
c.set_pong_handler(bind(&req_pong,"foo",::_1,::_2));
// require that a pong timeout is NOT received
c.set_pong_timeout_handler(bind(&fail_on_pong_timeout,::_1,::_2));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
// Run a client that closes the connection after 1 seconds
run_time_limited_client(c, "http://localhost:9005", 1, false);
sthread.join();
}
BOOST_AUTO_TEST_CASE( pong_timeout ) {
server s;
client c;
s.set_ping_handler(on_ping);
s.set_ping_handler(bind(&on_ping, &s,::_1,::_2));
s.set_close_handler(bind(&stop_on_close,&s,::_1));
c.set_fail_handler(bind(&check_ec<client>,&c,
websocketpp::lib::error_code(),::_1));
c.set_pong_handler(bind(&fail_on_pong,::_1,::_2));
c.set_open_handler(bind(&ping_on_open<client>,&c,"foo",::_1));
c.set_pong_timeout_handler(bind(&req_pong_timeout<client>,&c,"foo",::_1,::_2));
c.set_close_handler(bind(&check_ec<client>,&c,
websocketpp::lib::error_code(),::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
tthread.detach();
run_client(c, "http://localhost:9005",false);
sthread.join();
}
BOOST_AUTO_TEST_CASE( client_open_handshake_timeout ) {
client c;
// set open handler to fail test
c.set_open_handler(bind(&fail_on_open,::_1));
// set fail hander to test for the right fail error code
@@ -280,16 +416,16 @@ BOOST_AUTO_TEST_CASE( client_open_handshake_timeout ) {
websocketpp::error::open_handshake_timeout,::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_dummy_server,9005));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
sthread.detach();
tthread.detach();
run_client(c, "http://localhost:9005");
}
BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
server s;
// set open handler to fail test
s.set_open_handler(bind(&fail_on_open,::_1));
// set fail hander to test for the right fail error code
@@ -297,11 +433,11 @@ BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) {
websocketpp::error::open_handshake_timeout,::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
tthread.detach();
run_dummy_client("9005");
sthread.join();
}
@@ -318,13 +454,13 @@ BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) {
c.set_open_handler(bind(&close<client>,&c,::_1));
c.set_close_handler(bind(&check_ec<client>,&c,
websocketpp::error::close_handshake_timeout,::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
tthread.detach();
run_client(c, "http://localhost:9005",false);
run_client(c, "http://localhost:9005", false);
sthread.join();
}
@@ -333,7 +469,7 @@ BOOST_AUTO_TEST_CASE( client_peer_initiated_close_handshake_timeout ) {
// client should ack normally and then wait
// server leaves TCP connection open
// client handshake timer should be triggered
// TODO: how to make a mock server that leaves the TCP connection open?
}
@@ -350,12 +486,132 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
websocketpp::error::close_handshake_timeout,::_1));
c.set_open_handler(bind(&delay,::_1,1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,6));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
tthread.detach();
run_client(c, "http://localhost:9005",false);
sthread.join();
}
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
client c;
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,3));
tthread.detach();
websocketpp::lib::error_code ec;
c.init_asio(ec);
BOOST_CHECK(!ec);
c.run();
// This test checks that an io_service with no work ends immediately.
BOOST_CHECK(true);
}
BOOST_AUTO_TEST_CASE( client_is_perpetual ) {
client c;
bool flag = false;
websocketpp::lib::mutex mutex;
websocketpp::lib::error_code ec;
c.init_asio(ec);
BOOST_CHECK(!ec);
c.start_perpetual();
websocketpp::lib::thread cthread(websocketpp::lib::bind(&run_client_and_mark,&c,&flag,&mutex));
sleep(1);
{
// Checks that the thread hasn't exited yet
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(mutex);
BOOST_CHECK( !flag );
}
c.stop_perpetual();
sleep(1);
{
// Checks that the thread has exited
websocketpp::lib::lock_guard<websocketpp::lib::mutex> lock(mutex);
BOOST_CHECK( flag );
}
cthread.join();
}
BOOST_AUTO_TEST_CASE( client_failed_connection ) {
client c;
run_time_limited_client(c,"http://localhost:9005", 5, false);
}
BOOST_AUTO_TEST_CASE( stop_listening ) {
server s;
client c;
// the first connection stops the server from listening
s.set_open_handler(bind(&cancel_on_open,&s,::_1));
// client immediately closes after opening a connection
c.set_open_handler(bind(&close<client>,&c,::_1));
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,5));
tthread.detach();
run_client(c, "http://localhost:9005",false);
sthread.join();
}
BOOST_AUTO_TEST_CASE( pause_reading ) {
iostream_server s;
std::string handshake = "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\n\r\n";
char buffer[2] = { char(0x81), char(0x80) };
// suppress output (it needs a place to go to avoid error but we don't care what it is)
std::stringstream null_output;
s.register_ostream(&null_output);
iostream_server::connection_ptr con = s.get_connection();
con->start();
// read handshake, should work
BOOST_CHECK_EQUAL( con->read_some(handshake.data(), handshake.length()), handshake.length());
// pause reading and try again. The first read should work, the second should return 0
// the first read was queued already after the handshake so it will go through because
// reading wasn't paused when it was queued. The byte it reads wont be enough to
// complete the frame so another read will be requested. This one wont actually happen
// because the connection is paused now.
con->pause_reading();
BOOST_CHECK_EQUAL( con->read_some(buffer, 1), 1);
BOOST_CHECK_EQUAL( con->read_some(buffer+1, 1), 0);
// resume reading and try again. Should work this time because the resume should have
// re-queued a read.
con->resume_reading();
BOOST_CHECK_EQUAL( con->read_some(buffer+1, 1), 1);
}
BOOST_AUTO_TEST_CASE( server_connection_cleanup ) {
server_tls s;
}
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
BOOST_AUTO_TEST_CASE( move_construct_transport ) {
server s1;
server s2(std::move(s1));
}
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
+7 -7
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE transport_iostream_base
@@ -30,4 +30,4 @@
#include <iostream>
BOOST_AUTO_TEST_CASE( placeholder ) {}
BOOST_AUTO_TEST_CASE( placeholder ) {}
+466 -139
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:
@@ -11,10 +11,10 @@
* * 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
*
* 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;
@@ -22,7 +22,7 @@
* 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.
*
*
*/
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE transport_iostream_connection
@@ -32,6 +32,8 @@
#include <cstring>
#include <string>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/error.hpp>
#include <websocketpp/transport/iostream/connection.hpp>
@@ -52,231 +54,556 @@ typedef websocketpp::transport::iostream::connection<config> iostream_con;
using websocketpp::transport::iostream::error::make_error_code;
struct stub_con : public iostream_con {
typedef stub_con type;
typedef websocketpp::lib::shared_ptr<type> ptr;
typedef iostream_con::timer_ptr timer_ptr;
stub_con(bool is_server, config::alog_type &a, config::elog_type & e)
stub_con(bool is_server, config::alog_type & a, config::elog_type & e)
: iostream_con(is_server,a,e)
// Set the error to a known code that is unused by the library
// This way we can easily confirm that the handler was run at all.
, ec(websocketpp::error::make_error_code(websocketpp::error::test))
, indef_read_total(0)
{}
/// Get a shared pointer to this component
ptr get_shared() {
return websocketpp::lib::static_pointer_cast<type>(iostream_con::get_shared());
}
void write(std::string msg) {
iostream_con::async_write(
msg.data(),
msg.size(),
websocketpp::lib::bind(
&stub_con::handle_op,
this,
type::get_shared(),
websocketpp::lib::placeholders::_1
)
);
}
void write(std::vector<websocketpp::transport::buffer> & bufs) {
iostream_con::async_write(
bufs,
websocketpp::lib::bind(
&stub_con::handle_op,
this,
type::get_shared(),
websocketpp::lib::placeholders::_1
)
);
}
void async_read_at_least(size_t num_bytes, char *buf, size_t len)
{
{
iostream_con::async_read_at_least(
num_bytes,
buf,
len,
websocketpp::lib::bind(
&stub_con::handle_op,
this,
type::get_shared(),
websocketpp::lib::placeholders::_1
)
);
}
void handle_op(const websocketpp::lib::error_code& e) {
void handle_op(websocketpp::lib::error_code const & e) {
ec = e;
}
void async_read_indef(size_t num_bytes, char *buf, size_t len)
{
indef_read_size = num_bytes;
indef_read_buf = buf;
indef_read_len = len;
indef_read();
}
void indef_read() {
iostream_con::async_read_at_least(
indef_read_size,
indef_read_buf,
indef_read_len,
websocketpp::lib::bind(
&stub_con::handle_indef,
type::get_shared(),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2
)
);
}
void handle_indef(websocketpp::lib::error_code const & e, size_t amt_read) {
ec = e;
indef_read_total += amt_read;
indef_read();
}
void shutdown() {
iostream_con::async_shutdown(
websocketpp::lib::bind(
&stub_con::handle_async_shutdown,
type::get_shared(),
websocketpp::lib::placeholders::_1
)
);
}
void handle_async_shutdown(websocketpp::lib::error_code const & e) {
ec = e;
}
websocketpp::lib::error_code ec;
size_t indef_read_size;
char * indef_read_buf;
size_t indef_read_len;
size_t indef_read_total;
};
// Stubs
config::alog_type a;
config::elog_type e;
config::alog_type alogger;
config::elog_type elogger;
BOOST_AUTO_TEST_CASE( const_methods ) {
iostream_con con(true,a,e);
BOOST_CHECK( con.is_secure() == false );
BOOST_CHECK( con.get_remote_endpoint() == "iostream transport" );
iostream_con::ptr con(new iostream_con(true,alogger,elogger));
BOOST_CHECK( !con->is_secure() );
BOOST_CHECK_EQUAL( con->get_remote_endpoint(), "iostream transport" );
}
BOOST_AUTO_TEST_CASE( write_before_ostream_set ) {
stub_con con(true,a,e);
con.write("foo");
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
BOOST_AUTO_TEST_CASE( write_before_output_method_set ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->write("foo");
BOOST_CHECK( con->ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
std::vector<websocketpp::transport::buffer> bufs;
con.write(bufs);
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
con->write(bufs);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::output_stream_required) );
}
BOOST_AUTO_TEST_CASE( async_write ) {
stub_con con(true,a,e);
BOOST_AUTO_TEST_CASE( async_write_ostream ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
std::stringstream output;
con.register_ostream(&output);
con.write("foo");
BOOST_CHECK( !con.ec );
BOOST_CHECK( output.str() == "foo" );
con->register_ostream(&output);
con->write("foo");
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output.str(), "foo" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_0 ) {
websocketpp::lib::error_code write_handler(std::string & o, websocketpp::connection_hdl, char const * buf, size_t len) {
o += std::string(buf,len);
return websocketpp::lib::error_code();
}
websocketpp::lib::error_code vector_write_handler(std::string & o, websocketpp::connection_hdl, std::vector<websocketpp::transport::buffer> const & bufs) {
std::vector<websocketpp::transport::buffer>::const_iterator it;
for (it = bufs.begin(); it != bufs.end(); it++) {
o += std::string((*it).buf, (*it).len);
}
return websocketpp::lib::error_code();
}
websocketpp::lib::error_code write_handler_error(websocketpp::connection_hdl, char const *, size_t) {
return make_error_code(websocketpp::transport::error::general);
}
BOOST_AUTO_TEST_CASE( async_write_handler ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
std::string output;
con->set_write_handler(websocketpp::lib::bind(
&write_handler,
websocketpp::lib::ref(output),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2,
websocketpp::lib::placeholders::_3
));
con->write("foo");
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL(output, "foo");
}
BOOST_AUTO_TEST_CASE( async_write_handler_error ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_write_handler(&write_handler_error);
con->write("foo");
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
}
BOOST_AUTO_TEST_CASE( async_write_vector_0_ostream ) {
std::stringstream output;
stub_con con(true,a,e);
con.register_ostream(&output);
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->register_ostream(&output);
std::vector<websocketpp::transport::buffer> bufs;
con.write(bufs);
BOOST_CHECK( !con.ec );
BOOST_CHECK( output.str() == "" );
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output.str(), "" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_1 ) {
std::stringstream output;
stub_con con(true,a,e);
con.register_ostream(&output);
BOOST_AUTO_TEST_CASE( async_write_vector_0_write_handler ) {
std::string output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_write_handler(websocketpp::lib::bind(
&write_handler,
websocketpp::lib::ref(output),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2,
websocketpp::lib::placeholders::_3
));
std::vector<websocketpp::transport::buffer> bufs;
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output, "" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_1_ostream ) {
std::stringstream output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->register_ostream(&output);
std::vector<websocketpp::transport::buffer> bufs;
std::string foo = "foo";
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
con.write(bufs);
BOOST_CHECK( !con.ec );
BOOST_CHECK( output.str() == "foo" );
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output.str(), "foo" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_2 ) {
std::stringstream output;
stub_con con(true,a,e);
con.register_ostream(&output);
BOOST_AUTO_TEST_CASE( async_write_vector_1_write_handler ) {
std::string output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_write_handler(websocketpp::lib::bind(
&write_handler,
websocketpp::lib::ref(output),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2,
websocketpp::lib::placeholders::_3
));
std::vector<websocketpp::transport::buffer> bufs;
std::string foo = "foo";
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output, "foo" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_2_ostream ) {
std::stringstream output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->register_ostream(&output);
std::vector<websocketpp::transport::buffer> bufs;
std::string foo = "foo";
std::string bar = "bar";
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
con.write(bufs);
BOOST_CHECK( !con.ec );
BOOST_CHECK( output.str() == "foobar" );
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output.str(), "foobar" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_2_write_handler ) {
std::string output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_write_handler(websocketpp::lib::bind(
&write_handler,
websocketpp::lib::ref(output),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2,
websocketpp::lib::placeholders::_3
));
std::vector<websocketpp::transport::buffer> bufs;
std::string foo = "foo";
std::string bar = "bar";
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output, "foobar" );
}
BOOST_AUTO_TEST_CASE( async_write_vector_2_vector_write_handler ) {
std::string output;
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_vector_write_handler(websocketpp::lib::bind(
&vector_write_handler,
websocketpp::lib::ref(output),
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2
));
std::vector<websocketpp::transport::buffer> bufs;
std::string foo = "foo";
std::string bar = "bar";
bufs.push_back(websocketpp::transport::buffer(foo.data(),foo.size()));
bufs.push_back(websocketpp::transport::buffer(bar.data(),bar.size()));
con->write(bufs);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( output, "foobar" );
}
BOOST_AUTO_TEST_CASE( async_read_at_least_too_much ) {
stub_con con(true,a,e);
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
con.async_read_at_least(11,buf,10);
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::invalid_num_bytes) );
con->async_read_at_least(11,buf,10);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::invalid_num_bytes) );
}
BOOST_AUTO_TEST_CASE( async_read_at_least_double_read ) {
stub_con con(true,a,e);
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
con.async_read_at_least(5,buf,10);
con.async_read_at_least(5,buf,10);
BOOST_CHECK( con.ec == make_error_code(websocketpp::transport::iostream::error::double_read) );
con->async_read_at_least(5,buf,10);
con->async_read_at_least(5,buf,10);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::iostream::error::double_read) );
}
BOOST_AUTO_TEST_CASE( async_read_at_least ) {
stub_con con(true,a,e);
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
memset(buf,'x',10);
con.async_read_at_least(5,buf,10);
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
con->async_read_at_least(5,buf,10);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
std::stringstream channel;
channel << "abcd";
channel >> con;
BOOST_CHECK( channel.tellg() == -1 );
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
channel << "abcd";
channel >> *con;
BOOST_CHECK_EQUAL( channel.tellg(), -1 );
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
std::stringstream channel2;
channel2 << "e";
channel2 >> con;
BOOST_CHECK( channel2.tellg() == -1 );
BOOST_CHECK( !con.ec );
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
channel2 << "e";
channel2 >> *con;
BOOST_CHECK_EQUAL( channel2.tellg(), -1 );
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
std::stringstream channel3;
channel3 << "f";
channel3 >> con;
BOOST_CHECK( channel3.tellg() == 0 );
BOOST_CHECK( !con.ec );
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
con.async_read_at_least(1,buf+5,5);
channel3 >> con;
BOOST_CHECK( channel3.tellg() == -1 );
BOOST_CHECK( !con.ec );
BOOST_CHECK( std::string(buf,10) == "abcdefxxxx" );
channel3 << "f";
channel3 >> *con;
BOOST_CHECK_EQUAL( channel3.tellg(), 0 );
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
con->async_read_at_least(1,buf+5,5);
channel3 >> *con;
BOOST_CHECK_EQUAL( channel3.tellg(), -1 );
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefxxxx" );
}
BOOST_AUTO_TEST_CASE( async_read_at_least2 ) {
stub_con con(true,a,e);
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
memset(buf,'x',10);
con.async_read_at_least(5,buf,5);
BOOST_CHECK( con.ec == make_error_code(websocketpp::error::test) );
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
std::stringstream channel;
channel << "abcdefg";
channel >> con;
BOOST_CHECK( channel.tellg() == 5 );
BOOST_CHECK( !con.ec );
BOOST_CHECK( std::string(buf,10) == "abcdexxxxx" );
con.async_read_at_least(1,buf+5,5);
channel >> con;
BOOST_CHECK( channel.tellg() == -1 );
BOOST_CHECK( !con.ec );
BOOST_CHECK( std::string(buf,10) == "abcdefgxxx" );
channel << "abcdefg";
channel >> *con;
BOOST_CHECK_EQUAL( channel.tellg(), 5 );
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
con->async_read_at_least(1,buf+5,5);
channel >> *con;
BOOST_CHECK_EQUAL( channel.tellg(), -1 );
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
}
void timer_callback_stub(const websocketpp::lib::error_code & ec) {}
void timer_callback_stub(websocketpp::lib::error_code const &) {}
BOOST_AUTO_TEST_CASE( set_timer ) {
stub_con con(true,a,e);
stub_con::timer_ptr tp = con.set_timer(1000,timer_callback_stub);
stub_con::ptr con(new stub_con(true,alogger,elogger));
stub_con::timer_ptr tp = con->set_timer(1000,timer_callback_stub);
BOOST_CHECK( !tp );
}
BOOST_AUTO_TEST_CASE( async_read_at_least_read_some ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
memset(buf,'x',10);
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
char input[10] = "abcdefg";
BOOST_CHECK_EQUAL(con->read_some(input,5), 5);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
BOOST_CHECK_EQUAL(con->read_some(input+5,2), 0);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdexxxxx" );
con->async_read_at_least(1,buf+5,5);
BOOST_CHECK_EQUAL(con->read_some(input+5,2), 2);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "abcdefgxxx" );
}
BOOST_AUTO_TEST_CASE( async_read_at_least_read_some_indef ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[20];
memset(buf,'x',20);
con->async_read_indef(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
// here we expect to return early from read some because the outstanding
// read was for 5 bytes and we were called with 10.
char input[11] = "aaaaabbbbb";
BOOST_CHECK_EQUAL(con->read_some(input,10), 5);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "aaaaaxxxxx" );
BOOST_CHECK_EQUAL( con->indef_read_total, 5 );
// A subsequent read should read 5 more because the indef read refreshes
// itself. The new read will start again at the beginning of the buffer.
BOOST_CHECK_EQUAL(con->read_some(input+5,5), 5);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
}
BOOST_AUTO_TEST_CASE( async_read_at_least_read_all ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[20];
memset(buf,'x',20);
con->async_read_indef(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
char input[11] = "aaaaabbbbb";
BOOST_CHECK_EQUAL(con->read_all(input,10), 10);
BOOST_CHECK( !con->ec );
BOOST_CHECK_EQUAL( std::string(buf,10), "bbbbbxxxxx" );
BOOST_CHECK_EQUAL( con->indef_read_total, 10 );
}
BOOST_AUTO_TEST_CASE( eof_flag ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
con->eof();
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
}
BOOST_AUTO_TEST_CASE( fatal_error_flag ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
char buf[10];
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
con->fatal_error();
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::pass_through) );
}
BOOST_AUTO_TEST_CASE( shutdown ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
con->shutdown();
BOOST_CHECK_EQUAL( con->ec, websocketpp::lib::error_code() );
}
websocketpp::lib::error_code sd_handler(websocketpp::connection_hdl) {
return make_error_code(websocketpp::transport::error::general);
}
BOOST_AUTO_TEST_CASE( shutdown_handler ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
con->set_shutdown_handler(&sd_handler);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
con->shutdown();
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::general) );
}
BOOST_AUTO_TEST_CASE( shared_pointer_memory_cleanup ) {
stub_con::ptr con(new stub_con(true,alogger,elogger));
BOOST_CHECK_EQUAL(con.use_count(), 1);
char buf[10];
memset(buf,'x',10);
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::error::test) );
BOOST_CHECK_EQUAL(con.use_count(), 2);
char input[10] = "foo";
con->read_some(input,3);
BOOST_CHECK_EQUAL(con.use_count(), 2);
con->read_some(input,2);
BOOST_CHECK_EQUAL( std::string(buf,10), "foofoxxxxx" );
BOOST_CHECK_EQUAL(con.use_count(), 1);
con->async_read_at_least(5,buf,5);
BOOST_CHECK_EQUAL(con.use_count(), 2);
con->eof();
BOOST_CHECK_EQUAL( con->ec, make_error_code(websocketpp::transport::error::eof) );
BOOST_CHECK_EQUAL(con.use_count(), 1);
}
Loaded 100 of 221 files, more files were not shown because too many files have changed in this diff. Show more