Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a885d5cc4 | ||
|
|
c6d7e295bf | ||
|
|
c43242523c | ||
|
|
12b8f37cf5 | ||
|
|
6b8dfe02c2 | ||
|
|
e99aef04c3 | ||
|
|
5c48a114f4 | ||
|
|
c2fd89bede | ||
|
|
c612a35f06 | ||
|
|
99d169f586 | ||
|
|
241741ba01 | ||
|
|
702b6a919b | ||
|
|
19cad9925f | ||
|
|
c4050979c3 | ||
|
|
7e8c8a8fad | ||
|
|
88de392422 | ||
|
|
e79e0d1f94 | ||
|
|
bc12b81b29 | ||
|
|
8bc11bdf24 | ||
|
|
1cb045d946 | ||
|
|
2a36e41a9a | ||
|
|
0e1fc63b83 | ||
|
|
0b0871d879 | ||
|
|
20c67910e1 | ||
|
|
e943c9e1ed | ||
|
|
749b119b6b | ||
|
|
e9c65467b3 | ||
|
|
b34a1786bc | ||
|
|
e50ed8c1b1 | ||
|
|
67224f71b5 | ||
|
|
0b2e14ee3a | ||
|
|
1cb9666036 | ||
|
|
cb3d7de91f | ||
|
|
9baab8faa9 | ||
|
|
6330286ad5 | ||
|
|
cb4cf66911 | ||
|
|
99e1a99633 | ||
|
|
96b2d42c83 | ||
|
|
bc04ae4f5f | ||
|
|
ee74047c2d | ||
|
|
2819d364d9 | ||
|
|
d282738c81 | ||
|
|
a32eb0887b | ||
|
|
6645fcb390 | ||
|
|
29bb4ada91 | ||
|
|
ac9164c3b5 | ||
|
|
4cab5e5c0c | ||
|
|
16d126ee61 | ||
|
|
9ddb300d87 | ||
|
|
81ef065ccf | ||
|
|
e6e14df950 | ||
|
|
527f401049 | ||
|
|
00456642fa | ||
|
|
7be37565ca | ||
|
|
5675036891 | ||
|
|
4b6cfed3fc | ||
|
|
6578aaea02 | ||
|
|
229134aa95 | ||
|
|
c7bef866e4 | ||
|
|
3ad502916e | ||
|
|
7451e0c58b | ||
|
|
facb698845 | ||
|
|
37ce8abc77 | ||
|
|
f94b3c0e4c | ||
|
|
378437aecd | ||
|
|
7f19b6ea95 | ||
|
|
5b99feef7f |
No files matched your search
@@ -38,7 +38,7 @@ PROJECT_NAME = WebSocket++
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# 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
|
# 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
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
HEAD
|
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
|
- Examples: Add `print_client` example. This demonstrates a minimal non-TLS
|
||||||
client that connects to a server and prints out the messages it receives.
|
client that connects to a server and prints out the messages it receives.
|
||||||
- Examples: Add `print_client_tls` example. This demonstrates a minimal TLS
|
- 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
|
rather than connection `pre_init`. This allows setting of socket options prior
|
||||||
to the bind/listen/accept system calls. Thank you ChristianRobl3D for
|
to the bind/listen/accept system calls. Thank you ChristianRobl3D for
|
||||||
reporting #530.
|
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
|
- 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
|
with what the websocketpp is using. Thank you Flow86 for reporting and a
|
||||||
patch.
|
patch.
|
||||||
- Compatibility: Update `telemetry_client` to use a slightly more cross platform
|
- Compatibility: Update `telemetry_client` to use a slightly more cross platform
|
||||||
method of sleeping. Should work on windows now. Thank you Meir Yanovich for
|
method of sleeping. Should work on windows now. Thank you Meir Yanovich for
|
||||||
reporting.
|
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
|
- Bug: Store loggers in shared pointers to avoid crashes related to connections
|
||||||
trying to write logs entries after their respective endpoint has been
|
trying to write logs entries after their respective endpoint has been
|
||||||
deallocated. Thank you Thalhammer for reporting and Jupp Müller for the
|
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
|
- Bug/Documentation: Fix incorrect example code that used
|
||||||
`websocketpp::lib::error_code` instead of `websocketpp::exception`. Thank you
|
`websocketpp::lib::error_code` instead of `websocketpp::exception`. Thank you
|
||||||
heretic13 for reporting
|
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
|
0.7.0 - 2016-02-22
|
||||||
- MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method
|
- MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method
|
||||||
@@ -42,6 +98,10 @@ HEAD
|
|||||||
Muzahid Hussain for reporting and related code. #458
|
Muzahid Hussain for reporting and related code. #458
|
||||||
- Feature: Add support for subprotocols in Hybi00. Thank you Lukas Obermann
|
- Feature: Add support for subprotocols in Hybi00. Thank you Lukas Obermann
|
||||||
for reporting and a patch. #518
|
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: Better automatic std::chrono feature detection for Visual Studio
|
||||||
- Improvement: Major refactoring to bundled CMake build system. CMake can now be
|
- 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
|
used to build all of the examples and the test suite. Thank you Thijs Wenker
|
||||||
|
|||||||
@@ -79,12 +79,9 @@ macro (final_target)
|
|||||||
CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
|
CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# install headers, directly from current source dir and look for subfolders with headers
|
install (DIRECTORY ${CMAKE_SOURCE_DIR}/${TARGET_NAME}
|
||||||
file (GLOB_RECURSE TARGET_INSTALL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.hpp)
|
DESTINATION include/
|
||||||
foreach (hppfile ${TARGET_INSTALL_HEADERS})
|
FILES_MATCHING PATTERN "*.hpp*")
|
||||||
get_filename_component (currdir ${hppfile} PATH)
|
|
||||||
install (FILES ${hppfile} DESTINATION "include/${TARGET_NAME}/${currdir}")
|
|
||||||
endforeach()
|
|
||||||
endmacro ()
|
endmacro ()
|
||||||
|
|
||||||
macro (link_boost)
|
macro (link_boost)
|
||||||
|
|||||||
+7
-2
@@ -55,7 +55,7 @@ If you handle errors from methods like send, ping, close, etc correctly then you
|
|||||||
|
|
||||||
Normally, for security purposes, operating systems prevent programs from listening on sockets created by other programs. When your program crashes and restarts, the new instance is a different program from the perspective of the operating system. As such it can’t listen on the socket address/port that the previous program was using until after a timeout occurs to make sure the old program was done with it.
|
Normally, for security purposes, operating systems prevent programs from listening on sockets created by other programs. When your program crashes and restarts, the new instance is a different program from the perspective of the operating system. As such it can’t listen on the socket address/port that the previous program was using until after a timeout occurs to make sure the old program was done with it.
|
||||||
|
|
||||||
The the first step for handling this is to make sure that you provide a method (signal handler, admin websocket message, etc) to perform a clean server shutdown. There is a question elsewhere in this FAQ that describes the steps necessary for this.
|
The first step for handling this is to make sure that you provide a method (signal handler, admin websocket message, etc) to perform a clean server shutdown. There is a question elsewhere in this FAQ that describes the steps necessary for this.
|
||||||
|
|
||||||
The clean close strategy won't help in the case of crashes or other abnormal closures. An option to consider for these cases is the use of the SO_REUSEADDR socket option. This instructs the OS to not request an exclusive lock on the socket. This means that after your program crashes the replacement you start can immediately listen on that address/port combo again.
|
The clean close strategy won't help in the case of crashes or other abnormal closures. An option to consider for these cases is the use of the SO_REUSEADDR socket option. This instructs the OS to not request an exclusive lock on the socket. This means that after your program crashes the replacement you start can immediately listen on that address/port combo again.
|
||||||
|
|
||||||
@@ -72,12 +72,14 @@ To specify the type of an outgoing message, use the frame opcode values listed a
|
|||||||
## Dependency Management
|
## Dependency Management
|
||||||
|
|
||||||
### Can WebSocket++ be used without Boost?
|
### 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.
|
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.
|
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
|
### 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.
|
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
|
### 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.
|
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
|
## Compression
|
||||||
|
|
||||||
### How do I use permessage-deflate in version 0.6.0-permessagedeflate and 0.7.0?
|
### How do I use permessage-deflate in version 0.6.0-permessagedeflate and 0.7.0?
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ int main() {
|
|||||||
//foo.handle_accept(con,true);
|
//foo.handle_accept(con,true);
|
||||||
|
|
||||||
std::stringstream input;
|
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 << "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
|
||||||
input >> *con;
|
input >> *con;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
|
||||||
|
|||||||
@@ -217,8 +217,8 @@ BOOST_AUTO_TEST_CASE( connection_extensions ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
|
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 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 output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: ";
|
||||||
output+=websocketpp::user_agent;
|
output+=websocketpp::user_agent;
|
||||||
output+="\r\nUpgrade: websocket\r\n\r\n";
|
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 ) {
|
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 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 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;
|
server s;
|
||||||
s.set_user_agent("");
|
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 ) {
|
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 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 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;
|
server s;
|
||||||
s.set_user_agent("");
|
s.set_user_agent("");
|
||||||
@@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE( request_no_server_header_override ) {
|
|||||||
BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
|
BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
|
||||||
std::string uri = "ws://localhost";
|
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";
|
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 ) {
|
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.
|
// 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};
|
char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
|
||||||
input.append(frame0, 10);
|
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
|
// After the handshake, add a single frame with a close message with message too big
|
||||||
// error code.
|
// error code.
|
||||||
@@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE( websocket_fail_parse_error ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( websocket_fail_invalid_version ) {
|
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;
|
server s;
|
||||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::invalid_version);
|
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 ) {
|
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;
|
server s;
|
||||||
websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
|
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 ) {
|
// 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;
|
// server s;
|
||||||
// websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
|
// 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 ) {
|
// 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";
|
// 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_CHECK(run_server_test(input) == output);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE( basic_text_message ) {
|
// 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};
|
// unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
|
||||||
// input.append(reinterpret_cast<char*>(frames),8);
|
// input.append(reinterpret_cast<char*>(frames),8);
|
||||||
@@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
|
|||||||
|
|
||||||
BOOST_CHECK(!ec);
|
BOOST_CHECK(!ec);
|
||||||
|
|
||||||
std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: ICX+Yqv66kxgM0FcWaLWlFLwTAI=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
|
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
|
// This test the case where a handshake times out immediately before the
|
||||||
// handler that would have completed it gets invoked. This situation happens
|
// 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 ) {
|
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
|
||||||
debug_server s;
|
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();
|
debug_server::connection_ptr con = s.get_connection();
|
||||||
con->start();
|
con->start();
|
||||||
@@ -516,7 +516,7 @@ BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
|
|||||||
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race2 ) {
|
BOOST_AUTO_TEST_CASE( server_handshake_timeout_race2 ) {
|
||||||
debug_server s;
|
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();
|
debug_server::connection_ptr con = s.get_connection();
|
||||||
con->start();
|
con->start();
|
||||||
|
|||||||
@@ -147,8 +147,11 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) {
|
|||||||
server1.listen(ep1, ec);
|
server1.listen(ep1, ec);
|
||||||
BOOST_CHECK(!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);
|
server2.listen(ep1, ec);
|
||||||
BOOST_REQUIRE_EQUAL(ec, make_error_code(pass_through));
|
BOOST_REQUIRE(ec);
|
||||||
|
|
||||||
server2.listen(ep2, ec);
|
server2.listen(ep2, ec);
|
||||||
BOOST_CHECK(!ec);
|
BOOST_CHECK(!ec);
|
||||||
|
|||||||
@@ -186,15 +186,22 @@ BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_invalid ) {
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_valid ) {
|
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_valid ) {
|
||||||
ext_vars v;
|
ext_vars v;
|
||||||
|
|
||||||
|
// confirm that a request for a value of 8 is interpreted as 9
|
||||||
v.attr["server_max_window_bits"] = "8";
|
v.attr["server_max_window_bits"] = "8";
|
||||||
|
|
||||||
v.esp = v.exts.negotiate(v.attr);
|
v.esp = v.exts.negotiate(v.attr);
|
||||||
BOOST_CHECK( v.exts.is_enabled() );
|
BOOST_CHECK( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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");
|
||||||
|
|
||||||
|
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.attr["server_max_window_bits"] = "15";
|
||||||
|
|
||||||
v.esp = v.exts.negotiate(v.attr);
|
v.esp = v.exts.negotiate(v.attr);
|
||||||
BOOST_CHECK( v.exts.is_enabled() );
|
BOOST_CHECK( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, websocketpp::lib::error_code() );
|
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 ) {
|
BOOST_AUTO_TEST_CASE( negotiate_server_max_window_bits_decline ) {
|
||||||
ext_vars v;
|
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.ec = v.exts.set_server_max_window_bits(15,pmd_mode::decline);
|
||||||
v.esp = v.exts.negotiate(v.attr);
|
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_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;
|
ext_vars v;
|
||||||
v.attr["server_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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;
|
ext_vars v;
|
||||||
v.attr["server_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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;
|
ext_vars v;
|
||||||
v.attr["server_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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
|
// 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);
|
v.esp = v.exts.negotiate(v.attr);
|
||||||
BOOST_CHECK( v.exts.is_enabled() );
|
BOOST_CHECK( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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");
|
||||||
|
|
||||||
|
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.attr["client_max_window_bits"] = "15";
|
||||||
v.esp = v.exts.negotiate(v.attr);
|
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_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;
|
ext_vars v;
|
||||||
v.attr["client_max_window_bits"] = "8";
|
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_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;
|
ext_vars v;
|
||||||
v.attr["client_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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;
|
ext_vars v;
|
||||||
v.attr["client_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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;
|
ext_vars v;
|
||||||
v.attr["client_max_window_bits"] = "8";
|
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( v.exts.is_enabled() );
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
BOOST_CHECK_EQUAL( v.esp.first, 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 compress_out;
|
||||||
std::string decompress_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);
|
v.ec = v.exts.compress(compress_in,compress_out);
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
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 ) {
|
BOOST_AUTO_TEST_CASE( compress_data_multiple ) {
|
||||||
ext_vars v;
|
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++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
std::string compress_in = "Hello";
|
std::string compress_in = "Hello";
|
||||||
@@ -545,11 +644,12 @@ BOOST_AUTO_TEST_CASE( compress_data_large ) {
|
|||||||
|
|
||||||
websocketpp::http::attribute_list alist;
|
websocketpp::http::attribute_list alist;
|
||||||
|
|
||||||
alist["server_max_window_bits"] = "8";
|
alist["server_max_window_bits"] = "9";
|
||||||
v.exts.set_server_max_window_bits(8,websocketpp::extensions::permessage_deflate::mode::smallest);
|
v.exts.set_server_max_window_bits(9,websocketpp::extensions::permessage_deflate::mode::smallest);
|
||||||
|
|
||||||
v.exts.negotiate(alist);
|
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);
|
v.ec = v.exts.compress(compress_in,compress_out);
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
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.enable_server_no_context_takeover();
|
||||||
|
|
||||||
v.exts.negotiate(alist);
|
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);
|
v.ec = v.exts.compress(compress_in,compress_out1);
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
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 compress_out;
|
||||||
std::string decompress_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);
|
v.ec = v.exts.compress(compress_in,compress_out);
|
||||||
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
BOOST_CHECK_EQUAL( v.ec, websocketpp::lib::error_code() );
|
||||||
@@ -640,7 +742,8 @@ BOOST_AUTO_TEST_CASE( decompress_data ) {
|
|||||||
std::string out;
|
std::string out;
|
||||||
std::string reference = "Hello";
|
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);
|
v.ec = v.exts.decompress(in,11,out);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
|||||||
websocketpp::http::parser::response response;
|
websocketpp::http::parser::response response;
|
||||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
|
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::http::parser::request r;
|
||||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
@@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE( old_http_version ) {
|
|||||||
websocketpp::http::parser::request r;
|
websocketpp::http::parser::request r;
|
||||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
@@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
|||||||
websocketpp::http::parser::request r;
|
websocketpp::http::parser::request r;
|
||||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
|||||||
websocketpp::http::parser::request r;
|
websocketpp::http::parser::request r;
|
||||||
websocketpp::processor::hybi00<websocketpp::http::parser::request,websocketpp::http::parser::response> p(false);
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
@@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
|
|||||||
websocketpp::uri_ptr u;
|
websocketpp::uri_ptr u;
|
||||||
bool exception = false;
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
r.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ typedef stub_config::message_type::ptr message_ptr;
|
|||||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
|
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 ) {
|
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
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 ) {
|
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
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 ) {
|
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\n\r\n";
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
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 ) {
|
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n";
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
@@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
|
|||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
websocketpp::uri_ptr u;
|
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.consume(handshake.c_str(),handshake.size());
|
||||||
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
env.req.replace_header("Sec-WebSocket-Key3","janelle!");
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
|||||||
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
websocketpp::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
|||||||
|
|
||||||
p.process_handshake(r,"",response);
|
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("Upgrade"), "websocket");
|
||||||
BOOST_CHECK_EQUAL(response.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
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::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi07<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
|||||||
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
websocketpp::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE( exact_match ) {
|
|||||||
|
|
||||||
p.process_handshake(r,"",response);
|
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("Upgrade") == "websocket");
|
||||||
BOOST_CHECK(response.get_header("Sec-WebSocket-Accept") == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
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::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
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::processor::hybi08<stub_config> p(false,true,msg_manager,rng);
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE( bad_host ) {
|
|||||||
websocketpp::uri_ptr u;
|
websocketpp::uri_ptr u;
|
||||||
websocketpp::lib::error_code ec;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ struct processor_setup_ext {
|
|||||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n";
|
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());
|
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);
|
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("Upgrade"), "websocket");
|
||||||
BOOST_CHECK_EQUAL(env.res.get_header("Sec-WebSocket-Accept"), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=");
|
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 ) {
|
BOOST_AUTO_TEST_CASE( non_get_method ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
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());
|
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 ) {
|
BOOST_AUTO_TEST_CASE( old_http_version ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
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());
|
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 ) {
|
BOOST_AUTO_TEST_CASE( missing_handshake_key1 ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
|
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());
|
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 ) {
|
BOOST_AUTO_TEST_CASE( missing_handshake_key2 ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-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());
|
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 ) {
|
BOOST_AUTO_TEST_CASE( bad_host ) {
|
||||||
processor_setup env(true);
|
processor_setup env(true);
|
||||||
|
|
||||||
std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n";
|
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());
|
env.req.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
BOOST_AUTO_TEST_CASE( exact_match ) {
|
BOOST_AUTO_TEST_CASE( exact_match ) {
|
||||||
websocketpp::http::parser::request r;
|
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());
|
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 ) {
|
BOOST_AUTO_TEST_CASE( non_exact_match1 ) {
|
||||||
websocketpp::http::parser::request r;
|
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());
|
r.consume(handshake.c_str(),handshake.size());
|
||||||
|
|
||||||
|
|||||||
+15
-15
@@ -118,8 +118,8 @@ void open_func_subprotocol(server* s, std::string* out, websocketpp::connection_
|
|||||||
|
|
||||||
/* Tests */
|
/* Tests */
|
||||||
BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
|
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 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 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;
|
server s;
|
||||||
s.set_user_agent("test");
|
s.set_user_agent("test");
|
||||||
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
|
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";
|
std::string output = "HTTP/1.1 400 Bad Request\r\nServer: test\r\n\r\n";
|
||||||
|
|
||||||
server s;
|
server s;
|
||||||
@@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( unimplemented_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";
|
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 ) {
|
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;
|
std::string subprotocol;
|
||||||
|
|
||||||
@@ -165,9 +165,9 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_empty ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
|
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 validate;
|
||||||
std::string open;
|
std::string open;
|
||||||
@@ -183,9 +183,9 @@ BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( accept_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 validate;
|
||||||
std::string open;
|
std::string open;
|
||||||
@@ -201,9 +201,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_one ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
|
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 validate;
|
||||||
std::string open;
|
std::string open;
|
||||||
@@ -219,9 +219,9 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
|
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 validate;
|
||||||
std::string open;
|
std::string open;
|
||||||
@@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*BOOST_AUTO_TEST_CASE( user_reject_origin ) {
|
/*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";
|
std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n";
|
||||||
|
|
||||||
server s;
|
server s;
|
||||||
|
|||||||
@@ -140,7 +140,10 @@ typedef websocketpp::lib::shared_ptr<mock_con> connection_ptr;
|
|||||||
struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
|
struct mock_endpoint : public websocketpp::transport::asio::endpoint<config> {
|
||||||
typedef websocketpp::transport::asio::endpoint<config> base;
|
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);
|
alog->set_channels(websocketpp::log::alevel::all);
|
||||||
base::init_logging(alog,elog);
|
base::init_logging(alog,elog);
|
||||||
init_asio();
|
init_asio();
|
||||||
@@ -182,6 +185,8 @@ BOOST_AUTO_TEST_CASE( tls_handshake_timeout ) {
|
|||||||
dummy_server.detach();
|
dummy_server.detach();
|
||||||
timer.detach();
|
timer.detach();
|
||||||
|
|
||||||
|
sleep(1); // give the server thread some time to start
|
||||||
|
|
||||||
mock_endpoint endpoint;
|
mock_endpoint endpoint;
|
||||||
endpoint.set_tls_init_handler(&on_tls_init);
|
endpoint.set_tls_init_handler(&on_tls_init);
|
||||||
endpoint.connect("wss://localhost:9005");
|
endpoint.connect("wss://localhost:9005");
|
||||||
|
|||||||
@@ -354,11 +354,35 @@ void close(T * e, websocketpp::connection_hdl hdl) {
|
|||||||
e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,"");
|
e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the specified time period then fail the test
|
class test_deadline_timer
|
||||||
void run_test_timer(long value) {
|
{
|
||||||
sleep(value);
|
public:
|
||||||
BOOST_FAIL( "Test timed out" );
|
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 ) {
|
BOOST_AUTO_TEST_CASE( pong_no_timeout ) {
|
||||||
server s;
|
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));
|
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 a client that closes the connection after 1 seconds
|
||||||
run_time_limited_client(c, "http://localhost:9005", 1, false);
|
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::error_code(),::_1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
sleep(1); // give the server thread some time to start
|
||||||
tthread.detach();
|
|
||||||
|
test_deadline_timer deadline(10);
|
||||||
|
|
||||||
run_client(c, "http://localhost:9005",false);
|
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::error::open_handshake_timeout,::_1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_dummy_server,9005));
|
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_dummy_server,9005));
|
||||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
|
||||||
sthread.detach();
|
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");
|
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::error::open_handshake_timeout,::_1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
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");
|
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::error::close_handshake_timeout,::_1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
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);
|
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));
|
c.set_open_handler(bind(&delay,::_1,1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,10));
|
test_deadline_timer deadline(10);
|
||||||
tthread.detach();
|
|
||||||
|
|
||||||
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();
|
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 ) {
|
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
|
||||||
client c;
|
client c;
|
||||||
|
|
||||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,3));
|
test_deadline_timer deadline(3);
|
||||||
tthread.detach();
|
|
||||||
|
|
||||||
websocketpp::lib::error_code ec;
|
websocketpp::lib::error_code ec;
|
||||||
c.init_asio(ec);
|
c.init_asio(ec);
|
||||||
@@ -566,17 +599,18 @@ BOOST_AUTO_TEST_CASE( stop_listening ) {
|
|||||||
c.set_open_handler(bind(&close<client>,&c,::_1));
|
c.set_open_handler(bind(&close<client>,&c,::_1));
|
||||||
|
|
||||||
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
|
||||||
websocketpp::lib::thread tthread(websocketpp::lib::bind(&run_test_timer,5));
|
test_deadline_timer deadline(5);
|
||||||
tthread.detach();
|
|
||||||
|
|
||||||
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();
|
sthread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( pause_reading ) {
|
BOOST_AUTO_TEST_CASE( pause_reading ) {
|
||||||
iostream_server s;
|
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) };
|
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)
|
// suppress output (it needs a place to go to avoid error but we don't care what it is)
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ using namespace websocketpp;
|
|||||||
BOOST_AUTO_TEST_CASE( reserved_values ) {
|
BOOST_AUTO_TEST_CASE( reserved_values ) {
|
||||||
BOOST_CHECK( !close::status::reserved(999) );
|
BOOST_CHECK( !close::status::reserved(999) );
|
||||||
BOOST_CHECK( close::status::reserved(1004) );
|
BOOST_CHECK( close::status::reserved(1004) );
|
||||||
BOOST_CHECK( close::status::reserved(1014) );
|
|
||||||
BOOST_CHECK( close::status::reserved(1016) );
|
BOOST_CHECK( close::status::reserved(1016) );
|
||||||
BOOST_CHECK( close::status::reserved(2999) );
|
BOOST_CHECK( close::status::reserved(2999) );
|
||||||
BOOST_CHECK( !close::status::reserved(1000) );
|
BOOST_CHECK( !close::status::reserved(1000) );
|
||||||
|
|||||||
+12
-1
@@ -142,6 +142,11 @@ namespace status {
|
|||||||
/// or reconnect to the same IP upon user action.
|
/// or reconnect to the same IP upon user action.
|
||||||
static value const try_again_later = 1013;
|
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
|
/// An endpoint failed to perform a TLS handshake
|
||||||
/**
|
/**
|
||||||
* Designated for use in applications expecting a status code to indicate
|
* Designated for use in applications expecting a status code to indicate
|
||||||
@@ -178,7 +183,7 @@ namespace status {
|
|||||||
*/
|
*/
|
||||||
inline bool reserved(value code) {
|
inline bool reserved(value code) {
|
||||||
return ((code >= rsv_start && code <= rsv_end) ||
|
return ((code >= rsv_start && code <= rsv_end) ||
|
||||||
code == 1004 || code == 1014);
|
code == 1004);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// First value in range that is always invalid on the wire
|
/// First value in range that is always invalid on the wire
|
||||||
@@ -248,6 +253,12 @@ namespace status {
|
|||||||
return "Extension required";
|
return "Extension required";
|
||||||
case internal_endpoint_error:
|
case internal_endpoint_error:
|
||||||
return "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:
|
case tls_handshake:
|
||||||
return "TLS handshake failure";
|
return "TLS handshake failure";
|
||||||
case subprotocol_error:
|
case subprotocol_error:
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ namespace lib {
|
|||||||
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
|
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
using std::weak_ptr;
|
using std::weak_ptr;
|
||||||
using std::auto_ptr;
|
|
||||||
using std::enable_shared_from_this;
|
using std::enable_shared_from_this;
|
||||||
using std::static_pointer_cast;
|
using std::static_pointer_cast;
|
||||||
using std::make_shared;
|
using std::make_shared;
|
||||||
|
|||||||
@@ -51,7 +51,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#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 <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -64,7 +68,7 @@
|
|||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace lib {
|
namespace lib {
|
||||||
|
|
||||||
#ifdef _WEBSOCKETPP_CPP11_THREAD_
|
#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_)
|
||||||
using std::mutex;
|
using std::mutex;
|
||||||
using std::lock_guard;
|
using std::lock_guard;
|
||||||
using std::thread;
|
using std::thread;
|
||||||
|
|||||||
@@ -1633,15 +1633,6 @@ private:
|
|||||||
session::http_state::value m_http_state;
|
session::http_state::value m_http_state;
|
||||||
|
|
||||||
bool m_was_clean;
|
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
|
} // namespace websocketpp
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
|
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
|
||||||
|
|
||||||
#include <websocketpp/common/cpp11.hpp>
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
|
#include <websocketpp/common/stdint.hpp>
|
||||||
#include <websocketpp/common/system_error.hpp>
|
#include <websocketpp/common/system_error.hpp>
|
||||||
|
|
||||||
#include <websocketpp/http/constants.hpp>
|
#include <websocketpp/http/constants.hpp>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <websocketpp/common/cpp11.hpp>
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
#include <websocketpp/common/memory.hpp>
|
#include <websocketpp/common/memory.hpp>
|
||||||
#include <websocketpp/common/platforms.hpp>
|
#include <websocketpp/common/platforms.hpp>
|
||||||
|
#include <websocketpp/common/stdint.hpp>
|
||||||
#include <websocketpp/common/system_error.hpp>
|
#include <websocketpp/common/system_error.hpp>
|
||||||
#include <websocketpp/error.hpp>
|
#include <websocketpp/error.hpp>
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace extensions {
|
namespace extensions {
|
||||||
|
|
||||||
/// Implementation of the draft permessage-deflate WebSocket extension
|
/// Implementation of RFC 7692, the permessage-deflate WebSocket extension
|
||||||
/**
|
/**
|
||||||
* ### permessage-deflate interface
|
* ### permessage-deflate interface
|
||||||
*
|
*
|
||||||
@@ -174,18 +175,30 @@ namespace websocketpp {
|
|||||||
namespace extensions {
|
namespace extensions {
|
||||||
namespace permessage_deflate {
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
static uint8_t const max_client_max_window_bits = 15;
|
||||||
|
|
||||||
namespace mode {
|
namespace mode {
|
||||||
@@ -213,7 +226,7 @@ public:
|
|||||||
, m_server_max_window_bits_mode(mode::accept)
|
, m_server_max_window_bits_mode(mode::accept)
|
||||||
, m_client_max_window_bits_mode(mode::accept)
|
, m_client_max_window_bits_mode(mode::accept)
|
||||||
, m_initialized(false)
|
, m_initialized(false)
|
||||||
, m_compress_buffer_size(16384)
|
, m_compress_buffer_size(8192)
|
||||||
{
|
{
|
||||||
m_dstate.zalloc = Z_NULL;
|
m_dstate.zalloc = Z_NULL;
|
||||||
m_dstate.zfree = Z_NULL;
|
m_dstate.zfree = Z_NULL;
|
||||||
@@ -292,6 +305,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
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) ||
|
if ((m_server_no_context_takeover && is_server) ||
|
||||||
(m_client_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 bits setting is the base 2 logarithm of the maximum window size that
|
||||||
* the server must use to compress outgoing messages. The permitted range
|
* 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.
|
* window. The default setting is 15.
|
||||||
*
|
*
|
||||||
* Mode Options:
|
* Mode Options:
|
||||||
@@ -386,6 +400,14 @@ public:
|
|||||||
* adjusted by the server. A server may unilaterally set this value without
|
* adjusted by the server. A server may unilaterally set this value without
|
||||||
* client support.
|
* 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 bits The size to request for the outgoing window size
|
||||||
* @param mode The mode to use for negotiating this parameter
|
* @param mode The mode to use for negotiating this parameter
|
||||||
* @return A status code
|
* @return A status code
|
||||||
@@ -394,6 +416,12 @@ public:
|
|||||||
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
||||||
return error::make_error_code(error::invalid_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 = bits;
|
||||||
m_server_max_window_bits_mode = mode;
|
m_server_max_window_bits_mode = mode;
|
||||||
|
|
||||||
@@ -403,8 +431,8 @@ public:
|
|||||||
/// Limit client LZ77 sliding window size
|
/// Limit client LZ77 sliding window size
|
||||||
/**
|
/**
|
||||||
* The bits setting is the base 2 logarithm of the window size that the
|
* 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
|
* client must use to compress outgoing messages. The permitted range is 9
|
||||||
* to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window.
|
* to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window.
|
||||||
* The default setting is 15.
|
* The default setting is 15.
|
||||||
*
|
*
|
||||||
* Mode Options:
|
* Mode Options:
|
||||||
@@ -417,6 +445,14 @@ public:
|
|||||||
* outgoing window size unilaterally. A server may only limit the client's
|
* outgoing window size unilaterally. A server may only limit the client's
|
||||||
* window size if the remote client supports that feature.
|
* 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 bits The size to request for the outgoing window size
|
||||||
* @param mode The mode to use for negotiating this parameter
|
* @param mode The mode to use for negotiating this parameter
|
||||||
* @return A status code
|
* @return A status code
|
||||||
@@ -425,6 +461,12 @@ public:
|
|||||||
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
|
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
|
||||||
return error::make_error_code(error::invalid_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 = bits;
|
||||||
m_client_max_window_bits_mode = mode;
|
m_client_max_window_bits_mode = mode;
|
||||||
|
|
||||||
@@ -555,7 +597,7 @@ public:
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
m_istate.avail_out = m_compress_buffer_size;
|
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);
|
ret = inflate(&m_istate, Z_SYNC_FLUSH);
|
||||||
|
|
||||||
@@ -564,7 +606,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
out.append(
|
out.append(
|
||||||
reinterpret_cast<char *>(m_compress_buffer.get()),
|
reinterpret_cast<char *>(m_decompress_buffer.get()),
|
||||||
m_compress_buffer_size - m_istate.avail_out
|
m_compress_buffer_size - m_istate.avail_out
|
||||||
);
|
);
|
||||||
} while (m_istate.avail_out == 0);
|
} while (m_istate.avail_out == 0);
|
||||||
@@ -642,11 +684,17 @@ private:
|
|||||||
* client requested that we use.
|
* client requested that we use.
|
||||||
*
|
*
|
||||||
* options:
|
* options:
|
||||||
* - decline (refuse to use the attribute)
|
* - decline (ignore value, offer our default instead)
|
||||||
* - accept (use whatever the client says)
|
* - accept (use the value requested by the client)
|
||||||
* - largest (use largest possible value)
|
* - largest (use largest value acceptable to both)
|
||||||
* - smallest (use smallest possible value)
|
* - 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 [in] value The value of the attribute from the offer
|
||||||
* @param [out] ec A reference to the error code to return errors via
|
* @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);
|
ec = make_error_code(error::invalid_mode);
|
||||||
m_server_max_window_bits = default_server_max_window_bits;
|
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
|
/// Negotiate client_max_window_bits attribute
|
||||||
@@ -687,11 +740,17 @@ private:
|
|||||||
* negotiation mode.
|
* negotiation mode.
|
||||||
*
|
*
|
||||||
* options:
|
* options:
|
||||||
* - decline (refuse to use the attribute)
|
* - decline (ignore value, offer our default instead)
|
||||||
* - accept (use whatever the client says)
|
* - accept (use the value requested by the client)
|
||||||
* - largest (use largest possible value)
|
* - largest (use largest value acceptable to both)
|
||||||
* - smallest (use smallest possible value)
|
* - 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 [in] value The value of the attribute from the offer
|
||||||
* @param [out] ec A reference to the error code to return errors via
|
* @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);
|
ec = make_error_code(error::invalid_mode);
|
||||||
m_client_max_window_bits = default_client_max_window_bits;
|
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;
|
bool m_enabled;
|
||||||
@@ -741,6 +805,7 @@ private:
|
|||||||
int m_flush;
|
int m_flush;
|
||||||
size_t m_compress_buffer_size;
|
size_t m_compress_buffer_size;
|
||||||
lib::unique_ptr_uchar_array m_compress_buffer;
|
lib::unique_ptr_uchar_array m_compress_buffer;
|
||||||
|
lib::unique_ptr_uchar_array m_decompress_buffer;
|
||||||
z_stream m_dstate;
|
z_stream m_dstate;
|
||||||
z_stream m_istate;
|
z_stream m_istate;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -610,6 +610,9 @@ inline size_t prepare_masking_key(const masking_key_type& key) {
|
|||||||
* to zero and less than sizeof(size_t).
|
* to zero and less than sizeof(size_t).
|
||||||
*/
|
*/
|
||||||
inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
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()) {
|
if (lib::net::is_little_endian()) {
|
||||||
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
|
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
|
||||||
return (prepared_key >> offset*8) | temp;
|
return (prepared_key >> offset*8) | temp;
|
||||||
|
|||||||
@@ -999,19 +999,16 @@ void connection<config>::handle_read_frame(lib::error_code const & ec,
|
|||||||
"handle_read_frame: got invalid istate in closed state");
|
"handle_read_frame: got invalid istate in closed state");
|
||||||
return;
|
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) {
|
} else if (ecm == transport::error::action_after_shutdown) {
|
||||||
echannel = log::elevel::info;
|
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);
|
log_err(echannel, "handle_read_frame", ecm);
|
||||||
this->terminate(ecm);
|
this->terminate(ecm);
|
||||||
return;
|
return;
|
||||||
@@ -1222,12 +1219,18 @@ lib::error_code connection<config>::process_handshake_request() {
|
|||||||
std::pair<lib::error_code,std::string> neg_results;
|
std::pair<lib::error_code,std::string> neg_results;
|
||||||
neg_results = m_processor->negotiate_extensions(m_request);
|
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
|
// There was a fatal error in extension parsing that should result in
|
||||||
// a failed connection attempt.
|
// 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);
|
m_response.set_status(http::status_code::bad_request);
|
||||||
return neg_results.first;
|
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 {
|
} else {
|
||||||
// extension negotiation succeeded, set response header accordingly
|
// extension negotiation succeeded, set response header accordingly
|
||||||
// we don't send an empty extensions header because it breaks many
|
// we don't send an empty extensions header because it breaks many
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace processor {
|
|||||||
namespace constants {
|
namespace constants {
|
||||||
|
|
||||||
static char const upgrade_token[] = "websocket";
|
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";
|
static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
|
|
||||||
} // namespace constants
|
} // namespace constants
|
||||||
|
|||||||
@@ -125,38 +125,60 @@ public:
|
|||||||
|
|
||||||
http::parameter_list::const_iterator it;
|
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()) {
|
if (m_permessage_deflate.is_implemented()) {
|
||||||
err_str_pair neg_ret;
|
err_str_pair neg_ret;
|
||||||
for (it = p.begin(); it != p.end(); ++it) {
|
for (it = p.begin(); it != p.end(); ++it) {
|
||||||
// look through each extension, if the key is permessage-deflate
|
// not a permessage-deflate extension request, ignore
|
||||||
if (it->first == "permessage-deflate") {
|
if (it->first != "permessage-deflate") {
|
||||||
// if we have already successfully negotiated this extension
|
continue;
|
||||||
// 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);
|
|
||||||
|
|
||||||
if (neg_ret.first) {
|
// if we have already successfully negotiated this extension
|
||||||
// Figure out if this is an error that should halt all
|
// then skip any other requests to negotiate the same one
|
||||||
// extension negotiations or simply cause negotiation of
|
// with different parameters
|
||||||
// this specific extension to fail.
|
if (m_permessage_deflate.is_enabled()) {
|
||||||
//std::cout << "permessage-compress negotiation failed: "
|
continue;
|
||||||
// << neg_ret.first.message() << std::endl;
|
}
|
||||||
} else {
|
|
||||||
// Note: this list will need commas if WebSocket++ ever
|
// attempt to negotiate this offer
|
||||||
// supports more than one extension
|
neg_ret = m_permessage_deflate.negotiate(it->second);
|
||||||
ret.second += neg_ret.second;
|
|
||||||
m_permessage_deflate.init(base::m_server);
|
if (neg_ret.first) {
|
||||||
continue;
|
// 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+189
-189
@@ -1,189 +1,189 @@
|
|||||||
/*
|
/*
|
||||||
*****
|
*****
|
||||||
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1
|
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
|
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
|
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
|
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||||
under the same license as the original, which is listed below.
|
under the same license as the original, which is listed below.
|
||||||
*****
|
*****
|
||||||
|
|
||||||
Copyright (c) 2011, Micael Hildenborg
|
Copyright (c) 2011, Micael Hildenborg
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of Micael Hildenborg nor the
|
* Neither the name of Micael Hildenborg nor the
|
||||||
names of its contributors may be used to endorse or promote products
|
names of its contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior written permission.
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SHA1_DEFINED
|
#ifndef SHA1_DEFINED
|
||||||
#define SHA1_DEFINED
|
#define SHA1_DEFINED
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace sha1 {
|
namespace sha1 {
|
||||||
|
|
||||||
namespace { // local
|
namespace { // local
|
||||||
|
|
||||||
// Rotate an integer value to left.
|
// Rotate an integer value to left.
|
||||||
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||||
return ((value << steps) | (value >> (32 - steps)));
|
return ((value << steps) | (value >> (32 - steps)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the first 16 integers in the buffert to zero.
|
// Sets the first 16 integers in the buffert to zero.
|
||||||
// Used for clearing the W buffert.
|
// Used for clearing the W buffert.
|
||||||
inline void clearWBuffert(unsigned int * buffert)
|
inline void clearWBuffert(unsigned int * buffert)
|
||||||
{
|
{
|
||||||
for (int pos = 16; --pos >= 0;)
|
for (int pos = 16; --pos >= 0;)
|
||||||
{
|
{
|
||||||
buffert[pos] = 0;
|
buffert[pos] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void innerHash(unsigned int * result, unsigned int * w)
|
inline void innerHash(unsigned int * result, unsigned int * w)
|
||||||
{
|
{
|
||||||
unsigned int a = result[0];
|
unsigned int a = result[0];
|
||||||
unsigned int b = result[1];
|
unsigned int b = result[1];
|
||||||
unsigned int c = result[2];
|
unsigned int c = result[2];
|
||||||
unsigned int d = result[3];
|
unsigned int d = result[3];
|
||||||
unsigned int e = result[4];
|
unsigned int e = result[4];
|
||||||
|
|
||||||
int round = 0;
|
int round = 0;
|
||||||
|
|
||||||
#define sha1macro(func,val) \
|
#define sha1macro(func,val) \
|
||||||
{ \
|
{ \
|
||||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||||
e = d; \
|
e = d; \
|
||||||
d = c; \
|
d = c; \
|
||||||
c = rol(b, 30); \
|
c = rol(b, 30); \
|
||||||
b = a; \
|
b = a; \
|
||||||
a = t; \
|
a = t; \
|
||||||
}
|
}
|
||||||
|
|
||||||
while (round < 16)
|
while (round < 16)
|
||||||
{
|
{
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
++round;
|
++round;
|
||||||
}
|
}
|
||||||
while (round < 20)
|
while (round < 20)
|
||||||
{
|
{
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
++round;
|
++round;
|
||||||
}
|
}
|
||||||
while (round < 40)
|
while (round < 40)
|
||||||
{
|
{
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||||
++round;
|
++round;
|
||||||
}
|
}
|
||||||
while (round < 60)
|
while (round < 60)
|
||||||
{
|
{
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||||
++round;
|
++round;
|
||||||
}
|
}
|
||||||
while (round < 80)
|
while (round < 80)
|
||||||
{
|
{
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||||
++round;
|
++round;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef sha1macro
|
#undef sha1macro
|
||||||
|
|
||||||
result[0] += a;
|
result[0] += a;
|
||||||
result[1] += b;
|
result[1] += b;
|
||||||
result[2] += c;
|
result[2] += c;
|
||||||
result[3] += d;
|
result[3] += d;
|
||||||
result[4] += e;
|
result[4] += e;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/// Calculate a SHA1 hash
|
/// Calculate a SHA1 hash
|
||||||
/**
|
/**
|
||||||
* @param src points to any kind of data to be hashed.
|
* @param src points to any kind of data to be hashed.
|
||||||
* @param bytelength the number of bytes to hash from the src pointer.
|
* @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
|
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||||
* the sha1 result in.
|
* the sha1 result in.
|
||||||
*/
|
*/
|
||||||
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||||
// Init the result array.
|
// Init the result array.
|
||||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
||||||
0x10325476, 0xc3d2e1f0 };
|
0x10325476, 0xc3d2e1f0 };
|
||||||
|
|
||||||
// Cast the void src pointer to be the byte array we can work with.
|
// Cast the void src pointer to be the byte array we can work with.
|
||||||
unsigned char const * sarray = (unsigned char const *) src;
|
unsigned char const * sarray = (unsigned char const *) src;
|
||||||
|
|
||||||
// The reusable round buffer
|
// The reusable round buffer
|
||||||
unsigned int w[80];
|
unsigned int w[80];
|
||||||
|
|
||||||
// Loop through all complete 64byte blocks.
|
// Loop through all complete 64byte blocks.
|
||||||
|
|
||||||
size_t endCurrentBlock;
|
size_t endCurrentBlock;
|
||||||
size_t currentBlock = 0;
|
size_t currentBlock = 0;
|
||||||
|
|
||||||
if (bytelength >= 64) {
|
if (bytelength >= 64) {
|
||||||
size_t const endOfFullBlocks = bytelength - 64;
|
size_t const endOfFullBlocks = bytelength - 64;
|
||||||
|
|
||||||
while (currentBlock <= endOfFullBlocks) {
|
while (currentBlock <= endOfFullBlocks) {
|
||||||
endCurrentBlock = currentBlock + 64;
|
endCurrentBlock = currentBlock + 64;
|
||||||
|
|
||||||
// Init the round buffer with the 64 byte block data.
|
// Init the round buffer with the 64 byte block data.
|
||||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||||
{
|
{
|
||||||
// This line will swap endian on big endian and keep endian on
|
// This line will swap endian on big endian and keep endian on
|
||||||
// little endian.
|
// little endian.
|
||||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||||
}
|
}
|
||||||
innerHash(result, w);
|
innerHash(result, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the last and not full 64 byte block if existing.
|
// Handle the last and not full 64 byte block if existing.
|
||||||
endCurrentBlock = bytelength - currentBlock;
|
endCurrentBlock = bytelength - currentBlock;
|
||||||
clearWBuffert(w);
|
clearWBuffert(w);
|
||||||
size_t lastBlockBytes = 0;
|
size_t lastBlockBytes = 0;
|
||||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
if (endCurrentBlock >= 56) {
|
if (endCurrentBlock >= 56) {
|
||||||
innerHash(result, w);
|
innerHash(result, w);
|
||||||
clearWBuffert(w);
|
clearWBuffert(w);
|
||||||
}
|
}
|
||||||
w[15] = bytelength << 3;
|
w[15] = bytelength << 3;
|
||||||
innerHash(result, w);
|
innerHash(result, w);
|
||||||
|
|
||||||
// Store hash in result pointer, and make sure we get in in the correct
|
// Store hash in result pointer, and make sure we get in in the correct
|
||||||
// order on both endian models.
|
// order on both endian models.
|
||||||
for (int hashByte = 20; --hashByte >= 0;) {
|
for (int hashByte = 20; --hashByte >= 0;) {
|
||||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sha1
|
} // namespace sha1
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif // SHA1_DEFINED
|
#endif // SHA1_DEFINED
|
||||||
@@ -1116,17 +1116,10 @@ protected:
|
|||||||
tec = socket_con_type::translate_ec(ec);
|
tec = socket_con_type::translate_ec(ec);
|
||||||
m_tec = ec;
|
m_tec = ec;
|
||||||
|
|
||||||
if (tec == transport::error::tls_short_read) {
|
// all other errors are effectively pass through errors of
|
||||||
// TLS short read at this point is somewhat expected if both
|
// some sort so print some detail on the info channel for
|
||||||
// sides try and end the connection at the same time or if
|
// library users to look up if needed.
|
||||||
// SSLv2 is being used. In general there is nothing that can
|
log_err(log::elevel::info,"asio async_shutdown",ec);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_alog->static_test(log::alevel::devel)) {
|
if (m_alog->static_test(log::alevel::devel)) {
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ public:
|
|||||||
/// Type of a shared pointer to an io_service work object
|
/// Type of a shared pointer to an io_service work object
|
||||||
typedef lib::shared_ptr<lib::asio::io_service::work> work_ptr;
|
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
|
// generate and manage our own io_service
|
||||||
explicit endpoint()
|
explicit endpoint()
|
||||||
: m_io_service(NULL)
|
: m_io_service(NULL)
|
||||||
@@ -260,6 +263,19 @@ public:
|
|||||||
m_external_io_service = false;
|
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
|
/// Sets the tcp pre init handler
|
||||||
/**
|
/**
|
||||||
* The tcp pre init handler is called after the raw tcp connection has been
|
* The tcp pre init handler is called after the raw tcp connection has been
|
||||||
@@ -409,27 +425,33 @@ public:
|
|||||||
lib::asio::error_code bec;
|
lib::asio::error_code bec;
|
||||||
|
|
||||||
m_acceptor->open(ep.protocol(),bec);
|
m_acceptor->open(ep.protocol(),bec);
|
||||||
if (!bec) {
|
if (bec) {ec = clean_up_listen_after_error(bec);return;}
|
||||||
m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec);
|
|
||||||
}
|
m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec);
|
||||||
if (!bec) {
|
if (bec) {ec = clean_up_listen_after_error(bec);return;}
|
||||||
m_acceptor->bind(ep,bec);
|
|
||||||
}
|
// if a TCP pre-bind handler is present, run it
|
||||||
if (!bec) {
|
if (m_tcp_pre_bind_handler) {
|
||||||
m_acceptor->listen(m_listen_backlog,bec);
|
ec = m_tcp_pre_bind_handler(m_acceptor);
|
||||||
}
|
if (ec) {
|
||||||
if (bec) {
|
ec = clean_up_listen_after_error(ec);
|
||||||
if (m_acceptor->is_open()) {
|
return;
|
||||||
m_acceptor->close();
|
|
||||||
}
|
}
|
||||||
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
|
/// Set up endpoint for listening manually
|
||||||
/**
|
/**
|
||||||
* Bind the internal acceptor using the settings specified by the endpoint e
|
* Bind the internal acceptor using the settings specified by the endpoint e
|
||||||
@@ -733,7 +755,7 @@ public:
|
|||||||
m_elog->write(log::elevel::info,
|
m_elog->write(log::elevel::info,
|
||||||
"asio handle_timer error: "+ec.message());
|
"asio handle_timer error: "+ec.message());
|
||||||
log_err(log::elevel::info,"asio handle_timer",ec);
|
log_err(log::elevel::info,"asio handle_timer",ec);
|
||||||
callback(make_error_code(error::pass_through));
|
callback(socket_con_type::translate_ec(ec));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
callback(lib::error_code());
|
callback(lib::error_code());
|
||||||
@@ -818,7 +840,7 @@ protected:
|
|||||||
ret_ec = make_error_code(websocketpp::error::operation_canceled);
|
ret_ec = make_error_code(websocketpp::error::operation_canceled);
|
||||||
} else {
|
} else {
|
||||||
log_err(log::elevel::info,"asio handle_accept",asio_ec);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,7 +983,7 @@ protected:
|
|||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_resolve",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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,7 +1091,7 @@ protected:
|
|||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_connect",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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,6 +1140,16 @@ private:
|
|||||||
m_elog->write(l,s.str());
|
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 {
|
enum state {
|
||||||
UNINITIALIZED = 0,
|
UNINITIALIZED = 0,
|
||||||
READY = 1,
|
READY = 1,
|
||||||
@@ -1125,6 +1157,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
|
tcp_pre_bind_handler m_tcp_pre_bind_handler;
|
||||||
tcp_init_handler m_tcp_pre_init_handler;
|
tcp_init_handler m_tcp_pre_init_handler;
|
||||||
tcp_init_handler m_tcp_post_init_handler;
|
tcp_init_handler m_tcp_post_init_handler;
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ protected:
|
|||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// Translate any security policy specific information about an error code
|
/// Translate any security policy specific information about an error code
|
||||||
/**
|
/**
|
||||||
* Translate_ec takes an Asio error code and attempts to convert its value
|
* Translate_ec takes an Asio error code and attempts to convert its value
|
||||||
@@ -280,11 +281,13 @@ protected:
|
|||||||
* @return The translated error code
|
* @return The translated error code
|
||||||
*/
|
*/
|
||||||
template <typename ErrorCodeType>
|
template <typename ErrorCodeType>
|
||||||
|
static
|
||||||
lib::error_code translate_ec(ErrorCodeType) {
|
lib::error_code translate_ec(ErrorCodeType) {
|
||||||
// We don't know any more information about this error so pass through
|
// We don't know any more information about this error so pass through
|
||||||
return make_error_code(transport::error::pass_through);
|
return make_error_code(transport::error::pass_through);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
/// Overload of translate_ec to catch cases where lib::error_code is the
|
/// Overload of translate_ec to catch cases where lib::error_code is the
|
||||||
/// same type as lib::asio::error_code
|
/// same type as lib::asio::error_code
|
||||||
lib::error_code translate_ec(lib::error_code ec) {
|
lib::error_code translate_ec(lib::error_code ec) {
|
||||||
|
|||||||
@@ -333,6 +333,7 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// Translate any security policy specific information about an error code
|
/// Translate any security policy specific information about an error code
|
||||||
/**
|
/**
|
||||||
* Translate_ec takes an Asio error code and attempts to convert its value
|
* Translate_ec takes an Asio error code and attempts to convert its value
|
||||||
@@ -353,33 +354,23 @@ protected:
|
|||||||
* @return The translated error code
|
* @return The translated error code
|
||||||
*/
|
*/
|
||||||
template <typename ErrorCodeType>
|
template <typename ErrorCodeType>
|
||||||
|
static
|
||||||
lib::error_code translate_ec(ErrorCodeType ec) {
|
lib::error_code translate_ec(ErrorCodeType ec) {
|
||||||
if (ec.category() == lib::asio::error::get_ssl_category()) {
|
if (ec.category() == lib::asio::error::get_ssl_category()) {
|
||||||
if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) {
|
// We know it is a TLS related error, but otherwise don't know more.
|
||||||
return make_error_code(transport::error::tls_short_read);
|
// Pass through as TLS generic.
|
||||||
} else {
|
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 {
|
} else {
|
||||||
// We don't know any more information about this error so pass
|
// We don't know any more information about this error so pass
|
||||||
// through
|
// through
|
||||||
return make_error_code(transport::error::pass_through);
|
return make_error_code(transport::error::pass_through);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
/// Overload of translate_ec to catch cases where lib::error_code is the
|
/// Overload of translate_ec to catch cases where lib::error_code is the
|
||||||
/// same type as lib::asio::error_code
|
/// same type as lib::asio::error_code
|
||||||
lib::error_code translate_ec(lib::error_code ec) {
|
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;
|
return ec;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <websocketpp/error.hpp>
|
#include <websocketpp/error.hpp>
|
||||||
|
|
||||||
#include <websocketpp/common/memory.hpp>
|
#include <websocketpp/common/memory.hpp>
|
||||||
|
#include <websocketpp/common/stdint.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|||||||
@@ -72,11 +72,9 @@ private:
|
|||||||
* Based on code from
|
* Based on code from
|
||||||
* http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find
|
* 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
|
// case-independent (ci) compare_less binary function
|
||||||
struct nocase_compare
|
struct nocase_compare {
|
||||||
: public std::binary_function<unsigned char,unsigned char,bool>
|
|
||||||
{
|
|
||||||
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
|
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
|
||||||
return tolower (c1) < tolower (c2);
|
return tolower (c1) < tolower (c2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,17 +44,17 @@ static int const major_version = 0;
|
|||||||
/// Library minor version number
|
/// Library minor version number
|
||||||
static int const minor_version = 8;
|
static int const minor_version = 8;
|
||||||
/// Library patch version number
|
/// Library patch version number
|
||||||
static int const patch_version = 0;
|
static int const patch_version = 1;
|
||||||
/// Library pre-release flag
|
/// Library pre-release flag
|
||||||
/**
|
/**
|
||||||
* This is a textual flag indicating the type and number for pre-release
|
* 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.
|
* 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
|
/// 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
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user