Compare commits

..

67 Commits

Author SHA1 Message Date
Alexander Afanasyev ac4e021333 Fix compilation with boost 1.70.0 2019-04-25 17:23:23 -04:00
Peter Thorson c6d7e295bf Set version flags for release 2018-07-16 07:40:53 -05:00
Peter Thorson c43242523c Update changelog 2018-07-16 07:38:45 -05:00
Peter Thorson 12b8f37cf5 Merge branch 'pr/732' into develop 2018-07-16 07:34:02 -05:00
Peter Thorson 6b8dfe02c2 Merge branch 'pr/731' into develop 2018-07-16 07:32:03 -05:00
Gianfranco Costamagna e99aef04c3 cmake: Install websocketpp includes in the right cmake way, leaving out the examples and other stuff 2018-07-12 20:25:09 +02:00
Gianfranco Costamagna 5c48a114f4 Fix testsuite errors, due to a "Connection: upgrade" seen differently than "Connection: Upgrade" 2018-07-12 19:10:02 +02:00
Peter Thorson c2fd89bede Update version flags for future development 2018-07-12 07:52:49 -05:00
Peter Thorson c612a35f06 Set version flags for 0.8.0 release 2018-07-12 07:50:48 -05:00
Peter Thorson 99d169f586 Update changelog for recent PRs 2018-07-12 07:46:21 -05:00
Peter Thorson 241741ba01 Merge pull request #727 from bauerj/patch-1
Make HTTP Connection header capitalized
2018-07-12 07:27:05 -05:00
Johann Bauer 702b6a919b Make HTTP Connection header capitalized
This is what other implementations do and what the example in RFC 6455 uses.
2018-06-18 12:46:01 +02:00
Peter Thorson 19cad9925f credits 2017-09-24 10:48:12 -05:00
Peter Thorson c4050979c3 tcp_pre_bind_handler returns a lib::error_code not an asio::error_code. These are sometimes the same but not always. Fix ensures that the error code types always match correctly no matter what they are. Update test suite to reflect adjusted behavior 2017-09-24 10:44:21 -05:00
Peter Thorson 7e8c8a8fad Fix preprocessor syntax issue 2017-09-24 09:56:21 -05:00
Peter Thorson 88de392422 Merge pull request #652 from vadz/preserve-asio-errors
Preserve ASIO errors if possible
2017-09-24 09:52:52 -05:00
Peter Thorson e79e0d1f94 Merge branch 'develop' of https://github.com/zaphoyd/websocketpp into develop 2017-09-24 09:27:47 -05:00
Peter Thorson bc12b81b29 Merge branch 'pr/608' into develop
# Conflicts:
#	changelog.md
2017-09-24 09:27:42 -05:00
Peter Thorson 8bc11bdf24 credits 2017-09-24 09:19:50 -05:00
Peter Thorson 1cb045d946 Add pointers in the docs to new mingw support 2017-09-24 09:17:34 -05:00
Peter Thorson 2a36e41a9a Remove auto selection of mingw-std-threads when MinGW is detected. Increase the priority of mingw-std-threads given its optional status. 2017-09-24 09:17:17 -05:00
Peter Thorson 0e1fc63b83 remove submodule 2017-09-24 09:16:05 -05:00
Peter Thorson 0b0871d879 remove submodules 2017-09-24 08:55:47 -05:00
Peter Thorson 20c67910e1 Merge pull request #658 from gjasny/drop-unused-members
Drop unused class members
2017-09-24 08:49:12 -05:00
Peter Thorson e943c9e1ed credits for patch 2017-09-24 08:44:28 -05:00
Peter Thorson 749b119b6b Merge pull request #665 from gegles/develop
Fix compile issues for ASIO_STANDALONE
2017-09-24 08:41:15 -05:00
Guillaume Egles e9c65467b3 Fix compile issues for ASIO_STANDALONE 2017-08-30 14:46:56 -07:00
Gregor Jasny b34a1786bc Drop unused class members 2017-07-04 09:31:37 +02:00
Peter Thorson e50ed8c1b1 update changelog for PR 2017-06-11 17:49:41 -05:00
Peter Thorson 67224f71b5 Merge pull request #636 from gjasny/remove-undefined-behaviour
Avoid undefined behaviour at circular shift
2017-06-11 17:47:47 -05:00
Peter Thorson 0b2e14ee3a Merge branch 'pr/589' into develop 2017-06-11 17:44:02 -05:00
Peter Thorson 1cb9666036 Update changelog for PR 2017-06-11 17:43:09 -05:00
Peter Thorson cb3d7de91f Remove deprecated features to allow compiling with C++17 compilers fixes #592 2017-06-11 17:37:14 -05:00
Peter Thorson 9baab8faa9 Normalize line endings to unix format fixes #644 2017-06-11 17:27:41 -05:00
Peter Thorson 6330286ad5 Use separate buffers for compression and decompression to prevent corruption when reading and writing from separate threads. references #633 references #615 2017-06-11 17:24:51 -05:00
Peter Thorson cb4cf66911 Merge branch 'pr/634' into develop 2017-06-11 16:46:31 -05:00
Peter Thorson 99e1a99633 change log update for PR 2017-06-11 16:46:18 -05:00
Peter Thorson 96b2d42c83 Merge branch 'pr/638' into develop 2017-06-11 16:39:32 -05:00
Peter Thorson bc04ae4f5f update changelog for PR 2017-06-11 16:37:46 -05:00
Peter Thorson ee74047c2d Merge pull request #645 from alex-che/integration_tests_sleep
Fix refused client connection due to servers not yet started
2017-06-11 16:34:49 -05:00
Peter Thorson 2819d364d9 Merge branch 'develop' into integration_tests_sleep 2017-06-11 16:31:21 -05:00
Peter Thorson d282738c81 Merge branch 'pr/643' into develop 2017-06-11 16:28:58 -05:00
Peter Thorson a32eb0887b change log entry for PR 2017-06-11 16:28:47 -05:00
Peter Thorson 6645fcb390 Merge pull request #646 from alex-che/timers_tests_sleep
Fix the tls_handshake_timeout unit test failing due to server thread …
2017-06-11 16:18:00 -05:00
Peter Thorson 29bb4ada91 Merge branch 'pr/647' into develop 2017-06-11 16:16:38 -05:00
Peter Thorson ac9164c3b5 update changelog for PR 2017-06-11 16:16:13 -05:00
Peter Thorson 4cab5e5c0c minor adjustments to recent extension negotiation related fixes, refactor a bit more extension negotiation code to be simpler 2017-06-11 16:13:25 -05:00
Peter Thorson 16d126ee61 Remove custom handling of SSL_R_SHORT_READ errors. fixes #599 2017-06-11 15:41:06 -05:00
Peter Thorson 9ddb300d87 Update permessage-deflate support to reflect that zlib doesn't support a 256 bit window. Improve extension negotiation error checking and documentation. fixes #596 fixes #653 2017-06-11 15:24:43 -05:00
Vadim Zeitlin 81ef065ccf Preserve ASIO errors if possible in asio::endpoint too
This was already done in asio::xxx_socket::connection methods by using
translate_ec() which allowed to preserve the error code when possible (i.e.
when using Boost.ASIO with Boost.System or standalone ASIO with C++11
std::error_code), but errors also can happen in endpoint methods such as
handle_connect(), where they were totally lost and replaced with a rather
useless error::pass_through.

With these changes, the real error codes are preserved and applications using
the library can give more useful error messages if connection fails.
2017-06-04 16:50:14 +02:00
Vadim Zeitlin e6e14df950 Make asio::connection::xxx_socket::translate_ec() methods static
These methods don't need any object to operate on, so make them static to
allow calling them without an actual connection object at hand.
2017-06-04 01:56:59 +02:00
Alex Korotkin 527f401049 Fix unitialized shared_ptr in mock_endpoint 2017-05-17 09:54:14 +03:00
Alex Korotkin 00456642fa Fix the tls_handshake_timeout unit test failing due to server thread not having enough time to start 2017-05-17 09:48:33 +03:00
Alex Korotkin 7be37565ca Fix refused client connection due to servers not yet started
The server thread in a unit test may not have enough time to start and the
ongoing client connection will be refused. Fix this by adding sleep.
2017-05-16 18:13:11 +03:00
Alex Korotkin 5675036891 Fix unit test timers clashing between tests
If unit tests run long enough, then test timers fired for former unit tests can start to fail while running latter unit tests.
2017-05-16 16:51:43 +03:00
Alex Korotkin 4b6cfed3fc "stdint header included to fix uintXX_t compilation error" 2017-05-06 13:11:17 +03:00
Gregor Jasny 6578aaea02 Avoid undefined behaviour at circular shift
Clang UBSAN complains about 64 bit wide shifts.
2017-04-09 23:59:23 -07:00
Gregor Jasny 229134aa95 Add pre bind handler for listen socket
Within this handler socket options like IPV6_ONLY could be set.
2017-04-04 22:34:11 +02:00
Peter Taylor c7bef866e4 Fixed Capatialisation issue with submodule 2016-12-11 11:31:08 +00:00
emersont1 3ad502916e Added MinGW threading Capability 2016-12-08 18:41:49 +00:00
jbwdevries 7451e0c58b Merge pull request #1 from ronneke1996/implement_close_code_1014
Fixed typo in error message
2016-10-18 18:46:44 +02:00
Ron Nabuurs facb698845 Fixed typo in error message 2016-10-18 16:59:38 +02:00
Peter Thorson 37ce8abc77 Merge branch 'pr/593' into develop 2016-10-14 08:28:55 -05:00
Johan de Vries f94b3c0e4c Implemented close code 1014
Also adds two missing messages to get_string()
2016-10-10 10:05:15 +02:00
Peter Thorson 378437aecd Merge branch 'develop' 2016-02-22 08:30: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
38 changed files with 776 additions and 452 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = WebSocket++
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 0.8.0-dev
PROJECT_NUMBER = 0.8.1
# 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 a
+60
View File
@@ -1,4 +1,14 @@
HEAD
0.8.1 - 2018-07-16
Note: This release does not change library behavior. It only corrects issues
in the installer and test system.
- Test Suite: Adjust test suite to match behavior introduced in 0.8.0. Thank
you Gianfranco Costamagna for reporting and a patch. #731
- CMake: Update cmake installer to only install library files globally.
Thank you Gianfraco Costamanga for reporting and a patch. #732
0.8.0 - 2018-07-12
- Examples: Add `print_client` example. This demonstrates a minimal non-TLS
client that connects to a server and prints out the messages it receives.
- Examples: Add `print_client_tls` example. This demonstrates a minimal TLS
@@ -11,12 +21,48 @@ HEAD
rather than connection `pre_init`. This allows setting of socket options prior
to the bind/listen/accept system calls. Thank you ChristianRobl3D for
reporting #530.
- Improvement: Timers in transport integration tests should only fail if their
own test times out, rather than any test. #643 Thank you Alex Korotkin for
reporting and a patch.
- Improvement: Preserve transport layer error codes in more cases, particularly
during calls to `endpoint::listen`. #652 Thank you vadz for reporting and
patches.
- Compatibility: Make sure the chrono library used by Boost/Asio is in sync
with what the websocketpp is using. Thank you Flow86 for reporting and a
patch.
- Compatibility: Update `telemetry_client` to use a slightly more cross platform
method of sleeping. Should work on windows now. Thank you Meir Yanovich for
reporting.
- Compatibility: Updated permessage-deflate support to reflect that the zlib
library does not actually support a sliding window size of 256 bits.
WebSocket++ will no longer negotiate 256 bit deflate windows. If the user
of the library tries to request a 256 bit window a 512 bit window will be
specified instead (This was the previous behavior). #596 #653 Thank you
Vinnie Falco and Gianfranco Costamagna for reporting.
- Compatibility: Better error handling and logging in cases where extension
requests parse correctly but negotiation fails.
- Compatibility: Removed custom handling of `SSL_R_SHORT_READ` error condition.
This error code no longer exists in modern versions of OpenSSL and causes
a build error. It wasn't being used for anything particularly important
(slightly improving error reporting) and there isn't a great replacement.
#599 Thank you Gianfranco Costamagna for reporting.
- Compatibility: Add missing `<stdint>` headers. Fixes issues with g++ 5.4.0.
#638 Thank you Alex Korotkin for reporting and a patch.
- Compatibility: Remove the use of `std::auto_ptr` and `std::binary_function`
from builds with C++11 or later. These features are deprecated and were
removed entirely in C++17. This change allows building WebSocket++ on
C++17 compilers. #592 Thank you Michal Fojtak for reporting and a patch
- Compatibility: Add 1014 close code and adds missing descriptions for codes
1012 and 1013. #589 Thank you jbwdevries and ronneke1996 for reporting and
patches.
- Compatibility: Add hooks to support `mingw-std-threads` C++11 thread and mutex
polyfill library as an alternative to Boost. #608 Thank you Peter Taylor for
reporting and an initial patch.
- Compatibility: Changed the handshake connection token to 'Upgrade' from
'upgrade'. Technically this header is supposed to be processed case
insensitively. In practice, there are browsers (such as Edge) that don't do
this and they tend to use the uppercase value used as an example in RFC6455.
Thank you Johann Bauer for reporting and a patch. #727
- Bug: Store loggers in shared pointers to avoid crashes related to connections
trying to write logs entries after their respective endpoint has been
deallocated. Thank you Thalhammer for reporting and Jupp Müller for the
@@ -29,6 +75,16 @@ HEAD
- Bug/Documentation: Fix incorrect example code that used
`websocketpp::lib::error_code` instead of `websocketpp::exception`. Thank you
heretic13 for reporting
- Bug: Fix uninitialized shared pointer in Asio transport test suite. #647
Thank you Alex Korotkin for reporting and a patch.
- Bug: Fix a thread safety issue in the permessage-deflate extension that
caused message corruption when sending compressed messages from a different
thread than the main I/O thread. #615 Thank you KyleNyenhuis and Pieter De
Gendt for reporting and a patch.
- Bug: Fix an undefined behavior issue performing a 64 bit wide shift on a 64
bit value. #636 Thank you Gregor Jasny for reporting and a patch
- Bug: Fix some compile issues with ASIO_STANDALONE. #662 #665 Thank you
chronoxor and Guillaume Egles for reporting and patches.
0.7.0 - 2016-02-22
- MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method
@@ -42,6 +98,10 @@ HEAD
Muzahid Hussain for reporting and related code. #458
- Feature: Add support for subprotocols in Hybi00. Thank you Lukas Obermann
for reporting and a patch. #518
- Feature: Adds `tcp_pre_bind handler` to Asio transport. This allows setting
arbitrary socket options after the listen acceptor has been created but before
the socket bind has been performed. #634 #439 Thank you Gregor Jasny for
the patch.
- Improvement: Better automatic std::chrono feature detection for Visual Studio
- Improvement: Major refactoring to bundled CMake build system. CMake can now be
used to build all of the examples and the test suite. Thank you Thijs Wenker
+3 -6
View File
@@ -79,12 +79,9 @@ macro (final_target)
CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
endif ()
# install headers, directly from current source dir and look for subfolders with headers
file (GLOB_RECURSE TARGET_INSTALL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.hpp)
foreach (hppfile ${TARGET_INSTALL_HEADERS})
get_filename_component (currdir ${hppfile} PATH)
install (FILES ${hppfile} DESTINATION "include/${TARGET_NAME}/${currdir}")
endforeach()
install (DIRECTORY ${CMAKE_SOURCE_DIR}/${TARGET_NAME}
DESTINATION include/
FILES_MATCHING PATTERN "*.hpp*")
endmacro ()
macro (link_boost)
+6 -1
View File
@@ -72,12 +72,14 @@ To specify the type of an outgoing message, use the frame opcode values listed a
## Dependency Management
### Can WebSocket++ be used without Boost?
Yes. WebSocket++ only uses Boost features as polyfills for C++11 language features and libraries. If you have a C++11 compiler and standard library you can use WebSocket++ without Boost. In most cases setting your build environment to use the C++11 (or later) language dialect is sufficient to enable this mode of use.
Yes. WebSocket++ only uses Boost features as polyfills for C++11 language features and libraries. If you have a C++11 compiler and standard library you can use WebSocket++ without Boost. In most cases setting your build environment to use the C++11 (or later) language dialect is sufficient to enable this mode of use.
With less common compilers (and sometimes very recently release compilers) there may be specific issues with certain libraries that aren't automatically detected by the library. For these situations there are additional defines available to fine tune which C++11 libraries and features are used. TODO: more details about them.
For the iostream/raw transport the C++11 standard library is sufficient. For the Asio based transports, there is no C++11 library that provides the networking capabilaties that Asio does. As such even with a C++11 build system, you will need a standalone copy of Asio to use if Boost Asio is not available.
MinGW users who want to avoid Boost should also consult the nearby question about MinGW compatibility.
### Can WebSocket++ be used with standalone Asio
Yes. The process is the same as used with standalone Asio itself. Define `ASIO_STANDALONE` before including Asio or WebSocket++ headers. You will need to download a copy of the Asio headers separately (http://www.think-async.com) and make sure they are in your build system's include path.
@@ -91,6 +93,9 @@ The `<websocketpp/config/asio.hpp>` and `<websocketpp/config/asio_client.hpp>` h
### Build issues with TLS on recent versions of OS X
Mac OS X ships a severely outdated version of the OpenSSL library. To securely use TLS with WebSocket++ on OS X you will need to install a modern version of OpenSSL via homebrew or compiling from source.
### Can WebSocket++ be used with MinGW
Generally, yes. Note that in C++11 mode MinGW does not currently support the C++11 STL `<thread>` library. WebSocket++ requires a thread/mutex library. Options include Boost thread (the default when a compatible C++11 `<thread>` can't be found) or `mingw-std-threads` (https://github.com/meganz/mingw-std-threads) by including those headers and defining `_WEBSOCKETPP_MINGW_THREAD_`.
## Compression
### How do I use permessage-deflate in version 0.6.0-permessagedeflate and 0.7.0?
+1 -1
View File
@@ -179,7 +179,7 @@ int main() {
//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\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;
+1 -1
View File
@@ -1,4 +1,4 @@
WebSocket++ (0.8.0-dev)
WebSocket++ (0.8.1)
==========================
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
+17 -17
View File
@@ -217,8 +217,8 @@ BOOST_AUTO_TEST_CASE( connection_extensions ) {
}
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: ";
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: ";
output+=websocketpp::user_agent;
output+="\r\nUpgrade: websocket\r\n\r\n";
@@ -279,8 +279,8 @@ BOOST_AUTO_TEST_CASE( deferred_http_request ) {
}
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";
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("");
@@ -290,8 +290,8 @@ BOOST_AUTO_TEST_CASE( request_no_server_header ) {
}
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";
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("");
@@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE( request_no_server_header_override ) {
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 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";
@@ -326,13 +326,13 @@ BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
}
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";
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";
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.
@@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE( websocket_fail_parse_error ) {
}
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";
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);
@@ -373,7 +373,7 @@ BOOST_AUTO_TEST_CASE( websocket_fail_invalid_version ) {
}
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";
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);
@@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE( websocket_fail_unsupported_version ) {
}
// 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";
// 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);
@@ -429,14 +429,14 @@ BOOST_AUTO_TEST_CASE( websocket_fail_upgrade_required ) {
// 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 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";
// 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);
@@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
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";
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
@@ -501,7 +501,7 @@ BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
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";
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();
@@ -516,7 +516,7 @@ BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
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";
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();
+4 -1
View File
@@ -147,8 +147,11 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) {
server1.listen(ep1, ec);
BOOST_CHECK(!ec);
// This should return some sort of problem. Usually either "pass through" or
// a more specific address in use error. It is hard to capture the full range
// of 'correctly wrong' values.
server2.listen(ep1, ec);
BOOST_REQUIRE_EQUAL(ec, make_error_code(pass_through));
BOOST_REQUIRE(ec);
server2.listen(ep2, ec);
BOOST_CHECK(!ec);
+129 -26
View File
@@ -186,15 +186,22 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_invalid ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_valid ) {
ext_vars v;
// confirm that a request for a value of 8 is interpreted as 9
v.attr["server_max_window_bits"] = "8";
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
v.attr["server_max_window_bits"] = "9";
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; server_max_window_bits=9");
v.attr["server_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() );
@@ -213,7 +220,7 @@ BOOST_AUTO_TEST_CASE( invalid_set_server_max_window_bits ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_decline ) {
ext_vars v;
v.attr["server_max_window_bits"] = "8";
v.attr["server_max_window_bits"] = "9";
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::decline);
v.esp = v.exts.negotiate(v.attr);
@@ -223,7 +230,7 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_decline ) {
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_accept ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_accept_8 ) {
ext_vars v;
v.attr["server_max_window_bits"] = "8";
@@ -232,10 +239,22 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_accept ) {
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; server_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_largest ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_accept ) {
ext_vars v;
v.attr["server_max_window_bits"] = "9";
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::accept);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_largest_8 ) {
ext_vars v;
v.attr["server_max_window_bits"] = "8";
@@ -244,10 +263,22 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_largest ) {
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; server_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_smallest ) {
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_largest ) {
ext_vars v;
v.attr["server_max_window_bits"] = "9";
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::largest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_smallest_8 ) {
ext_vars v;
v.attr["server_max_window_bits"] = "8";
@@ -256,7 +287,19 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_smallest ) {
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; server_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_smallest ) {
ext_vars v;
v.attr["server_max_window_bits"] = "9";
v.ec = v.exts.set_server_max_window_bits(15,pmd_mode::smallest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; server_max_window_bits=9");
}
// Negotiate server_max_window_bits
@@ -292,7 +335,13 @@ BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_valid ) {
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; client_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
v.attr["client_max_window_bits"] = "9";
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; client_max_window_bits=9");
v.attr["client_max_window_bits"] = "15";
v.esp = v.exts.negotiate(v.attr);
@@ -311,7 +360,7 @@ BOOST_AUTO_TEST_CASE( invalid_set_client_max_window_bits ) {
BOOST_CHECK_EQUAL(v.ec,pmde::make_error_code(pmde::invalid_max_window_bits));
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_decline ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_decline_8 ) {
ext_vars v;
v.attr["client_max_window_bits"] = "8";
@@ -323,7 +372,19 @@ BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_decline ) {
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_accept ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_decline ) {
ext_vars v;
v.attr["client_max_window_bits"] = "9";
v.ec = v.exts.set_client_max_window_bits(9,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_client_max_window_bits_accept_8 ) {
ext_vars v;
v.attr["client_max_window_bits"] = "8";
@@ -332,10 +393,22 @@ BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_accept ) {
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; client_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_largest ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_accept ) {
ext_vars v;
v.attr["client_max_window_bits"] = "9";
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::accept);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_largest_8 ) {
ext_vars v;
v.attr["client_max_window_bits"] = "8";
@@ -344,10 +417,22 @@ BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_largest ) {
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; client_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_smallest ) {
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_largest ) {
ext_vars v;
v.attr["client_max_window_bits"] = "9";
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::largest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_smallest_8 ) {
ext_vars v;
v.attr["client_max_window_bits"] = "8";
@@ -356,7 +441,19 @@ BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_smallest ) {
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; client_max_window_bits=8");
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
BOOST_AUTO_TEST_CASE( negotiate_client_max_window_bits_smallest ) {
ext_vars v;
v.attr["client_max_window_bits"] = "9";
v.ec = v.exts.set_client_max_window_bits(15,pmd_mode::smallest);
v.esp = v.exts.negotiate(v.attr);
BOOST_CHECK( v.exts.is_enabled() );
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
BOOST_CHECK_EQUAL( v.esp.second, "permessage-deflate; client_max_window_bits=9");
}
@@ -507,7 +604,8 @@ BOOST_AUTO_TEST_CASE( compress_data ) {
std::string compress_out;
std::string decompress_out;
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -520,7 +618,8 @@ BOOST_AUTO_TEST_CASE( compress_data ) {
BOOST_AUTO_TEST_CASE( compress_data_multiple ) {
ext_vars v;
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
for (int i = 0; i < 2; i++) {
std::string compress_in = "Hello";
@@ -545,11 +644,12 @@ BOOST_AUTO_TEST_CASE( compress_data_large ) {
websocketpp::http::attribute_list alist;
alist["server_max_window_bits"] = "8";
v.exts.set_server_max_window_bits(8,websocketpp::extensions::permessage_deflate::mode::smallest);
alist["server_max_window_bits"] = "9";
v.exts.set_server_max_window_bits(9,websocketpp::extensions::permessage_deflate::mode::smallest);
v.exts.negotiate(alist);
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -573,7 +673,8 @@ BOOST_AUTO_TEST_CASE( compress_data_no_context_takeover ) {
v.exts.enable_server_no_context_takeover();
v.exts.negotiate(alist);
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.compress(compress_in,compress_out1);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -609,7 +710,8 @@ BOOST_AUTO_TEST_CASE( compress_empty ) {
std::string compress_out;
std::string decompress_out;
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.compress(compress_in,compress_out);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
@@ -640,7 +742,8 @@ BOOST_AUTO_TEST_CASE( decompress_data ) {
std::string out;
std::string reference = "Hello";
v.exts.init(true);
v.ec = v.exts.init(true);
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
v.ec = v.exts.decompress(in,11,out);
+6 -6
View File
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
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";
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");
@@ -79,7 +79,7 @@ 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";
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!");
@@ -93,7 +93,7 @@ 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";
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!");
@@ -107,7 +107,7 @@ 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";
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!");
@@ -121,7 +121,7 @@ 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";
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!");
@@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
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";
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!");
+6 -6
View File
@@ -66,7 +66,7 @@ typedef stub_config::message_type::ptr message_ptr;
BOOST_AUTO_TEST_CASE( exact_match ) {
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";
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");
@@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
BOOST_AUTO_TEST_CASE( non_get_method ) {
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";
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!");
@@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
BOOST_AUTO_TEST_CASE( old_http_version ) {
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";
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!");
@@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
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";
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!");
@@ -137,7 +137,7 @@ 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-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
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!");
@@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
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";
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!");
+7 -7
View File
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
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";
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());
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
p.process_handshake(r,"",response);
BOOST_CHECK_EQUAL(response.get_header("Connection"), "upgrade");
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=");
}
@@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
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";
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());
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
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";
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());
@@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
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";
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());
@@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
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";
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());
@@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
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:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n";
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());
+7 -7
View File
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
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";
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());
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
p.process_handshake(r,"",response);
BOOST_CHECK(response.get_header("Connection") == "upgrade");
BOOST_CHECK(response.get_header("Connection") == "Upgrade");
BOOST_CHECK(response.get_header("Upgrade") == "websocket");
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
}
@@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
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";
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());
@@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
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";
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());
@@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
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";
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());
@@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
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";
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());
@@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
websocketpp::uri_ptr u;
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";
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());
+7 -7
View File
@@ -120,7 +120,7 @@ struct processor_setup_ext {
BOOST_AUTO_TEST_CASE( exact_match ) {
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";
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());
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
env.p.process_handshake(env.req,"",env.res);
BOOST_CHECK_EQUAL(env.res.get_header("Connection"), "upgrade");
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=");
}
@@ -147,7 +147,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
BOOST_AUTO_TEST_CASE( non_get_method ) {
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";
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());
@@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE( non_get_method ) {
BOOST_AUTO_TEST_CASE( old_http_version ) {
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";
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());
@@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
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";
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());
@@ -183,7 +183,7 @@ 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";
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());
@@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
BOOST_AUTO_TEST_CASE( bad_host ) {
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";
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());
+2 -2
View File
@@ -37,7 +37,7 @@
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";
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());
@@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE( ci_exact_match ) {
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";
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());
+15 -15
View File
@@ -118,8 +118,8 @@ void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_
/* Tests */
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";
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");
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
}
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 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;
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
}
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 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";
@@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE( unimplemented_websocket_version ) {
}
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 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 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;
@@ -165,9 +165,9 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_empty ) {
}
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 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 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;
@@ -183,9 +183,9 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
}
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 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 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;
@@ -201,9 +201,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_one ) {
}
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 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 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;
@@ -219,9 +219,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
}
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 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 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;
@@ -237,7 +237,7 @@ 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 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;
+6 -1
View File
@@ -140,7 +140,10 @@ 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() {
mock_endpoint()
: alog(websocketpp::lib::make_shared<config::alog_type>())
, elog(websocketpp::lib::make_shared<config::elog_type>())
{
alog->set_channels(websocketpp::log::alevel::all);
base::init_logging(alog,elog);
init_asio();
@@ -182,6 +185,8 @@ BOOST_AUTO_TEST_CASE( tls_handshake_timeout ) {
dummy_server.detach();
timer.detach();
sleep(1); // give the server thread some time to start
mock_endpoint endpoint;
endpoint.set_tls_init_handler(&on_tls_init);
endpoint.connect("wss://localhost:9005");
+56 -22
View File
@@ -354,11 +354,35 @@ void close(T * e, websocketpp::connection_hdl hdl) {
e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,"");
}
// Wait for the specified time period then fail the test
void run_test_timer(long value) {
sleep(value);
BOOST_FAIL( "Test timed out" );
}
class test_deadline_timer
{
public:
test_deadline_timer(int seconds)
: m_timer(m_io_service, boost::posix_time::seconds(seconds))
{
m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1));
std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run;
m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_service));
}
~test_deadline_timer()
{
m_timer.cancel();
m_timer_thread.join();
}
private:
void expired(const boost::system::error_code & ec)
{
if (ec == boost::asio::error::operation_aborted)
return;
BOOST_CHECK(!ec);
BOOST_FAIL("Test timed out");
}
boost::asio::io_service m_io_service;
boost::asio::deadline_timer m_timer;
websocketpp::lib::thread m_timer_thread;
};
BOOST_AUTO_TEST_CASE( pong_no_timeout ) {
server s;
@@ -375,6 +399,8 @@ BOOST_AUTO_TEST_CASE( pong_no_timeout ) {
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
sleep(1); // give the server thread some time to start
// Run a client that closes the connection after 1 seconds
run_time_limited_client(c, "http://localhost:9005", 1, false);
@@ -398,8 +424,9 @@ BOOST_AUTO_TEST_CASE( pong_timeout ) {
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,10));
tthread.detach();
sleep(1); // give the server thread some time to start
test_deadline_timer deadline(10);
run_client(c, "http://localhost:9005",false);
@@ -416,9 +443,11 @@ 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,10));
sthread.detach();
tthread.detach();
sleep(1); // give the server thread some time to start
test_deadline_timer deadline(10);
run_client(c, "http://localhost:9005");
}
@@ -433,8 +462,10 @@ 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,10));
tthread.detach();
test_deadline_timer deadline(10);
sleep(1); // give the server thread some time to start
run_dummy_client("9005");
@@ -456,8 +487,10 @@ BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) {
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,10));
tthread.detach();
test_deadline_timer deadline(10);
sleep(1); // give the server thread some time to start
run_client(c, "http://localhost:9005", false);
@@ -488,10 +521,11 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
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,10));
tthread.detach();
test_deadline_timer deadline(10);
run_client(c, "http://localhost:9005",false);
sleep(1); // give the server thread some time to start
run_client(c, "http://localhost:9005", false);
sthread.join();
}
@@ -499,8 +533,7 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) {
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
client c;
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,3));
tthread.detach();
test_deadline_timer deadline(3);
websocketpp::lib::error_code ec;
c.init_asio(ec);
@@ -566,17 +599,18 @@ BOOST_AUTO_TEST_CASE( stop_listening ) {
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();
test_deadline_timer deadline(5);
run_client(c, "http://localhost:9005",false);
sleep(1); // give the server thread some time to start
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";
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)
-1
View File
@@ -39,7 +39,6 @@ using namespace websocketpp;
BOOST_AUTO_TEST_CASE( reserved_values ) {
BOOST_CHECK( !close::status::reserved(999) );
BOOST_CHECK( close::status::reserved(1004) );
BOOST_CHECK( close::status::reserved(1014) );
BOOST_CHECK( close::status::reserved(1016) );
BOOST_CHECK( close::status::reserved(2999) );
BOOST_CHECK( !close::status::reserved(1000) );
+12 -1
View File
@@ -142,6 +142,11 @@ namespace status {
/// or reconnect to the same IP upon user action.
static value const try_again_later = 1013;
/// Indicates that the server was acting as a gateway or proxy and received
/// an invalid response from the upstream server. This is similar to 502
/// HTTP Status Code.
static value const bad_gateway = 1014;
/// An endpoint failed to perform a TLS handshake
/**
* Designated for use in applications expecting a status code to indicate
@@ -178,7 +183,7 @@ namespace status {
*/
inline bool reserved(value code) {
return ((code >= rsv_start && code <= rsv_end) ||
code == 1004 || code == 1014);
code == 1004);
}
/// First value in range that is always invalid on the wire
@@ -248,6 +253,12 @@ namespace status {
return "Extension required";
case internal_endpoint_error:
return "Internal endpoint error";
case service_restart:
return "Service restart";
case try_again_later:
return "Try again later";
case bad_gateway:
return "Bad gateway";
case tls_handshake:
return "TLS handshake failure";
case subprotocol_error:
-1
View File
@@ -65,7 +65,6 @@ namespace lib {
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
using std::shared_ptr;
using std::weak_ptr;
using std::auto_ptr;
using std::enable_shared_from_this;
using std::static_pointer_cast;
using std::make_shared;
+6 -2
View File
@@ -51,7 +51,11 @@
#endif
#endif
#ifdef _WEBSOCKETPP_CPP11_THREAD_
#if defined(_WEBSOCKETPP_MINGW_THREAD_)
#include <mingw-threads/mingw.thread.h>
#include <mingw-threads/mingw.mutex.h>
#include <mingw-threads/mingw.condition_variable.h>
#elif defined(_WEBSOCKETPP_CPP11_THREAD_)
#include <thread>
#include <mutex>
#include <condition_variable>
@@ -64,7 +68,7 @@
namespace websocketpp {
namespace lib {
#ifdef _WEBSOCKETPP_CPP11_THREAD_
#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_)
using std::mutex;
using std::lock_guard;
using std::thread;
-9
View File
@@ -1633,15 +1633,6 @@ private:
session::http_state::value m_http_state;
bool m_was_clean;
/// Whether or not this endpoint initiated the closing handshake.
bool m_closed_by_me;
/// ???
bool m_failed_by_me;
/// Whether or not this endpoint initiated the drop of the TCP connection
bool m_dropped_by_me;
};
} // namespace websocketpp
@@ -29,6 +29,7 @@
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/http/constants.hpp>
@@ -32,6 +32,7 @@
#include <websocketpp/common/cpp11.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/platforms.hpp>
#include <websocketpp/common/stdint.hpp>
#include <websocketpp/common/system_error.hpp>
#include <websocketpp/error.hpp>
@@ -46,7 +47,7 @@
namespace websocketpp {
namespace extensions {
/// Implementation of the draft permessage-deflate WebSocket extension
/// Implementation of RFC 7692, the permessage-deflate WebSocket extension
/**
* ### permessage-deflate interface
*
@@ -174,18 +175,30 @@ namespace websocketpp {
namespace extensions {
namespace permessage_deflate {
/// Default value for server_max_window_bits as defined by draft 17
/// Default value for server_max_window_bits as defined by RFC 7692
static uint8_t const default_server_max_window_bits = 15;
/// Minimum value for server_max_window_bits as defined by draft 17
/// Minimum value for server_max_window_bits as defined by RFC 7692
/**
* NOTE: A value of 8 is not actually supported by zlib, the deflate
* library that WebSocket++ uses. To preserve backwards compatibility
* with RFC 7692 and previous versions of the library a value of 8
* is accepted by the library but will always be negotiated as 9.
*/
static uint8_t const min_server_max_window_bits = 8;
/// Maximum value for server_max_window_bits as defined by draft 17
/// Maximum value for server_max_window_bits as defined by RFC 7692
static uint8_t const max_server_max_window_bits = 15;
/// Default value for client_max_window_bits as defined by draft 17
/// Default value for client_max_window_bits as defined by RFC 7692
static uint8_t const default_client_max_window_bits = 15;
/// Minimum value for client_max_window_bits as defined by draft 17
/// Minimum value for client_max_window_bits as defined by RFC 7692
/**
* NOTE: A value of 8 is not actually supported by zlib, the deflate
* library that WebSocket++ uses. To preserve backwards compatibility
* with RFC 7692 and previous versions of the library a value of 8
* is accepted by the library but will always be negotiated as 9.
*/
static uint8_t const min_client_max_window_bits = 8;
/// Maximum value for client_max_window_bits as defined by draft 17
/// Maximum value for client_max_window_bits as defined by RFC 7692
static uint8_t const max_client_max_window_bits = 15;
namespace mode {
@@ -213,7 +226,7 @@ public:
, m_server_max_window_bits_mode(mode::accept)
, m_client_max_window_bits_mode(mode::accept)
, m_initialized(false)
, m_compress_buffer_size(16384)
, m_compress_buffer_size(8192)
{
m_dstate.zalloc = Z_NULL;
m_dstate.zfree = Z_NULL;
@@ -292,6 +305,7 @@ public:
}
m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]);
if ((m_server_no_context_takeover && is_server) ||
(m_client_no_context_takeover && !is_server))
{
@@ -372,7 +386,7 @@ public:
/**
* The bits setting is the base 2 logarithm of the maximum window size that
* the server must use to compress outgoing messages. The permitted range
* is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB
* is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB
* window. The default setting is 15.
*
* Mode Options:
@@ -386,6 +400,14 @@ public:
* adjusted by the server. A server may unilaterally set this value without
* client support.
*
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
* zlib, the deflate compression library that WebSocket++ uses has always
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
* continues to perform the 8->9 conversion for backwards compatibility
* purposes but this should be considered deprecated functionality.
*
* @param bits The size to request for the outgoing window size
* @param mode The mode to use for negotiating this parameter
* @return A status code
@@ -394,6 +416,12 @@ public:
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
return error::make_error_code(error::invalid_max_window_bits);
}
// See note in doc comment above about what is happening here
if (bits == 8) {
bits = 9;
}
m_server_max_window_bits = bits;
m_server_max_window_bits_mode = mode;
@@ -403,8 +431,8 @@ public:
/// Limit client LZ77 sliding window size
/**
* The bits setting is the base 2 logarithm of the window size that the
* client must use to compress outgoing messages. The permitted range is 8
* to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window.
* client must use to compress outgoing messages. The permitted range is 9
* to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window.
* The default setting is 15.
*
* Mode Options:
@@ -417,6 +445,14 @@ public:
* outgoing window size unilaterally. A server may only limit the client's
* window size if the remote client supports that feature.
*
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
* zlib, the deflate compression library that WebSocket++ uses has always
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
* continues to perform the 8->9 conversion for backwards compatibility
* purposes but this should be considered deprecated functionality.
*
* @param bits The size to request for the outgoing window size
* @param mode The mode to use for negotiating this parameter
* @return A status code
@@ -425,6 +461,12 @@ public:
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
return error::make_error_code(error::invalid_max_window_bits);
}
// See note in doc comment above about what is happening here
if (bits == 8) {
bits = 9;
}
m_client_max_window_bits = bits;
m_client_max_window_bits_mode = mode;
@@ -555,7 +597,7 @@ public:
do {
m_istate.avail_out = m_compress_buffer_size;
m_istate.next_out = m_compress_buffer.get();
m_istate.next_out = m_decompress_buffer.get();
ret = inflate(&m_istate, Z_SYNC_FLUSH);
@@ -564,7 +606,7 @@ public:
}
out.append(
reinterpret_cast<char *>(m_compress_buffer.get()),
reinterpret_cast<char *>(m_decompress_buffer.get()),
m_compress_buffer_size - m_istate.avail_out
);
} while (m_istate.avail_out == 0);
@@ -642,11 +684,17 @@ private:
* client requested that we use.
*
* options:
* - decline (refuse to use the attribute)
* - accept (use whatever the client says)
* - largest (use largest possible value)
* - decline (ignore value, offer our default instead)
* - accept (use the value requested by the client)
* - largest (use largest value acceptable to both)
* - smallest (use smallest possible value)
*
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
* be requested for negotiation by an older client/server, if the result of
* the negotiation would be to send a value of 8, a value of 9 is offered
* instead. This ensures that WebSocket++ will only ever negotiate connections
* with compression settings explicitly supported by zlib.
*
* @param [in] value The value of the attribute from the offer
* @param [out] ec A reference to the error code to return errors via
*/
@@ -678,6 +726,11 @@ private:
ec = make_error_code(error::invalid_mode);
m_server_max_window_bits = default_server_max_window_bits;
}
// See note in doc comment
if (m_server_max_window_bits == 8) {
m_server_max_window_bits = 9;
}
}
/// Negotiate client_max_window_bits attribute
@@ -687,11 +740,17 @@ private:
* negotiation mode.
*
* options:
* - decline (refuse to use the attribute)
* - accept (use whatever the client says)
* - largest (use largest possible value)
* - decline (ignore value, offer our default instead)
* - accept (use the value requested by the client)
* - largest (use largest value acceptable to both)
* - smallest (use smallest possible value)
*
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
* be requested for negotiation by an older client/server, if the result of
* the negotiation would be to send a value of 8, a value of 9 is offered
* instead. This ensures that WebSocket++ will only ever negotiate connections
* with compression settings explicitly supported by zlib.
*
* @param [in] value The value of the attribute from the offer
* @param [out] ec A reference to the error code to return errors via
*/
@@ -727,6 +786,11 @@ private:
ec = make_error_code(error::invalid_mode);
m_client_max_window_bits = default_client_max_window_bits;
}
// See note in doc comment
if (m_client_max_window_bits == 8) {
m_client_max_window_bits = 9;
}
}
bool m_enabled;
@@ -741,6 +805,7 @@ private:
int m_flush;
size_t m_compress_buffer_size;
lib::unique_ptr_uchar_array m_compress_buffer;
lib::unique_ptr_uchar_array m_decompress_buffer;
z_stream m_dstate;
z_stream m_istate;
};
+3
View File
@@ -610,6 +610,9 @@ inline size_t prepare_masking_key(const masking_key_type& key) {
* to zero and less than sizeof(size_t).
*/
inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
if (offset == 0) {
return prepared_key;
}
if (lib::net::is_little_endian()) {
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
return (prepared_key >> offset*8) | temp;
+17 -14
View File
@@ -999,19 +999,16 @@ void connection<config>::handle_read_frame(lib::error_code const & ec,
"handle_read_frame: got invalid istate in closed state");
return;
}
} else if (ecm == transport::error::tls_short_read) {
if (m_state == session::state::closed) {
// We expect to get a TLS short read if we try to read after the
// connection is closed. If this happens ignore and exit the
// read frame path.
terminate(lib::error_code());
return;
}
echannel = log::elevel::rerror;
} else if (ecm == transport::error::action_after_shutdown) {
echannel = log::elevel::info;
} else {
// TODO: more generally should we do something different here in the
// case that m_state is cosed? Are errors after the connection is
// already closed really an rerror?
}
log_err(echannel, "handle_read_frame", ecm);
this->terminate(ecm);
return;
@@ -1222,12 +1219,18 @@ lib::error_code connection<config>::process_handshake_request() {
std::pair<lib::error_code,std::string> neg_results;
neg_results = m_processor->negotiate_extensions(m_request);
if (neg_results.first) {
if (neg_results.first == processor::error::make_error_code(processor::error::extension_parse_error)) {
// There was a fatal error in extension parsing that should result in
// a failed connection attempt.
m_alog->write(log::alevel::devel, "Bad request: " + neg_results.first.message());
m_elog->write(log::elevel::info, "Bad request: " + neg_results.first.message());
m_response.set_status(http::status_code::bad_request);
return neg_results.first;
} else if (neg_results.first) {
// There was a fatal error in extension processing that is probably our
// fault. Consider extension negotiation to have failed and continue as
// if extensions were not supported
m_elog->write(log::elevel::info,
"Extension negotiation failed: " + neg_results.first.message());
} else {
// extension negotiation succeeded, set response header accordingly
// we don't send an empty extensions header because it breaks many
@@ -2174,7 +2177,7 @@ connection<config>::get_processor(int version) const {
transport_con_type::is_secure(),
m_is_server,
m_msg_manager,
lib::ref(m_rng)
m_rng
);
break;
case 8:
@@ -2182,7 +2185,7 @@ connection<config>::get_processor(int version) const {
transport_con_type::is_secure(),
m_is_server,
m_msg_manager,
lib::ref(m_rng)
m_rng
);
break;
case 13:
@@ -2190,7 +2193,7 @@ connection<config>::get_processor(int version) const {
transport_con_type::is_secure(),
m_is_server,
m_msg_manager,
lib::ref(m_rng)
m_rng
);
break;
default:
+1 -1
View File
@@ -45,7 +45,7 @@ endpoint<connection,config>::create_connection() {
//scoped_lock_type guard(m_mutex);
// Create a connection on the heap and manage it using a shared pointer
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
m_user_agent, m_alog, m_elog, lib::ref(m_rng));
m_user_agent, m_alog, m_elog, m_rng);
connection_weak_ptr w(con);
+1 -1
View File
@@ -44,7 +44,7 @@ namespace processor {
namespace constants {
static char const upgrade_token[] = "websocket";
static char const connection_token[] = "upgrade";
static char const connection_token[] = "Upgrade";
static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
} // namespace constants
+46 -24
View File
@@ -125,38 +125,60 @@ public:
http::parameter_list::const_iterator it;
// look through the list of extension requests to find the first
// one that we can accept.
if (m_permessage_deflate.is_implemented()) {
err_str_pair neg_ret;
for (it = p.begin(); it != p.end(); ++it) {
// look through each extension, if the key is permessage-deflate
if (it->first == "permessage-deflate") {
// if we have already successfully negotiated this extension
// then skip any other requests to negotiate the same one
// with different parameters
if (m_permessage_deflate.is_enabled()) {
continue;
}
neg_ret = m_permessage_deflate.negotiate(it->second);
// not a permessage-deflate extension request, ignore
if (it->first != "permessage-deflate") {
continue;
}
if (neg_ret.first) {
// Figure out if this is an error that should halt all
// extension negotiations or simply cause negotiation of
// this specific extension to fail.
//std::cout << "permessage-compress negotiation failed: "
// << neg_ret.first.message() << std::endl;
} else {
// Note: this list will need commas if WebSocket++ ever
// supports more than one extension
ret.second += neg_ret.second;
m_permessage_deflate.init(base::m_server);
continue;
}
// if we have already successfully negotiated this extension
// then skip any other requests to negotiate the same one
// with different parameters
if (m_permessage_deflate.is_enabled()) {
continue;
}
// attempt to negotiate this offer
neg_ret = m_permessage_deflate.negotiate(it->second);
if (neg_ret.first) {
// negotiation offer failed. Do nothing. We will continue
// searching for a permessage-deflate config that succeeds
continue;
}
// Negotiation tentatively succeeded
// Actually try to initialize the extension before we
// deem negotiation complete
lib::error_code ec = m_permessage_deflate.init(base::m_server);
if (ec) {
// Negotiation succeeded but initialization failed this is
// an error that should stop negotiation of permessage
// deflate. Return the reason for the init failure
ret.first = ec;
break;
} else {
// Successfully initialized, push the negotiated response into
// the reply and stop looking for additional permessage-deflate
// extensions
ret.second += neg_ret.second;
break;
}
}
}
// support for future extensions would go here. Should check the value of
// ret.first before continuing. Might need to consider whether failure of
// negotiation of an earlier extension should stop negotiation of subsequent
// ones
return ret;
}
+189 -189
View File
@@ -1,189 +1,189 @@
/*
*****
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1
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.
*/
#ifndef SHA1_DEFINED
#define SHA1_DEFINED
namespace websocketpp {
namespace sha1 {
namespace { // local
// Rotate an integer value to left.
inline unsigned int rol(unsigned int value, unsigned int steps) {
return ((value << steps) | (value >> (32 - steps)));
}
// Sets the first 16 integers in the buffert to zero.
// Used for clearing the W buffert.
inline void clearWBuffert(unsigned int * buffert)
{
for (int pos = 16; --pos >= 0;)
{
buffert[pos] = 0;
}
}
inline void innerHash(unsigned int * result, unsigned int * w)
{
unsigned int a = result[0];
unsigned int b = result[1];
unsigned int c = result[2];
unsigned int d = result[3];
unsigned int e = result[4];
int round = 0;
#define sha1macro(func,val) \
{ \
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
e = d; \
d = c; \
c = rol(b, 30); \
b = a; \
a = t; \
}
while (round < 16)
{
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 20)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 40)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0x6ed9eba1)
++round;
}
while (round < 60)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
++round;
}
while (round < 80)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0xca62c1d6)
++round;
}
#undef sha1macro
result[0] += a;
result[1] += b;
result[2] += c;
result[3] += d;
result[4] += e;
}
} // namespace
/// Calculate a SHA1 hash
/**
* @param src points to any kind of data to be hashed.
* @param bytelength the number of bytes to hash from the src pointer.
* @param hash should point to a buffer of at least 20 bytes of size for storing
* the sha1 result in.
*/
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
// Init the result array.
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
0x10325476, 0xc3d2e1f0 };
// Cast the void src pointer to be the byte array we can work with.
unsigned char const * sarray = (unsigned char const *) src;
// The reusable round buffer
unsigned int w[80];
// Loop through all complete 64byte blocks.
size_t endCurrentBlock;
size_t currentBlock = 0;
if (bytelength >= 64) {
size_t const endOfFullBlocks = bytelength - 64;
while (currentBlock <= endOfFullBlocks) {
endCurrentBlock = currentBlock + 64;
// Init the round buffer with the 64 byte block data.
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
{
// This line will swap endian on big endian and keep endian on
// little endian.
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
| (((unsigned int) sarray[currentBlock + 2]) << 8)
| (((unsigned int) sarray[currentBlock + 1]) << 16)
| (((unsigned int) sarray[currentBlock]) << 24);
}
innerHash(result, w);
}
}
// Handle the last and not full 64 byte block if existing.
endCurrentBlock = bytelength - currentBlock;
clearWBuffert(w);
size_t lastBlockBytes = 0;
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
}
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
if (endCurrentBlock >= 56) {
innerHash(result, w);
clearWBuffert(w);
}
w[15] = bytelength << 3;
innerHash(result, w);
// Store hash in result pointer, and make sure we get in in the correct
// order on both endian models.
for (int hashByte = 20; --hashByte >= 0;) {
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
}
}
} // namespace sha1
} // namespace websocketpp
#endif // SHA1_DEFINED
/*
*****
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1
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.
*/
#ifndef SHA1_DEFINED
#define SHA1_DEFINED
namespace websocketpp {
namespace sha1 {
namespace { // local
// Rotate an integer value to left.
inline unsigned int rol(unsigned int value, unsigned int steps) {
return ((value << steps) | (value >> (32 - steps)));
}
// Sets the first 16 integers in the buffert to zero.
// Used for clearing the W buffert.
inline void clearWBuffert(unsigned int * buffert)
{
for (int pos = 16; --pos >= 0;)
{
buffert[pos] = 0;
}
}
inline void innerHash(unsigned int * result, unsigned int * w)
{
unsigned int a = result[0];
unsigned int b = result[1];
unsigned int c = result[2];
unsigned int d = result[3];
unsigned int e = result[4];
int round = 0;
#define sha1macro(func,val) \
{ \
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
e = d; \
d = c; \
c = rol(b, 30); \
b = a; \
a = t; \
}
while (round < 16)
{
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 20)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 40)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0x6ed9eba1)
++round;
}
while (round < 60)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
++round;
}
while (round < 80)
{
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0xca62c1d6)
++round;
}
#undef sha1macro
result[0] += a;
result[1] += b;
result[2] += c;
result[3] += d;
result[4] += e;
}
} // namespace
/// Calculate a SHA1 hash
/**
* @param src points to any kind of data to be hashed.
* @param bytelength the number of bytes to hash from the src pointer.
* @param hash should point to a buffer of at least 20 bytes of size for storing
* the sha1 result in.
*/
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
// Init the result array.
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
0x10325476, 0xc3d2e1f0 };
// Cast the void src pointer to be the byte array we can work with.
unsigned char const * sarray = (unsigned char const *) src;
// The reusable round buffer
unsigned int w[80];
// Loop through all complete 64byte blocks.
size_t endCurrentBlock;
size_t currentBlock = 0;
if (bytelength >= 64) {
size_t const endOfFullBlocks = bytelength - 64;
while (currentBlock <= endOfFullBlocks) {
endCurrentBlock = currentBlock + 64;
// Init the round buffer with the 64 byte block data.
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
{
// This line will swap endian on big endian and keep endian on
// little endian.
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
| (((unsigned int) sarray[currentBlock + 2]) << 8)
| (((unsigned int) sarray[currentBlock + 1]) << 16)
| (((unsigned int) sarray[currentBlock]) << 24);
}
innerHash(result, w);
}
}
// Handle the last and not full 64 byte block if existing.
endCurrentBlock = bytelength - currentBlock;
clearWBuffert(w);
size_t lastBlockBytes = 0;
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
}
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
if (endCurrentBlock >= 56) {
innerHash(result, w);
clearWBuffert(w);
}
w[15] = bytelength << 3;
innerHash(result, w);
// Store hash in result pointer, and make sure we get in in the correct
// order on both endian models.
for (int hashByte = 20; --hashByte >= 0;) {
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
}
}
} // namespace sha1
} // namespace websocketpp
#endif // SHA1_DEFINED
+6 -13
View File
@@ -312,7 +312,7 @@ public:
*/
timer_ptr set_timer(long duration, timer_handler callback) {
timer_ptr new_timer = lib::make_shared<lib::asio::steady_timer>(
lib::ref(*m_io_service),
*m_io_service,
lib::asio::milliseconds(duration)
);
@@ -462,7 +462,7 @@ protected:
if (config::enable_multithreading) {
m_strand = lib::make_shared<lib::asio::io_service::strand>(
lib::ref(*io_service));
*io_service);
}
lib::error_code ec = socket_con_type::init_asio(io_service, m_strand,
@@ -1116,17 +1116,10 @@ protected:
tec = socket_con_type::translate_ec(ec);
m_tec = ec;
if (tec == transport::error::tls_short_read) {
// TLS short read at this point is somewhat expected if both
// sides try and end the connection at the same time or if
// SSLv2 is being used. In general there is nothing that can
// be done here other than a low level development log.
} else {
// all other errors are effectively pass through errors of
// some sort so print some detail on the info channel for
// library users to look up if needed.
log_err(log::elevel::info,"asio async_shutdown",ec);
}
// all other errors are effectively pass through errors of
// some sort so print some detail on the info channel for
// library users to look up if needed.
log_err(log::elevel::info,"asio async_shutdown",ec);
}
} else {
if (m_alog->static_test(log::alevel::devel)) {
+57 -24
View File
@@ -88,6 +88,9 @@ public:
/// Type of a shared pointer to an io_service work object
typedef lib::shared_ptr<lib::asio::io_service::work> work_ptr;
/// Type of socket pre-bind handler
typedef lib::function<lib::error_code(acceptor_ptr)> tcp_pre_bind_handler;
// generate and manage our own io_service
explicit endpoint()
: m_io_service(NULL)
@@ -193,7 +196,7 @@ public:
m_io_service = ptr;
m_external_io_service = true;
m_acceptor = lib::make_shared<lib::asio::ip::tcp::acceptor>(
lib::ref(*m_io_service));
*m_io_service);
m_state = READY;
ec = lib::error_code();
@@ -260,6 +263,19 @@ public:
m_external_io_service = false;
}
/// Sets the tcp pre bind handler
/**
* The tcp pre bind handler is called after the listen acceptor has
* been created but before the socket bind is performed.
*
* @since 0.8.0
*
* @param h The handler to call on tcp pre bind init.
*/
void set_tcp_pre_bind_handler(tcp_pre_bind_handler h) {
m_tcp_pre_bind_handler = h;
}
/// Sets the tcp pre init handler
/**
* The tcp pre init handler is called after the raw tcp connection has been
@@ -409,27 +425,33 @@ public:
lib::asio::error_code bec;
m_acceptor->open(ep.protocol(),bec);
if (!bec) {
m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec);
}
if (!bec) {
m_acceptor->bind(ep,bec);
}
if (!bec) {
m_acceptor->listen(m_listen_backlog,bec);
}
if (bec) {
if (m_acceptor->is_open()) {
m_acceptor->close();
if (bec) {ec = clean_up_listen_after_error(bec);return;}
m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec);
if (bec) {ec = clean_up_listen_after_error(bec);return;}
// if a TCP pre-bind handler is present, run it
if (m_tcp_pre_bind_handler) {
ec = m_tcp_pre_bind_handler(m_acceptor);
if (ec) {
ec = clean_up_listen_after_error(ec);
return;
}
log_err(log::elevel::info,"asio listen",bec);
ec = make_error_code(error::pass_through);
} else {
m_state = LISTENING;
ec = lib::error_code();
}
m_acceptor->bind(ep,bec);
if (bec) {ec = clean_up_listen_after_error(bec);return;}
m_acceptor->listen(m_listen_backlog,bec);
if (bec) {ec = clean_up_listen_after_error(bec);return;}
// Success
m_state = LISTENING;
ec = lib::error_code();
}
/// Set up endpoint for listening manually
/**
* Bind the internal acceptor using the settings specified by the endpoint e
@@ -667,7 +689,7 @@ public:
*/
void start_perpetual() {
m_work = lib::make_shared<lib::asio::io_service::work>(
lib::ref(*m_io_service)
*m_io_service
);
}
@@ -733,7 +755,7 @@ public:
m_elog->write(log::elevel::info,
"asio handle_timer error: "+ec.message());
log_err(log::elevel::info,"asio handle_timer",ec);
callback(make_error_code(error::pass_through));
callback(socket_con_type::translate_ec(ec));
}
} else {
callback(lib::error_code());
@@ -818,7 +840,7 @@ protected:
ret_ec = make_error_code(websocketpp::error::operation_canceled);
} else {
log_err(log::elevel::info,"asio handle_accept",asio_ec);
ret_ec = make_error_code(error::pass_through);
ret_ec = socket_con_type::translate_ec(asio_ec);
}
}
@@ -833,7 +855,7 @@ protected:
// Create a resolver
if (!m_resolver) {
m_resolver = lib::make_shared<lib::asio::ip::tcp::resolver>(
lib::ref(*m_io_service));
*m_io_service);
}
tcon->set_uri(u);
@@ -961,7 +983,7 @@ protected:
if (ec) {
log_err(log::elevel::info,"asio async_resolve",ec);
callback(make_error_code(error::pass_through));
callback(socket_con_type::translate_ec(ec));
return;
}
@@ -1069,7 +1091,7 @@ protected:
if (ec) {
log_err(log::elevel::info,"asio async_connect",ec);
callback(make_error_code(error::pass_through));
callback(socket_con_type::translate_ec(ec));
return;
}
@@ -1118,6 +1140,16 @@ private:
m_elog->write(l,s.str());
}
/// Helper for cleaning up in the listen method after an error
template <typename error_type>
lib::error_code clean_up_listen_after_error(error_type const & ec) {
if (m_acceptor->is_open()) {
m_acceptor->close();
}
log_err(log::elevel::info,"asio listen",ec);
return socket_con_type::translate_ec(ec);
}
enum state {
UNINITIALIZED = 0,
READY = 1,
@@ -1125,6 +1157,7 @@ private:
};
// Handlers
tcp_pre_bind_handler m_tcp_pre_bind_handler;
tcp_init_handler m_tcp_pre_init_handler;
tcp_init_handler m_tcp_post_init_handler;
+5 -2
View File
@@ -169,7 +169,7 @@ protected:
}
m_socket = lib::make_shared<lib::asio::ip::tcp::socket>(
lib::ref(*service));
*service);
if (m_socket_init_handler) {
m_socket_init_handler(m_hdl, *m_socket);
@@ -261,6 +261,7 @@ protected:
return lib::error_code();
}
public:
/// Translate any security policy specific information about an error code
/**
* Translate_ec takes an Asio error code and attempts to convert its value
@@ -280,11 +281,13 @@ protected:
* @return The translated error code
*/
template <typename ErrorCodeType>
static
lib::error_code translate_ec(ErrorCodeType) {
// We don't know any more information about this error so pass through
return make_error_code(transport::error::pass_through);
}
static
/// Overload of translate_ec to catch cases where lib::error_code is the
/// same type as lib::asio::error_code
lib::error_code translate_ec(lib::error_code ec) {
+8 -17
View File
@@ -194,7 +194,7 @@ protected:
return socket::make_error_code(socket::error::invalid_tls_context);
}
m_socket = lib::make_shared<socket_type>(
_WEBSOCKETPP_REF(*service),lib::ref(*m_context));
_WEBSOCKETPP_REF(*service),*m_context);
if (m_socket_init_handler) {
m_socket_init_handler(m_hdl, get_socket());
@@ -333,6 +333,7 @@ protected:
}
}
public:
/// Translate any security policy specific information about an error code
/**
* Translate_ec takes an Asio error code and attempts to convert its value
@@ -353,33 +354,23 @@ protected:
* @return The translated error code
*/
template <typename ErrorCodeType>
static
lib::error_code translate_ec(ErrorCodeType ec) {
if (ec.category() == lib::asio::error::get_ssl_category()) {
if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) {
return make_error_code(transport::error::tls_short_read);
} else {
// We know it is a TLS related error, but otherwise don't know
// more. Pass through as TLS generic.
return make_error_code(transport::error::tls_error);
}
// We know it is a TLS related error, but otherwise don't know more.
// Pass through as TLS generic.
return make_error_code(transport::error::tls_error);
} else {
// We don't know any more information about this error so pass
// through
return make_error_code(transport::error::pass_through);
}
}
static
/// Overload of translate_ec to catch cases where lib::error_code is the
/// same type as lib::asio::error_code
lib::error_code translate_ec(lib::error_code ec) {
// Normalize the tls_short_read error as it is used by the library and
// needs a consistent value. All other errors pass through natively.
// TODO: how to get the SSL category from std::error?
/*if (ec.category() == lib::asio::error::get_ssl_category()) {
if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) {
return make_error_code(transport::error::tls_short_read);
}
}*/
return ec;
}
private:
+1
View File
@@ -31,6 +31,7 @@
#include <websocketpp/error.hpp>
#include <websocketpp/common/memory.hpp>
#include <websocketpp/common/stdint.hpp>
#include <algorithm>
#include <sstream>
+2 -4
View File
@@ -72,11 +72,9 @@ private:
* Based on code from
* http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find
*/
struct ci_less : std::binary_function<std::string, std::string, bool> {
struct ci_less {
// case-independent (ci) compare_less binary function
struct nocase_compare
: public std::binary_function<unsigned char,unsigned char,bool>
{
struct nocase_compare {
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
return tolower (c1) < tolower (c2);
}
+3 -3
View File
@@ -44,17 +44,17 @@ static int const major_version = 0;
/// Library minor version number
static int const minor_version = 8;
/// Library patch version number
static int const patch_version = 0;
static int const patch_version = 1;
/// Library pre-release flag
/**
* This is a textual flag indicating the type and number for pre-release
* versions (dev, alpha, beta, rc). This will be blank for release versions.
*/
static char const prerelease_flag[] = "dev";
static char const prerelease_flag[] = "";
/// Default user agent string
static char const user_agent[] = "WebSocket++/0.8.0-dev";
static char const user_agent[] = "WebSocket++/0.8.1";
} // namespace websocketpp