Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 946365
Collapse All | Expand All

(-)websocketpp-zaphoyd/changelog.md (+79 lines)
Lines 1-4 Link Here
1
HEAD
1
HEAD
2
- MINOR BREAKING BUNDLED LIBRARY CHANGE: The bundled mini-HTTP library has
3
  been refactored to eliminate its use of exceptions. This does not affect any
4
  of the core library APIs. If any users are calling into the underlying HTTP
5
  libraries directly (classes in the namespace `websocketpp::http::*`) they 
6
  should review any error handling they do.
7
- MINOR BREAKING BUNDLED LIBRARY CHANGE: The `websocketpp::utility::to_lower`
8
  function, from the bundled utility library, has been removed. This vestigial
9
  code was not used by the library at all and throwing warnings in MSVC.
10
  Thank you fedor-strelkov and maksis for reporting and remediation ideas. #956
11
- Feature: WebSocket++ can now be compiled without exceptions by defining
12
  `_WEBSOCKETPP_NO_EXCEPTIONS` in the C++ preprocessor. All internal use of
13
  exceptions have been removed. External interfaces that throw exceptions are
14
  still avaliable and supported (except in exception free mode) but now have
15
  overloads that allow `error_code` based error handling.
16
- Compatibility: Overhauled the URI authority parsing logic to be more 
17
  compliant with RFC3986. WebSocket++ is now able to detect invalid registry
18
  hosts, invalid IPv4 and IPv6 literal addresses. Dozens of additional
19
  uri tests added (thank you to the uriparser project for inspiration & test
20
  cases). URI methods that produce URI strings will now produce RFC3986
21
  compliant URIs when IPv6 literals are involved. Thank you Jeff Davie, 
22
  thorsten-klein, mstaz, and barsnick for reporting, example patches, and
23
  testing. #601 #879
24
- Improvement: The error handling system for the server role's async start
25
  accept loop and connection generation has been significantly improved. 
26
  `endpoint::get_connection` now takes an output parameter ec that gives
27
  a detailed error code if connection creation fails. `endpoint::start_accept`
28
  now accepts a handler function as a parameter instead of an error code.
29
  This handler function allows the client program to be alerted when the
30
  async accept loop stops (for any reason, including explicit cancellation)
31
  at any time. Previously, it was only possible to tell if the initial loop 
32
  start had failed, making it difficult to tell when/if the async accept loop
33
  needed to be restarted. The loop handler returns two error codes, a higher
34
  level library code and a second more specific transport level code. The
35
  old `endpoint::get_connection` and `endpoint::start_accept` functions 
36
  remain for backwards compatibility but are deprecated. Thank you Oleh
37
  Derevenko for reporting. #896
38
- Improvement: Cancel ping timer before calling blocking pong handler.
39
  This should reduce any unnecessary expiration logic done to a timer
40
  that is going to be cancelled regardless. Thank you Oleh Derevenko
41
  for reporting. #901
42
- Improvement: Cancel ping timer on connection close. Once the close handeshake
43
  begins, pong responses can no longer be delivered and any outstanding pings
44
  can be assumed to have been preempted by the close. fixes #664
45
- Performance: Refactor to_hex utility method to reduce unecessary copying,
46
  std::string construction, and duplicated code. Add tests. Thank you Dmitry
47
  Matrokhin for reporting and the patch. #914
48
- Performance: Move based overload for connection::set_body for C++11 and
49
  later compilers. Thank you Matus Kysel for the patch & tests. #792
50
- Reliability: Add a few defensive assertions to guard against corrupted
51
  HTTP message reads. Thank you Oleh Derevenko for reporting. #899
52
- Compatibility: Remove use of simple template ids in constructors. This was
53
  required to compile in C++20 mode and higher. Thank you yushb0602 for
54
  reporting and jcelerier for a patch.
55
- Fix Regression: Correct a regression introduced in 0.8.0 that broke
56
  functionality for setting accepted socket options like TCP_NODELAY.
57
  #530 #812
58
- Bug: Fix null pointer deference in proxy error handling code. Thank you
59
  abitmore for reporting and stkaufer for a patch. #820 #825
60
- Documentation: Added language to explicitly clarify that the library
61
  license is in fact the 3-Clause BSD license. #906
62
- Travis/CI: Updated Travis config to use newer version of ubuntu, and use
63
  CMake based build & tests.
64
- SCons: Fix typo in SConstruct that prevented clang from getting the right
65
  value for CXXFLAGS. Thank you robinlinden for reporting and a patch. #878
66
- SCons: Improve compatibility with Python 3. Thank you Jochen Jägers and 
67
  Gianfranco Costamagna for reporting and the patches. #885 #857 #1024
68
- SCons: Correct copy/paste error in `scratch_client` SConstruct file.
69
  Thank you kautsig for reporting and the patch. #893
70
- CMake: Fix typo in CMakeLists.txt that caused CXX_FLAGS to be improperly
71
  quoted. Removed unnecessary hardcoded dependency on libc++ for clang.
72
  Thank you kraj and leochan2009 for reporting and a patch. #614 #859
73
- CMake: Fix issue in CMakeLists.txt that caused boost dependencies to be
74
  seen as a single library rather than multiple. Thank you Gianfranco
75
  Costamagna for reporting and a patch. #855
76
- CMake: Adjust CMake config to use GNUInstallDirs to choose install
77
  directories rather than hard coding. Thank you Khem Raj for reporting and
78
  a patch. #854
79
- CMake: Improve support for building tests & examples on the Haiku platform
80
  Thank you Schrijvers Luc for reporting and the patch. #849
2
81
3
0.8.2 - 2020-04-19
82
0.8.2 - 2020-04-19
4
- Examples: Update print_client_tls example to remove use of deprecated
83
- Examples: Update print_client_tls example to remove use of deprecated
(-)websocketpp-zaphoyd/CMakeLists.txt (-4 / +17 lines)
Lines 39-44 endif() Link Here
39
39
40
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
40
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
41
41
42
include(GNUInstallDirs)
43
42
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
44
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
43
if ("${LIB64}" STREQUAL "TRUE")
45
if ("${LIB64}" STREQUAL "TRUE")
44
  set(LIBSUFFIX 64)
46
  set(LIBSUFFIX 64)
Lines 82-87 include (CMakeHelpers) Link Here
82
option (ENABLE_CPP11 "Build websocketpp with CPP11 features enabled." TRUE)
84
option (ENABLE_CPP11 "Build websocketpp with CPP11 features enabled." TRUE)
83
option (BUILD_EXAMPLES "Build websocketpp examples." FALSE)
85
option (BUILD_EXAMPLES "Build websocketpp examples." FALSE)
84
option (BUILD_TESTS "Build websocketpp tests." FALSE)
86
option (BUILD_TESTS "Build websocketpp tests." FALSE)
87
option (USE_ASIO_STANDALONE "Build websocketpp examples and tests using the standalone ASIO library." FALSE)
85
88
86
if (BUILD_TESTS OR BUILD_EXAMPLES)
89
if (BUILD_TESTS OR BUILD_EXAMPLES)
87
90
Lines 130-140 if (BUILD_TESTS OR BUILD_EXAMPLES) Link Here
130
133
131
    # g++
134
    # g++
132
    if (CMAKE_COMPILER_IS_GNUCXX)
135
    if (CMAKE_COMPILER_IS_GNUCXX)
133
        if (NOT APPLE)
136
        if (NOT APPLE AND NOT HAIKU)
134
            set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
137
            set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
135
        else()
138
        else()
139
        if (HAIKU)
140
            set (WEBSOCKETPP_PLATFORM_LIBS pthread network)
141
        else()
136
            set (WEBSOCKETPP_PLATFORM_LIBS pthread)
142
            set (WEBSOCKETPP_PLATFORM_LIBS pthread)
137
        endif()
143
        endif()
144
        endif()
138
        set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
145
        set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
139
        set (WEBSOCKETPP_BOOST_LIBS system thread)
146
        set (WEBSOCKETPP_BOOST_LIBS system thread)
140
        set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
147
        set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
Lines 152-161 if (BUILD_TESTS OR BUILD_EXAMPLES) Link Here
152
159
153
    # clang
160
    # clang
154
    if (CMAKE_COMPILER_IS_CLANGXX)
161
    if (CMAKE_COMPILER_IS_CLANGXX)
155
        if (NOT APPLE)
162
        if (APPLE)
156
            set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
157
        else()
158
            set (WEBSOCKETPP_PLATFORM_LIBS pthread)
163
            set (WEBSOCKETPP_PLATFORM_LIBS pthread)
164
        elseif (HAIKU)
165
            set (WEBSOCKETPP_PLATFORM_LIBS pthread network)
166
        else()
167
            set (WEBSOCKETPP_PLATFORM_LIBS pthread rt)
159
        endif()
168
        endif()
160
        set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
169
        set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto)
161
        set (WEBSOCKETPP_BOOST_LIBS system thread)
170
        set (WEBSOCKETPP_BOOST_LIBS system thread)
Lines 253-258 endif() Link Here
253
262
254
############ Add projects
263
############ Add projects
255
264
265
if (USE_ASIO_STANDALONE)
266
    add_definitions("-DASIO_STANDALONE -DASIO_HAS_BOOST_DATE_TIME")
267
endif ()
268
256
# Add main library
269
# Add main library
257
add_subdirectory (websocketpp)
270
add_subdirectory (websocketpp)
258
271
(-)websocketpp-zaphoyd/COPYING (+4 lines)
Lines 1-5 Link Here
1
Main Library:
1
Main Library:
2
2
3
BSD 3-Clause License
4
3
Copyright (c) 2014, Peter Thorson. All rights reserved.
5
Copyright (c) 2014, Peter Thorson. All rights reserved.
4
6
5
Redistribution and use in source and binary forms, with or without
7
Redistribution and use in source and binary forms, with or without
Lines 64-69 use as a header only library. This conve Link Here
64
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
66
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
65
under the same license as the original, which is listed below.
67
under the same license as the original, which is listed below.
66
68
69
New BSD License / 3-Clause BSD License
70
67
 Copyright (c) 2011, Micael Hildenborg
71
 Copyright (c) 2011, Micael Hildenborg
68
 All rights reserved.
72
 All rights reserved.
69
73
(-)websocketpp-zaphoyd/docs/config.dox (-16 / +17 lines)
Lines 1-6 Link Here
1
/** \page reference.config Config Reference
1
/** \page reference.config Config Reference
2
2
3
WebSocket++ uses a config template parameter to supply a number of compile type policy types and default numerical values for buffer sizes, timeouts, security behavior, etc. Swapping policies allows changing certain core library behavior designed to be pluggable.
3
WebSocket++ uses a config template parameter to supply a number of compile time policy types and default numerical values for buffer sizes, timeouts, security behavior, etc. Swapping policies allows changing certain core library behavior designed to be pluggable.
4
4
5
A custom config can be made standalone or can subclass one of the bundled configs and just override a few things.
5
A custom config can be made standalone or can subclass one of the bundled configs and just override a few things.
6
6
Lines 38-57 Core Config Options Link Here
38
38
39
Policies are classes used to allow clean swapping of behavior without changing the core library
39
Policies are classes used to allow clean swapping of behavior without changing the core library
40
40
41
| Typedef Name              | Effect                                 |
41
| Typedef Name              | Effect                                 | Core policies |
42
| ------------------------- | -------------------------------------- |
42
| ------------------------- | -------------------------------------- | ------------- |
43
| concurrency_type          | Concurrency policy                     |
43
| concurrency_type          | Provides concurrency primitives        | **None** Stub to disable concurrency overhead & dependencies in single threaded environments |
44
| elog_type                 | Error logger type                      |
44
| ^                         | ^                                      | **Basic** Primities provided by the C++11 STL or Boost.Atomic |
45
| alog_type                 | Access logger type                     |
45
| elog_type                 | Provides error logging functionality                      | |
46
| request_type              | HTTP request type                      |
46
| alog_type                 | Provides access logging functionality  | |
47
| response_type             | HTTP response type                     |
47
| request_type              | Stores and manipulates HTTP requests   | |
48
| message_type              | Type to deliver recieved messages      |
48
| response_type             | Stores and manipulates HTTP responses  | |
49
| con_msg_manager_type      | Connection level message manager       |
49
| message_type              | Stores and manipulates WebSocket Messages | |
50
| endpoint_msg_manager_type | Endpoint level message manager         |
50
| con_msg_manager_type      | Connection level message manager       | |
51
| rng_type                  | Random Number Generation policy        |
51
| endpoint_msg_manager_type | Endpoint level message manager         | |
52
| transport_type            | Transport policy to use                |
52
| rng_type                  | Random Number Generation policy        | |
53
| endpoint_base             | User overridable Endpoint base class   |
53
| transport_type            | Provides network I/O and timers        | |
54
| connection_base           | User overridable Connection base class |
54
| endpoint_base             | User overridable Endpoint base class   | |
55
| connection_base           | User overridable Connection base class | |
55
56
56
### Timeouts Values
57
### Timeouts Values
57
58
Lines 91-97 If your application has a lot of connect Link Here
91
Drop connections on protocol error rather than sending a close frame. Off by default. This may result in legitimate messages near the error being dropped as well. It may free up resources otherwise spent dealing with misbehaving clients.
92
Drop connections on protocol error rather than sending a close frame. Off by default. This may result in legitimate messages near the error being dropped as well. It may free up resources otherwise spent dealing with misbehaving clients.
92
93
93
#### Silent Close
94
#### Silent Close
94
Silence close suppresses the return of detailed connection close information during the closing handshake. This information is useful for debugging and presenting useful errors to end users but may be undesirable for security reasons in some production environments. Close reasons could be used by an attacker to confirm that the endpoint is out of resources or be used to identify the WebSocket implementation in use.
95
Silenct close suppresses the return of detailed connection close information during the closing handshake. This information is useful for debugging and presenting useful errors to end users but may be undesirable for security reasons in some production environments. Close reasons could be used by an attacker to confirm that the endpoint is out of resources or be used to identify the WebSocket implementation in use.
95
96
96
Note: this will suppress *all* close codes, including those explicitly sent by local applications.
97
Note: this will suppress *all* close codes, including those explicitly sent by local applications.
97
98
(-)websocketpp-zaphoyd/docs/faq.dox (-6 / +6 lines)
Lines 29-47 Note: some browsers will allow the conne Link Here
29
29
30
### How do I cleanly exit an Asio transport based program
30
### How do I cleanly exit an Asio transport based program
31
31
32
The Asio transport based clients and servers use the Asio library's underlying `io_service` to handle asyncronous networking operations. The standard behavior of the io_service is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following:
32
The Asio transport based clients and servers use the Asio library's underlying `io_context` to handle asyncronous networking operations. The standard behavior of the io_context is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following:
33
33
34
- For servers, call `websocketpp::transport::asio::endpoint::stop_listening` to initiate the closing of the server listening socket.
34
- For servers, call `websocketpp::transport::asio::endpoint::stop_listening` to initiate the closing of the server listening socket.
35
- For clients, if you have engaged perpetual mode with `websocketpp::transport::asio::endpoint::start_perpetual`, disable it with `websocketpp::transport::asio::endpoint::stop_perpetual`.
35
- For clients, if you have engaged perpetual mode with `websocketpp::transport::asio::endpoint::start_perpetual`, disable it with `websocketpp::transport::asio::endpoint::stop_perpetual`.
36
- For both, run `websocketpp::endpoint::close` or `websocketpp::connection::close` on all currently outstanding connections. This will initiate the WebSocket closing handshake for these connections
36
- For both, run `websocketpp::endpoint::close` or `websocketpp::connection::close` on all currently outstanding connections. This will initiate the WebSocket closing handshake for these connections
37
- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_service gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_service::run` method will exit cleanly and automatically when all operations are complete.
37
- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_context gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_context::run` method will exit cleanly and automatically when all operations are complete.
38
38
39
__WARNING__: Asio's `io_service` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_service::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_service::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors.
39
__WARNING__: Asio's `io_context` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_context::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_context::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors.
40
40
41
__Special cases__:
41
__Special cases__:
42
- If your client uses the `start_perpetual` method it will prevent the io_service from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each.
42
- If your client uses the `start_perpetual` method it will prevent the io_context from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each.
43
- If you are using an external io_service and/or are placing non-WebSocket++ operations on the `io_service` those operations may keep the `io_service` open even after all WebSocket++ operations have completed.
43
- If you are using an external io_context and/or are placing non-WebSocket++ operations on the `io_context` those operations may keep the `io_context` open even after all WebSocket++ operations have completed.
44
- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_service` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_service::work`" cases.
44
- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_context` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_context::work`" cases.
45
45
46
### Is there a way to check the validity of a `connection_hdl`?
46
### Is there a way to check the validity of a `connection_hdl`?
47
47
(-)websocketpp-zaphoyd/docs/handlers.dox (-8 / +54 lines)
Lines 46-58 operations have been run. Common pre-han Link Here
46
46
47
### TCP Post-init Handler
47
### TCP Post-init Handler
48
48
49
| Event                                              | Signature                       | Availability         |
50
| -------------------------------------------------- | ------------------------------- | -------------------- |
51
| TCP established, pre-handshake operations complete | `tcp_post_init(connection_hdl)` | 0.3.0 Asio Transport |
52
53
This hook is triggered after all pre-WebSocket handshake operations have been run. Common pre-handshake
54
operations include TLS handshakes and proxy connections.
55
56
### TLS Initialization Handler
57
49
| Event                   | Signature                                  | Availability                  |
58
| Event                   | Signature                                  | Availability                  |
50
| ----------------------- | ------------------------------------------ | ----------------------------- |
59
| ----------------------- | ------------------------------------------ | ----------------------------- |
51
| Request for TLS context | `tls_context_ptr tls_init(connection_hdl)` | 0.3.0 Asio Transport with TLS |
60
| Request for TLS context | `tls_context_ptr tls_init(connection_hdl)` | 0.3.0 Asio Transport with TLS |
52
61
53
This hook is triggered before the TLS handshake to request the TLS context to use. You must 
62
This hook is triggered before the TLS handshake to request the TLS context to use. The user program must 
54
return a pointer to a configured TLS conext to continue. This provides the opportuinity to 
63
return a pointer to a configured TLS context to continue. This provides the opportuinity to set up TLS 
55
set up the TLS settings, certificates, etc.
64
settings, certificates, etc.
56
65
57
### Validate Handler
66
### Validate Handler
58
67
Lines 96-105 that fail will never have a close handle Link Here
96
Close will be called exactly once for every connection that open was called for.
105
Close will be called exactly once for every connection that open was called for.
97
Close is not called for failed connections.
106
Close is not called for failed connections.
98
107
108
Endpoint Handlers
109
-----------------
110
111
### TCP Listen Pre-bind handler
112
113
| Event          | Signature                                                                     | Availability         |
114
| -------------- | ----------------------------------------------------------------------------- | -------------------- |
115
| Listen Prebind | `lib::error_code tcp_pre_bind(lib::shared_ptr<lib::asio::ip::tcp::acceptor>)` | 0.8.0 Asio Transport |
116
117
This hook is triggered during the call to `endpoint::listen` after the acceptor
118
is initialized and open but before bind or listen are called. It provides an
119
opportunity to make application specific configuation to the acceptor, most
120
commonly setting socket options on the listening socket, such as SO_REUSEPORT
121
or IPV6_ONLY.
122
123
The return value of the callback will be used to determine whether to proceed
124
with listening. Return an empty/0 error code to proceed, or another error code
125
to fail. In the fail case, the error code will be reported back to the caller
126
of `endpoint::listen`.
127
128
### Acceptance Loop End Handler
129
130
| Event                                 | Signature                                                             | Availability                 |
131
| ------------------------------------- | --------------------------------------------------------------------- | ---------------------------- |
132
| Async Accept Loop end (after opening) | `accept_loop(void(lib::error_code const &, lib::error_code const &))` | 0.9.0 Core, Server role only |
133
134
This handler is passed to the `endpoint::start_accept()` function, which initiates an
135
asyncronous loop that accepts new connections, and is invoked when that loop ends. The
136
handler will be called exactly once for each call of `start_accept` no matter when or
137
how it exits (it might exit immediately).
138
139
The handler may be called inside the call to `start_accept` if that function has enough
140
information to determine that accepting connections will be impossible. Otherwise, it
141
may be invoked at a later time from a different asyncronous handler.
142
143
The handler returns two error codes. The first from the core library and the second a 
144
more detailed code passed through from the underlying transport.
145
99
Message Handlers
146
Message Handlers
100
----------------
147
----------------
101
148
102
These handers are called in response to incoming messages or message like events. They only will be called while the connection is in the open state.
149
These handers are called in response to incoming messages or message like events. 
150
They only will be called while the connection is in the open state.
103
151
104
### Message Handler
152
### Message Handler
105
153
Lines 145-151 Triggered if there is no response to a p Link Here
145
| HTTP request recieved | `http(connection_hdl` | 0.3.0 Core, Server role only |
193
| HTTP request recieved | `http(connection_hdl` | 0.3.0 Core, Server role only |
146
194
147
Called when HTTP requests that are not WebSocket handshake upgrade requests are
195
Called when HTTP requests that are not WebSocket handshake upgrade requests are
148
recieved. Allows responding to regular HTTP requests. If no handler is registered
196
received. Allows responding to regular HTTP requests. If no handler is registered
149
a 426/Upgrade Required error is returned.
197
a 426/Upgrade Required error is returned.
150
198
151
### Interrupt Handler
199
### Interrupt Handler
Lines 157-165 a 426/Upgrade Required error is returned Link Here
157
Interrupt events can be triggered by calling `endpoint::interrupt` or `connection::interrupt`. 
205
Interrupt events can be triggered by calling `endpoint::interrupt` or `connection::interrupt`. 
158
Interrupt is similar to a timer event with duration zero but with lower overhead. It is useful
206
Interrupt is similar to a timer event with duration zero but with lower overhead. It is useful
159
for single threaded programs to allow breaking up a very long handler into multiple parts and 
207
for single threaded programs to allow breaking up a very long handler into multiple parts and 
160
for multi threaded programs as a way for worker threads to signale to the main/network thread 
208
for multi threaded programs as a way for worker threads to signal to the main/network thread 
161
that an event is ready.
209
that an event is ready.
162
210
163
todo: write low and high watermark handlers
164
165
*/
211
*/
(-)websocketpp-zaphoyd/examples/associative_storage/associative_storage.cpp (-1 / +7 lines)
Lines 10-15 using websocketpp::connection_hdl; Link Here
10
using websocketpp::lib::placeholders::_1;
10
using websocketpp::lib::placeholders::_1;
11
using websocketpp::lib::placeholders::_2;
11
using websocketpp::lib::placeholders::_2;
12
using websocketpp::lib::bind;
12
using websocketpp::lib::bind;
13
using websocketpp::lib::error_code;
13
14
14
struct connection_data {
15
struct connection_data {
15
    int sessionid;
16
    int sessionid;
Lines 44-49 public: Link Here
44
        m_connections.erase(hdl);
45
        m_connections.erase(hdl);
45
    }
46
    }
46
47
48
    void on_end_accept(error_code lib_ec, error_code trans_ec) {
49
        std::cout << "Accept loop ended "
50
                  << lib_ec.message() << "/" << trans_ec.message() << std::endl;
51
    }
52
47
    void on_message(connection_hdl hdl, server::message_ptr msg) {
53
    void on_message(connection_hdl hdl, server::message_ptr msg) {
48
        connection_data& data = get_data_from_hdl(hdl);
54
        connection_data& data = get_data_from_hdl(hdl);
49
55
Lines 71-77 public: Link Here
71
77
72
    void run(uint16_t port) {
78
    void run(uint16_t port) {
73
        m_server.listen(port);
79
        m_server.listen(port);
74
        m_server.start_accept();
80
        m_server.start_accept(bind(&print_server::on_end_accept,this,::_1,::_2));
75
        m_server.run();
81
        m_server.run();
76
    }
82
    }
77
private:
83
private:
(-)websocketpp-zaphoyd/examples/broadcast_server/broadcast_server.cpp (-13 / +29 lines)
Lines 47-54 struct action { Link Here
47
class broadcast_server {
47
class broadcast_server {
48
public:
48
public:
49
    broadcast_server() {
49
    broadcast_server() {
50
        websocketpp::lib::error_code ec;
50
        // Initialize Asio Transport
51
        // Initialize Asio Transport
51
        m_server.init_asio();
52
        m_server.init_asio(ec);
53
        if (!ec) {
54
            return;
55
        }
52
56
53
        // Register handler callbacks
57
        // Register handler callbacks
54
        m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
58
        m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1));
Lines 57-74 public: Link Here
57
    }
61
    }
58
62
59
    void run(uint16_t port) {
63
    void run(uint16_t port) {
64
        websocketpp::lib::error_code ec;
65
60
        // listen on specified port
66
        // listen on specified port
61
        m_server.listen(port);
67
        m_server.listen(port,ec);
68
        if (!ec) {
69
            return;
70
        }
62
71
63
        // Start the server accept loop
72
        // Start the server accept loop
64
        m_server.start_accept();
73
        m_server.start_accept(ec);
74
        if (!ec) {
75
            return;
76
        }
65
77
66
        // Start the ASIO io_service run loop
78
        // Start the ASIO io_context run loop
67
        try {
79
        //try {
68
            m_server.run();
80
            m_server.run();
69
        } catch (const std::exception & e) {
81
        //} catch (const std::exception & e) {
70
            std::cout << e.what() << std::endl;
82
        //    std::cout << e.what() << std::endl;
71
        }
83
        //}
72
    }
84
    }
73
85
74
    void on_open(connection_hdl hdl) {
86
    void on_open(connection_hdl hdl) {
Lines 100-105 public: Link Here
100
    }
112
    }
101
113
102
    void process_messages() {
114
    void process_messages() {
115
        websocketpp::lib::error_code ec;
103
        while(1) {
116
        while(1) {
104
            unique_lock<mutex> lock(m_action_lock);
117
            unique_lock<mutex> lock(m_action_lock);
105
118
Lines 123-129 public: Link Here
123
136
124
                con_list::iterator it;
137
                con_list::iterator it;
125
                for (it = m_connections.begin(); it != m_connections.end(); ++it) {
138
                for (it = m_connections.begin(); it != m_connections.end(); ++it) {
126
                    m_server.send(*it,a.msg);
139
                    m_server.send(*it,a.msg,ec);
140
                    if (ec) {
141
                        return;
142
                    }
127
                }
143
                }
128
            } else {
144
            } else {
129
                // undefined.
145
                // undefined.
Lines 143-149 private: Link Here
143
};
159
};
144
160
145
int main() {
161
int main() {
146
    try {
162
    //try {
147
    broadcast_server server_instance;
163
    broadcast_server server_instance;
148
164
149
    // Start a thread to run the processing loop
165
    // Start a thread to run the processing loop
Lines 154-160 int main() { Link Here
154
170
155
    t.join();
171
    t.join();
156
172
157
    } catch (websocketpp::exception const & e) {
173
    //} catch (websocketpp::exception const & e) {
158
        std::cout << e.what() << std::endl;
174
    //    std::cout << e.what() << std::endl;
159
    }
175
    //}
160
}
176
}
(-)websocketpp-zaphoyd/examples/broadcast_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/debug_client/debug_client.cpp (-10 / +9 lines)
Lines 30-42 Link Here
30
 */
30
 */
31
31
32
#include <websocketpp/config/asio_client.hpp>
32
#include <websocketpp/config/asio_client.hpp>
33
34
#include <websocketpp/client.hpp>
33
#include <websocketpp/client.hpp>
35
34
36
#include <iostream>
35
#include <iostream>
37
#include <chrono>
36
#include <chrono>
38
37
39
typedef websocketpp::client<websocketpp::config::asio_client> client;
38
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
40
39
41
using websocketpp::lib::placeholders::_1;
40
using websocketpp::lib::placeholders::_1;
42
using websocketpp::lib::placeholders::_2;
41
using websocketpp::lib::placeholders::_2;
Lines 44-50 using websocketpp::lib::bind; Link Here
44
43
45
// pull out the type of messages sent by our config
44
// pull out the type of messages sent by our config
46
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
45
typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr;
47
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
46
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;
48
typedef client::connection_ptr connection_ptr;
47
typedef client::connection_ptr connection_ptr;
49
48
50
49
Lines 63-69 public: Link Here
63
62
64
        // Register our handlers
63
        // Register our handlers
65
        m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1));
64
        m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1));
66
        //m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
65
        m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1));
67
        m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2));
66
        m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2));
68
        m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
67
        m_endpoint.set_open_handler(bind(&type::on_open,this,::_1));
69
        m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
68
        m_endpoint.set_close_handler(bind(&type::on_close,this,::_1));
Lines 83-89 public: Link Here
83
82
84
        m_endpoint.connect(con);
83
        m_endpoint.connect(con);
85
84
86
        // Start the ASIO io_service run loop
85
        // Start the ASIO io_context run loop
87
        m_start = std::chrono::high_resolution_clock::now();
86
        m_start = std::chrono::high_resolution_clock::now();
88
        m_endpoint.run();
87
        m_endpoint.run();
89
    }
88
    }
Lines 94-106 public: Link Here
94
93
95
    context_ptr on_tls_init(websocketpp::connection_hdl) {
94
    context_ptr on_tls_init(websocketpp::connection_hdl) {
96
        m_tls_init = std::chrono::high_resolution_clock::now();
95
        m_tls_init = std::chrono::high_resolution_clock::now();
97
        context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
96
        context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(websocketpp::lib::asio::ssl::context::tlsv1);
98
97
99
        try {
98
        try {
100
            ctx->set_options(boost::asio::ssl::context::default_workarounds |
99
            ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds |
101
                             boost::asio::ssl::context::no_sslv2 |
100
                             websocketpp::lib::asio::ssl::context::no_sslv2 |
102
                             boost::asio::ssl::context::no_sslv3 |
101
                             websocketpp::lib::asio::ssl::context::no_sslv3 |
103
                             boost::asio::ssl::context::single_dh_use);
102
                             websocketpp::lib::asio::ssl::context::single_dh_use);
104
        } catch (std::exception& e) {
103
        } catch (std::exception& e) {
105
            std::cout << e.what() << std::endl;
104
            std::cout << e.what() << std::endl;
106
        }
105
        }
(-)websocketpp-zaphoyd/examples/debug_client/SConscript (-1 / +1 lines)
Lines 14-20 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
19
   prgs += env_cpp11.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
(-)websocketpp-zaphoyd/examples/debug_server/debug_server.cpp (-1 / +1 lines)
Lines 162-168 int main() { Link Here
162
        // Start the server accept loop
162
        // Start the server accept loop
163
        echo_server.start_accept();
163
        echo_server.start_accept();
164
164
165
        // Start the ASIO io_service run loop
165
        // Start the ASIO io_context run loop
166
        echo_server.run();
166
        echo_server.run();
167
    } catch (websocketpp::exception const & e) {
167
    } catch (websocketpp::exception const & e) {
168
        std::cout << e.what() << std::endl;
168
        std::cout << e.what() << std::endl;
(-)websocketpp-zaphoyd/examples/debug_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/dev/SConscript (-1 / +1 lines)
Lines 11-17 env_cpp11 = env_cpp11.Clone () Link Here
11
11
12
prgs = []
12
prgs = []
13
13
14
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
14
if 'WSPP_CPP11_ENABLED' in env_cpp11:
15
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system','timer','chrono'],env_cpp11) + [platform_libs] + [polyfill_libs]
15
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system','timer','chrono'],env_cpp11) + [platform_libs] + [polyfill_libs]
16
   prgs += env_cpp11.Program('main', ["main.cpp"], LIBS = BOOST_LIBS_CPP11)
16
   prgs += env_cpp11.Program('main', ["main.cpp"], LIBS = BOOST_LIBS_CPP11)
17
17
(-)websocketpp-zaphoyd/examples/echo_client/echo_client.cpp (-1 / +1 lines)
Lines 87-93 int main(int argc, char* argv[]) { Link Here
87
        // exchanged until the event loop starts running in the next line.
87
        // exchanged until the event loop starts running in the next line.
88
        c.connect(con);
88
        c.connect(con);
89
89
90
        // Start the ASIO io_service run loop
90
        // Start the ASIO io_context run loop
91
        // this will cause a single connection to be made to the server. c.run()
91
        // this will cause a single connection to be made to the server. c.run()
92
        // will exit when this connection is closed.
92
        // will exit when this connection is closed.
93
        c.run();
93
        c.run();
(-)websocketpp-zaphoyd/examples/echo_client/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
18
   prgs += env_cpp11.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/echo_server/echo_server.cpp (-2 / +9 lines)
Lines 9-14 typedef websocketpp::server<websocketpp: Link Here
9
using websocketpp::lib::placeholders::_1;
9
using websocketpp::lib::placeholders::_1;
10
using websocketpp::lib::placeholders::_2;
10
using websocketpp::lib::placeholders::_2;
11
using websocketpp::lib::bind;
11
using websocketpp::lib::bind;
12
using websocketpp::lib::error_code;
12
13
13
// pull out the type of messages sent by our config
14
// pull out the type of messages sent by our config
14
typedef server::message_ptr message_ptr;
15
typedef server::message_ptr message_ptr;
Lines 34-39 void on_message(server* s, websocketpp:: Link Here
34
    }
35
    }
35
}
36
}
36
37
38
// Define a callback to handle failures accepting connections
39
void on_end_accept(error_code lib_ec, error_code trans_ec) {
40
    std::cout << "Accept loop ended "
41
                << lib_ec.message() << "/" << trans_ec.message() << std::endl;
42
}
43
37
int main() {
44
int main() {
38
    // Create a server endpoint
45
    // Create a server endpoint
39
    server echo_server;
46
    server echo_server;
Lines 53-61 int main() { Link Here
53
        echo_server.listen(9002);
60
        echo_server.listen(9002);
54
61
55
        // Start the server accept loop
62
        // Start the server accept loop
56
        echo_server.start_accept();
63
        echo_server.start_accept(&on_end_accept);
57
64
58
        // Start the ASIO io_service run loop
65
        // Start the ASIO io_context run loop
59
        echo_server.run();
66
        echo_server.run();
60
    } catch (websocketpp::exception const & e) {
67
    } catch (websocketpp::exception const & e) {
61
        std::cout << e.what() << std::endl;
68
        std::cout << e.what() << std::endl;
(-)websocketpp-zaphoyd/examples/echo_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/echo_server_both/echo_server_both.cpp (-16 / +23 lines)
Lines 12-20 typedef websocketpp::server<websocketpp: Link Here
12
using websocketpp::lib::placeholders::_1;
12
using websocketpp::lib::placeholders::_1;
13
using websocketpp::lib::placeholders::_2;
13
using websocketpp::lib::placeholders::_2;
14
using websocketpp::lib::bind;
14
using websocketpp::lib::bind;
15
using websocketpp::lib::error_code;
15
16
16
// type of the ssl context pointer is long so alias it
17
// type of the ssl context pointer is long so alias it
17
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
18
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;
18
19
19
// The shared on_message handler takes a template parameter so the function can
20
// The shared on_message handler takes a template parameter so the function can
20
// resolve any endpoint dependent types like message_ptr or connection_ptr
21
// resolve any endpoint dependent types like message_ptr or connection_ptr
Lines 34-39 void on_message(EndpointType* s, websock Link Here
34
    }
35
    }
35
}
36
}
36
37
38
// Define a callback to handle failures accepting connections
39
void on_end_accept(error_code lib_ec, error_code trans_ec) {
40
    std::cout << "Accept loop ended "
41
                << lib_ec.message() << "/" << trans_ec.message() << std::endl;
42
}
43
37
// No change to TLS init methods from echo_server_tls
44
// No change to TLS init methods from echo_server_tls
38
std::string get_password() {
45
std::string get_password() {
39
    return "test";
46
    return "test";
Lines 41-56 std::string get_password() { Link Here
41
48
42
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
49
context_ptr on_tls_init(websocketpp::connection_hdl hdl) {
43
    std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
50
    std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl;
44
    context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1));
51
    context_ptr ctx(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::tlsv1));
45
52
46
    try {
53
    try {
47
        ctx->set_options(boost::asio::ssl::context::default_workarounds |
54
        ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds |
48
                         boost::asio::ssl::context::no_sslv2 |
55
                         websocketpp::lib::asio::ssl::context::no_sslv2 |
49
                         boost::asio::ssl::context::no_sslv3 |
56
                         websocketpp::lib::asio::ssl::context::no_sslv3 |
50
                         boost::asio::ssl::context::single_dh_use);
57
                         websocketpp::lib::asio::ssl::context::single_dh_use);
51
        ctx->set_password_callback(bind(&get_password));
58
        ctx->set_password_callback(bind(&get_password));
52
        ctx->use_certificate_chain_file("server.pem");
59
        ctx->use_certificate_chain_file("server.pem");
53
        ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem);
60
        ctx->use_private_key_file("server.pem", websocketpp::lib::asio::ssl::context::pem);
54
    } catch (std::exception& e) {
61
    } catch (std::exception& e) {
55
        std::cout << e.what() << std::endl;
62
        std::cout << e.what() << std::endl;
56
    }
63
    }
Lines 58-87 context_ptr on_tls_init(websocketpp::con Link Here
58
}
65
}
59
66
60
int main() {
67
int main() {
61
    // set up an external io_service to run both endpoints on. This is not
68
    // set up an external io_context to run both endpoints on. This is not
62
    // strictly necessary, but simplifies thread management a bit.
69
    // strictly necessary, but simplifies thread management a bit.
63
    boost::asio::io_service ios;
70
    websocketpp::lib::asio::io_context ctx;
64
71
65
    // set up plain endpoint
72
    // set up plain endpoint
66
    server_plain endpoint_plain;
73
    server_plain endpoint_plain;
67
    // initialize asio with our external io_service rather than an internal one
74
    // initialize asio with our external io_context rather than an internal one
68
    endpoint_plain.init_asio(&ios);
75
    endpoint_plain.init_asio(&ctx);
69
    endpoint_plain.set_message_handler(
76
    endpoint_plain.set_message_handler(
70
        bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2));
77
        bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2));
71
    endpoint_plain.listen(80);
78
    endpoint_plain.listen(80);
72
    endpoint_plain.start_accept();
79
    endpoint_plain.start_accept(&on_end_accept);
73
80
74
    // set up tls endpoint
81
    // set up tls endpoint
75
    server_tls endpoint_tls;
82
    server_tls endpoint_tls;
76
    endpoint_tls.init_asio(&ios);
83
    endpoint_tls.init_asio(&ctx);
77
    endpoint_tls.set_message_handler(
84
    endpoint_tls.set_message_handler(
78
        bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2));
85
        bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2));
79
    // TLS endpoint has an extra handler for the tls init
86
    // TLS endpoint has an extra handler for the tls init
80
    endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1));
87
    endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1));
81
    // tls endpoint listens on a different port
88
    // tls endpoint listens on a different port
82
    endpoint_tls.listen(443);
89
    endpoint_tls.listen(443);
83
    endpoint_tls.start_accept();
90
    endpoint_tls.start_accept(&on_end_accept);
84
91
85
    // Start the ASIO io_service run loop running both endpoints
92
    // Start the ASIO io_context run loop running both endpoints
86
    ios.run();
93
    ctx.run();
87
}
94
}
(-)websocketpp-zaphoyd/examples/echo_server_both/SConscript (-1 / +1 lines)
Lines 14-20 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
19
   prgs += env_cpp11.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
(-)websocketpp-zaphoyd/examples/echo_server_tls/echo_server_tls.cpp (-2 / +9 lines)
Lines 45-50 typedef websocketpp::server<websocketpp: Link Here
45
using websocketpp::lib::placeholders::_1;
45
using websocketpp::lib::placeholders::_1;
46
using websocketpp::lib::placeholders::_2;
46
using websocketpp::lib::placeholders::_2;
47
using websocketpp::lib::bind;
47
using websocketpp::lib::bind;
48
using websocketpp::lib::error_code;
48
49
49
// pull out the type of messages sent by our config
50
// pull out the type of messages sent by our config
50
typedef websocketpp::config::asio::message_type::ptr message_ptr;
51
typedef websocketpp::config::asio::message_type::ptr message_ptr;
Lines 63-68 void on_message(server* s, websocketpp:: Link Here
63
    }
64
    }
64
}
65
}
65
66
67
// Define a callback to handle failures accepting connections
68
void on_end_accept(error_code lib_ec, error_code trans_ec) {
69
    std::cout << "Accept loop ended "
70
                << lib_ec.message() << "/" << trans_ec.message() << std::endl;
71
}
72
66
void on_http(server* s, websocketpp::connection_hdl hdl) {
73
void on_http(server* s, websocketpp::connection_hdl hdl) {
67
    server::connection_ptr con = s->get_con_from_hdl(hdl);
74
    server::connection_ptr con = s->get_con_from_hdl(hdl);
68
    
75
    
Lines 146-154 int main() { Link Here
146
    echo_server.listen(9002);
153
    echo_server.listen(9002);
147
154
148
    // Start the server accept loop
155
    // Start the server accept loop
149
    echo_server.start_accept();
156
    echo_server.start_accept(&on_end_accept);
150
157
151
    // Start the ASIO io_service run loop
158
    // Start the ASIO io_context run loop
152
    echo_server.run();
159
    echo_server.run();
153
160
154
}
161
}
(-)websocketpp-zaphoyd/examples/echo_server_tls/SConscript (-1 / +1 lines)
Lines 14-20 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
19
   prgs += env_cpp11.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
(-)websocketpp-zaphoyd/examples/enriched_storage/enriched_storage.cpp (-1 / +7 lines)
Lines 34-39 using websocketpp::connection_hdl; Link Here
34
using websocketpp::lib::placeholders::_1;
34
using websocketpp::lib::placeholders::_1;
35
using websocketpp::lib::placeholders::_2;
35
using websocketpp::lib::placeholders::_2;
36
using websocketpp::lib::bind;
36
using websocketpp::lib::bind;
37
using websocketpp::lib::error_code;
37
38
38
class print_server {
39
class print_server {
39
public:
40
public:
Lines 57-62 public: Link Here
57
        std::cout << "Closing connection " << con->name 
58
        std::cout << "Closing connection " << con->name 
58
                  << " with sessionid " << con->sessionid << std::endl;
59
                  << " with sessionid " << con->sessionid << std::endl;
59
    }
60
    }
61
62
    void on_end_accept(error_code lib_ec, error_code trans_ec) {
63
        std::cout << "Accept loop ended "
64
                  << lib_ec.message() << "/" << trans_ec.message() << std::endl;
65
    }
60
    
66
    
61
    void on_message(connection_hdl hdl, server::message_ptr msg) {
67
    void on_message(connection_hdl hdl, server::message_ptr msg) {
62
        connection_ptr con = m_server.get_con_from_hdl(hdl);
68
        connection_ptr con = m_server.get_con_from_hdl(hdl);
Lines 73-79 public: Link Here
73
    
79
    
74
    void run(uint16_t port) {
80
    void run(uint16_t port) {
75
        m_server.listen(port);
81
        m_server.listen(port);
76
        m_server.start_accept();
82
        m_server.start_accept(bind(&print_server::on_end_accept,this,::_1,::_2));
77
        m_server.run();
83
        m_server.run();
78
    }
84
    }
79
private:
85
private:
(-)websocketpp-zaphoyd/examples/external_io_context/CMakeLists.txt (+12 lines)
Line 0 Link Here
1
2
file (GLOB SOURCE_FILES *.cpp)
3
file (GLOB HEADER_FILES *.hpp)
4
5
init_target (external_io_context)
6
7
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
8
9
link_boost ()
10
final_target ()
11
12
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
(-)websocketpp-zaphoyd/examples/external_io_context/external_io_context.cpp (+92 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 2015, Peter Thorson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions are met:
6
 *     * Redistributions of source code must retain the above copyright
7
 *       notice, this list of conditions and the following disclaimer.
8
 *     * Redistributions in binary form must reproduce the above copyright
9
 *       notice, this list of conditions and the following disclaimer in the
10
 *       documentation and/or other materials provided with the distribution.
11
 *     * Neither the name of the WebSocket++ Project nor the
12
 *       names of its contributors may be used to endorse or promote products
13
 *       derived from this software without specific prior written permission.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "tcp_echo_server.hpp"
28
29
#include <websocketpp/config/asio_no_tls.hpp>
30
#include <websocketpp/server.hpp>
31
32
#include <iostream>
33
34
using websocketpp::lib::placeholders::_1;
35
using websocketpp::lib::placeholders::_2;
36
using websocketpp::lib::bind;
37
using websocketpp::lib::error_code;
38
39
typedef websocketpp::server<websocketpp::config::asio> ws_echo_server;
40
41
// Define a callback to handle incoming messages
42
void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_server::message_ptr msg) {
43
    std::cout << "on_message called with hdl: " << hdl.lock().get()
44
              << " and message: " << msg->get_payload()
45
              << std::endl;
46
47
    // check for a special command to instruct the server to stop listening so
48
    // it can be cleanly exited.
49
    if (msg->get_payload() == "stop-listening") {
50
        s->stop_listening();
51
        return;
52
    }
53
54
    try {
55
        s->send(hdl, msg->get_payload(), msg->get_opcode());
56
    } catch (websocketpp::exception const & e) {
57
        std::cout << "Echo failed because: "
58
                  << "(" << e.what() << ")" << std::endl;
59
    }
60
}
61
62
// Define a callback to handle failures accepting connections
63
void on_end_accept(error_code lib_ec, error_code trans_ec) {
64
    std::cout << "Accept loop ended "
65
                << lib_ec.message() << "/" << trans_ec.message() << std::endl;
66
}
67
68
int main() {
69
    websocketpp::lib::asio::io_context context;
70
71
    // Add a TCP echo server on port 9003
72
    tcp_echo_server custom_http_server(context, 9003);
73
74
    // Add a WebSocket echo server on port 9002
75
    ws_echo_server ws_server;
76
    ws_server.set_access_channels(websocketpp::log::alevel::all);
77
    ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
78
79
    // The only difference in this code between an internal and external
80
    // io_context is the different constructor to init_asio
81
    ws_server.init_asio(&context);
82
83
    // Register our message handler
84
    ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2));
85
    ws_server.listen(9002);
86
    ws_server.start_accept(&on_end_accept);
87
88
    // TODO: add a timer?
89
90
    // Start the Asio io_context run loop for all
91
    context.run();
92
}
(-)websocketpp-zaphoyd/examples/external_io_context/SConscript (+23 lines)
Line 0 Link Here
1
## Main development example
2
##
3
4
Import('env')
5
Import('env_cpp11')
6
Import('boostlibs')
7
Import('platform_libs')
8
Import('polyfill_libs')
9
10
env = env.Clone ()
11
env_cpp11 = env_cpp11.Clone ()
12
13
prgs = []
14
15
# if a C++11 environment is available build using that, otherwise use boost
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS)
19
else:
20
   ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
21
   prgs += env.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS)
22
23
Return('prgs')
(-)websocketpp-zaphoyd/examples/external_io_context/tcp_echo_server.hpp (+95 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 2015, Peter Thorson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions are met:
6
 *     * Redistributions of source code must retain the above copyright
7
 *       notice, this list of conditions and the following disclaimer.
8
 *     * Redistributions in binary form must reproduce the above copyright
9
 *       notice, this list of conditions and the following disclaimer in the
10
 *       documentation and/or other materials provided with the distribution.
11
 *     * Neither the name of the WebSocket++ Project nor the
12
 *       names of its contributors may be used to endorse or promote products
13
 *       derived from this software without specific prior written permission.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
/**
28
 * TCP Echo Server
29
 *
30
 * This file defines a simple TCP Echo Server. It is adapted from the Asio
31
 * example: cpp03/echo/async_tcp_echo_server.cpp
32
 */ 
33
34
#include <websocketpp/common/asio.hpp>
35
#include <websocketpp/common/memory.hpp>
36
#include <websocketpp/common/functional.hpp>
37
38
using websocketpp::lib::placeholders::_1;
39
using websocketpp::lib::placeholders::_2;
40
using websocketpp::lib::bind;
41
42
struct tcp_echo_session : websocketpp::lib::enable_shared_from_this<tcp_echo_session> {
43
    typedef websocketpp::lib::shared_ptr<tcp_echo_session> ptr;
44
    
45
    tcp_echo_session(websocketpp::lib::asio::io_context & context) : m_socket(context) {}
46
47
    void start() {
48
        m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)),
49
            websocketpp::lib::bind(
50
                &tcp_echo_session::handle_read, shared_from_this(), _1, _2));
51
    }
52
    
53
    void handle_read(const websocketpp::lib::asio::error_code & ec, size_t transferred) {
54
        if (!ec) {
55
            websocketpp::lib::asio::async_write(m_socket,
56
                websocketpp::lib::asio::buffer(m_buffer, transferred),
57
                    bind(&tcp_echo_session::handle_write, shared_from_this(), _1));
58
        }
59
    }
60
    
61
    void handle_write(const websocketpp::lib::asio::error_code & ec) {
62
        if (!ec) {
63
            m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)),
64
                bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2));
65
        }
66
    }
67
68
    websocketpp::lib::asio::ip::tcp::socket m_socket;
69
    char m_buffer[1024];
70
};
71
72
struct tcp_echo_server {
73
    tcp_echo_server(websocketpp::lib::asio::io_context & context, short port)
74
        : m_context(context)
75
        , m_acceptor(context, websocketpp::lib::asio::ip::tcp::endpoint(websocketpp::lib::asio::ip::tcp::v6(), port))
76
    {
77
        this->start_accept();
78
    }
79
    
80
    void start_accept() {
81
        tcp_echo_session::ptr new_session(new tcp_echo_session(m_context));
82
        m_acceptor.async_accept(new_session->m_socket,
83
            bind(&tcp_echo_server::handle_accept, this, new_session, _1));
84
    }
85
    
86
    void handle_accept(tcp_echo_session::ptr new_session, const websocketpp::lib::asio::error_code & ec) {
87
        if (!ec) {
88
            new_session->start();
89
        }
90
        start_accept();
91
    }
92
93
    websocketpp::lib::asio::io_context & m_context;
94
    websocketpp::lib::asio::ip::tcp::acceptor m_acceptor;
95
};
(-)websocketpp-zaphoyd/examples/external_io_service/CMakeLists.txt (-12 lines)
Lines 1-12 Link Here
1
2
file (GLOB SOURCE_FILES *.cpp)
3
file (GLOB HEADER_FILES *.hpp)
4
5
init_target (external_io_service)
6
7
build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES})
8
9
link_boost ()
10
final_target ()
11
12
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples")
(-)websocketpp-zaphoyd/examples/external_io_service/external_io_service.cpp (-85 lines)
Lines 1-85 Link Here
1
/*
2
 * Copyright (c) 2015, Peter Thorson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions are met:
6
 *     * Redistributions of source code must retain the above copyright
7
 *       notice, this list of conditions and the following disclaimer.
8
 *     * Redistributions in binary form must reproduce the above copyright
9
 *       notice, this list of conditions and the following disclaimer in the
10
 *       documentation and/or other materials provided with the distribution.
11
 *     * Neither the name of the WebSocket++ Project nor the
12
 *       names of its contributors may be used to endorse or promote products
13
 *       derived from this software without specific prior written permission.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#include "tcp_echo_server.hpp"
28
29
#include <websocketpp/config/asio_no_tls.hpp>
30
#include <websocketpp/server.hpp>
31
32
#include <iostream>
33
34
using websocketpp::lib::placeholders::_1;
35
using websocketpp::lib::placeholders::_2;
36
using websocketpp::lib::bind;
37
38
typedef websocketpp::server<websocketpp::config::asio> ws_echo_server;
39
40
// Define a callback to handle incoming messages
41
void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_server::message_ptr msg) {
42
    std::cout << "on_message called with hdl: " << hdl.lock().get()
43
              << " and message: " << msg->get_payload()
44
              << std::endl;
45
46
    // check for a special command to instruct the server to stop listening so
47
    // it can be cleanly exited.
48
    if (msg->get_payload() == "stop-listening") {
49
        s->stop_listening();
50
        return;
51
    }
52
53
    try {
54
        s->send(hdl, msg->get_payload(), msg->get_opcode());
55
    } catch (websocketpp::exception const & e) {
56
        std::cout << "Echo failed because: "
57
                  << "(" << e.what() << ")" << std::endl;
58
    }
59
}
60
61
int main() {
62
    asio::io_service service;
63
64
    // Add a TCP echo server on port 9003
65
    tcp_echo_server custom_http_server(service, 9003);
66
67
    // Add a WebSocket echo server on port 9002
68
    ws_echo_server ws_server;
69
    ws_server.set_access_channels(websocketpp::log::alevel::all);
70
    ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
71
72
    // The only difference in this code between an internal and external
73
    // io_service is the different constructor to init_asio
74
    ws_server.init_asio(&service);
75
76
    // Register our message handler
77
    ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2));
78
    ws_server.listen(9002);
79
    ws_server.start_accept();
80
81
    // TODO: add a timer?
82
83
    // Start the Asio io_service run loop for all
84
    service.run();
85
}
(-)websocketpp-zaphoyd/examples/external_io_service/SConscript (-23 lines)
Lines 1-23 Link Here
1
## Main development example
2
##
3
4
Import('env')
5
Import('env_cpp11')
6
Import('boostlibs')
7
Import('platform_libs')
8
Import('polyfill_libs')
9
10
env = env.Clone ()
11
env_cpp11 = env_cpp11.Clone ()
12
13
prgs = []
14
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS)
19
else:
20
   ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs]
21
   prgs += env.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS)
22
23
Return('prgs')
(-)websocketpp-zaphoyd/examples/external_io_service/tcp_echo_server.hpp (-97 lines)
Lines 1-97 Link Here
1
/*
2
 * Copyright (c) 2015, Peter Thorson. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions are met:
6
 *     * Redistributions of source code must retain the above copyright
7
 *       notice, this list of conditions and the following disclaimer.
8
 *     * Redistributions in binary form must reproduce the above copyright
9
 *       notice, this list of conditions and the following disclaimer in the
10
 *       documentation and/or other materials provided with the distribution.
11
 *     * Neither the name of the WebSocket++ Project nor the
12
 *       names of its contributors may be used to endorse or promote products
13
 *       derived from this software without specific prior written permission.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
/**
28
 * TCP Echo Server
29
 *
30
 * This file defines a simple TCP Echo Server. It is adapted from the Asio
31
 * example: cpp03/echo/async_tcp_echo_server.cpp
32
 */ 
33
34
#include <websocketpp/common/asio.hpp>
35
#include <websocketpp/common/memory.hpp>
36
#include <websocketpp/common/functional.hpp>
37
38
using websocketpp::lib::placeholders::_1;
39
using websocketpp::lib::placeholders::_2;
40
using websocketpp::lib::bind;
41
42
namespace asio = websocketpp::lib::asio;
43
44
struct tcp_echo_session : websocketpp::lib::enable_shared_from_this<tcp_echo_session> {
45
    typedef websocketpp::lib::shared_ptr<tcp_echo_session> ptr;
46
    
47
    tcp_echo_session(asio::io_service & service) : m_socket(service) {}
48
49
    void start() {
50
        m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)),
51
            websocketpp::lib::bind(
52
                &tcp_echo_session::handle_read, shared_from_this(), _1, _2));
53
    }
54
    
55
    void handle_read(const asio::error_code & ec, size_t transferred) {
56
        if (!ec) {
57
            asio::async_write(m_socket,
58
                asio::buffer(m_buffer, transferred),
59
                    bind(&tcp_echo_session::handle_write, shared_from_this(), _1));
60
        }
61
    }
62
    
63
    void handle_write(const asio::error_code & ec) {
64
        if (!ec) {
65
            m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)),
66
                bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2));
67
        }
68
    }
69
70
    asio::ip::tcp::socket m_socket;
71
    char m_buffer[1024];
72
};
73
74
struct tcp_echo_server {
75
    tcp_echo_server(asio::io_service & service, short port)
76
        : m_service(service)
77
        , m_acceptor(service, asio::ip::tcp::endpoint(asio::ip::tcp::v6(), port))
78
    {
79
        this->start_accept();
80
    }
81
    
82
    void start_accept() {
83
        tcp_echo_session::ptr new_session(new tcp_echo_session(m_service));
84
        m_acceptor.async_accept(new_session->m_socket,
85
            bind(&tcp_echo_server::handle_accept, this, new_session, _1));
86
    }
87
    
88
    void handle_accept(tcp_echo_session::ptr new_session, const asio::error_code & ec) {
89
        if (!ec) {
90
            new_session->start();
91
        }
92
        start_accept();
93
    }
94
95
    asio::io_service & m_service;
96
    asio::ip::tcp::acceptor m_acceptor;
97
};
(-)websocketpp-zaphoyd/examples/handler_switch/handler_switch.cpp (-1 / +1 lines)
Lines 36-42 int main() { Link Here
36
36
37
    s.init_asio();
37
    s.init_asio();
38
    s.listen(9002);
38
    s.listen(9002);
39
    s.start_accept();
39
    s.start_accept(NULL); // ignore errors to keep example code consise
40
40
41
    s.run();
41
    s.run();
42
}
42
}
(-)websocketpp-zaphoyd/examples/iostream_server/iostream_server.cpp (-2 / +8 lines)
Lines 10-15 typedef websocketpp::server<websocketpp: Link Here
10
using websocketpp::lib::placeholders::_1;
10
using websocketpp::lib::placeholders::_1;
11
using websocketpp::lib::placeholders::_2;
11
using websocketpp::lib::placeholders::_2;
12
using websocketpp::lib::bind;
12
using websocketpp::lib::bind;
13
using websocketpp::lib::error_code;
13
14
14
// pull out the type of messages sent by our config
15
// pull out the type of messages sent by our config
15
typedef server::message_ptr message_ptr;
16
typedef server::message_ptr message_ptr;
Lines 55-61 int main() { Link Here
55
        // Register our message handler
56
        // Register our message handler
56
        s.set_message_handler(bind(&on_message,&s,::_1,::_2));
57
        s.set_message_handler(bind(&on_message,&s,::_1,::_2));
57
58
58
        server::connection_ptr con = s.get_connection();
59
        error_code ec;
60
        server::connection_ptr con = s.get_connection(ec);
61
        if (ec) {
62
            std::cout << "Failed to generate new connection because " << ec.message() << std::endl;
63
            return 1;
64
        }
59
65
60
        con->start();
66
        con->start();
61
67
Lines 69-75 int main() { Link Here
69
        // messages being buffered forever. The non-buffered strategy below
75
        // messages being buffered forever. The non-buffered strategy below
70
        // reads characters from stdin one at a time. This is inefficient and
76
        // reads characters from stdin one at a time. This is inefficient and
71
        // for more serious uses should be replaced with a platform specific
77
        // for more serious uses should be replaced with a platform specific
72
        // asyncronous i/o technique like select, poll, IOCP, etc
78
        // asynchronous i/o technique like select, poll, IOCP, etc
73
        bool buffered_io = false;
79
        bool buffered_io = false;
74
80
75
        if (buffered_io) {
81
        if (buffered_io) {
(-)websocketpp-zaphoyd/examples/iostream_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/print_client/print_client.cpp (-1 / +1 lines)
Lines 68-74 int main(int argc, char* argv[]) { Link Here
68
        // exchanged until the event loop starts running in the next line.
68
        // exchanged until the event loop starts running in the next line.
69
        c.connect(con);
69
        c.connect(con);
70
70
71
        // Start the ASIO io_service run loop
71
        // Start the ASIO io_context run loop
72
        // this will cause a single connection to be made to the server. c.run()
72
        // this will cause a single connection to be made to the server. c.run()
73
        // will exit when this connection is closed.
73
        // will exit when this connection is closed.
74
        c.run();
74
        c.run();
(-)websocketpp-zaphoyd/examples/print_client/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('print_client', ["print_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('print_client', ["print_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/print_client_tls/print_client_tls.cpp (-8 / +8 lines)
Lines 112-118 bool verify_common_name(char const * hos Link Here
112
 * and
112
 * and
113
 * https://github.com/iSECPartners/ssl-conservatory
113
 * https://github.com/iSECPartners/ssl-conservatory
114
 */
114
 */
115
bool verify_certificate(const char * hostname, bool preverified, boost::asio::ssl::verify_context& ctx) {
115
bool verify_certificate(const char * hostname, bool preverified, websocketpp::lib::asio::ssl::verify_context& ctx) {
116
    // The verify callback can be used to check whether the certificate that is
116
    // The verify callback can be used to check whether the certificate that is
117
    // being presented is valid for the peer. For example, RFC 2818 describes
117
    // being presented is valid for the peer. For example, RFC 2818 describes
118
    // the steps involved in doing this for HTTPS. Consult the OpenSSL
118
    // the steps involved in doing this for HTTPS. Consult the OpenSSL
Lines 176-191 bool verify_certificate(const char * hos Link Here
176
 * (websocketpp.org, for example).
176
 * (websocketpp.org, for example).
177
 */
177
 */
178
context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
178
context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
179
    context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);
179
    context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(websocketpp::lib::asio::ssl::context::sslv23);
180
180
181
    try {
181
    try {
182
        ctx->set_options(boost::asio::ssl::context::default_workarounds |
182
        ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds |
183
                         boost::asio::ssl::context::no_sslv2 |
183
                         websocketpp::lib::asio::ssl::context::no_sslv2 |
184
                         boost::asio::ssl::context::no_sslv3 |
184
                         websocketpp::lib::asio::ssl::context::no_sslv3 |
185
                         boost::asio::ssl::context::single_dh_use);
185
                         websocketpp::lib::asio::ssl::context::single_dh_use);
186
186
187
187
188
        ctx->set_verify_mode(boost::asio::ssl::verify_peer);
188
        ctx->set_verify_mode(websocketpp::lib::asio::ssl::verify_peer);
189
        ctx->set_verify_callback(bind(&verify_certificate, hostname, ::_1, ::_2));
189
        ctx->set_verify_callback(bind(&verify_certificate, hostname, ::_1, ::_2));
190
190
191
        // Here we load the CA certificates of all CA's that this client trusts.
191
        // Here we load the CA certificates of all CA's that this client trusts.
Lines 239-245 int main(int argc, char* argv[]) { Link Here
239
239
240
        c.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri);
240
        c.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri);
241
241
242
        // Start the ASIO io_service run loop
242
        // Start the ASIO io_context run loop
243
        // this will cause a single connection to be made to the server. c.run()
243
        // this will cause a single connection to be made to the server. c.run()
244
        // will exit when this connection is closed.
244
        // will exit when this connection is closed.
245
        c.run();
245
        c.run();
(-)websocketpp-zaphoyd/examples/print_client_tls/SConscript (-1 / +1 lines)
Lines 14-20 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
19
   prgs += env_cpp11.Program('print_client_tls', ["print_client_tls.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('print_client_tls', ["print_client_tls.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
(-)websocketpp-zaphoyd/examples/print_server/print_server.cpp (-1 / +1 lines)
Lines 18-24 int main() { Link Here
18
18
19
    print_server.init_asio();
19
    print_server.init_asio();
20
    print_server.listen(9002);
20
    print_server.listen(9002);
21
    print_server.start_accept();
21
    print_server.start_accept(NULL); // omit error handling to keep example consise
22
22
23
    print_server.run();
23
    print_server.run();
24
}
24
}
(-)websocketpp-zaphoyd/examples/print_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/scratch_client/SConscript (-2 / +2 lines)
Lines 14-24 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
19
   prgs += env_cpp11.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
21
   ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
21
   ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
22
   prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
22
   prgs += env.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS)
23
   
23
   
24
Return('prgs')
24
Return('prgs')
(-)websocketpp-zaphoyd/examples/scratch_server/SConscript (-1 / +1 lines)
Lines 14-20 env_cpp11 = env_cpp11.Clone () Link Here
14
prgs = []
14
prgs = []
15
15
16
# if a C++11 environment is available build using that, otherwise use boost
16
# if a C++11 environment is available build using that, otherwise use boost
17
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
17
if 'WSPP_CPP11_ENABLED' in env_cpp11:
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] + ['z']
18
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] + ['z']
19
   prgs += env_cpp11.Program('scratch_server', ["scratch_server.cpp"], LIBS = ALL_LIBS)
19
   prgs += env_cpp11.Program('scratch_server', ["scratch_server.cpp"], LIBS = ALL_LIBS)
20
else:
20
else:
(-)websocketpp-zaphoyd/examples/scratch_server/scratch_server.cpp (-1 / +1 lines)
Lines 94-100 int main(int argc, char * argv[]) { Link Here
94
        // Start the server accept loop
94
        // Start the server accept loop
95
        echo_server.start_accept();
95
        echo_server.start_accept();
96
	    
96
	    
97
	    // Start the ASIO io_service run loop
97
	    // Start the ASIO io_context run loop
98
        echo_server.run();
98
        echo_server.run();
99
    } catch (websocketpp::exception const & e) {
99
    } catch (websocketpp::exception const & e) {
100
        std::cout << e.what() << std::endl;
100
        std::cout << e.what() << std::endl;
(-)websocketpp-zaphoyd/examples/simple_broadcast_server/simple_broadcast_server.cpp (-1 / +7 lines)
Lines 8-13 using websocketpp::connection_hdl; Link Here
8
using websocketpp::lib::placeholders::_1;
8
using websocketpp::lib::placeholders::_1;
9
using websocketpp::lib::placeholders::_2;
9
using websocketpp::lib::placeholders::_2;
10
using websocketpp::lib::bind;
10
using websocketpp::lib::bind;
11
using websocketpp::lib::error_code;
11
12
12
class broadcast_server {
13
class broadcast_server {
13
public:
14
public:
Lines 27-32 public: Link Here
27
        m_connections.erase(hdl);
28
        m_connections.erase(hdl);
28
    }
29
    }
29
30
31
    void on_end_accept(error_code lib_ec, error_code trans_ec) {
32
        std::cout << "Accept loop ended "
33
                  << lib_ec.message() << "/" << trans_ec.message() << std::endl;
34
    }
35
30
    void on_message(connection_hdl hdl, server::message_ptr msg) {
36
    void on_message(connection_hdl hdl, server::message_ptr msg) {
31
        for (auto it : m_connections) {
37
        for (auto it : m_connections) {
32
            m_server.send(it,msg);
38
            m_server.send(it,msg);
Lines 35-41 public: Link Here
35
41
36
    void run(uint16_t port) {
42
    void run(uint16_t port) {
37
        m_server.listen(port);
43
        m_server.listen(port);
38
        m_server.start_accept();
44
        m_server.start_accept(bind(&broadcast_server::on_end_accept,this,::_1,::_2));
39
        m_server.run();
45
        m_server.run();
40
    }
46
    }
41
private:
47
private:
(-)websocketpp-zaphoyd/examples/sip_client/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/sip_client/sip_client.cpp (-1 / +1 lines)
Lines 69-75 int main(int argc, char* argv[]) { Link Here
69
69
70
        sip_client.connect(con);
70
        sip_client.connect(con);
71
71
72
        // Start the ASIO io_service run loop
72
        // Start the ASIO io_context run loop
73
        sip_client.run();
73
        sip_client.run();
74
74
75
        while(!received) {
75
        while(!received) {
(-)websocketpp-zaphoyd/examples/subprotocol_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/subprotocol_server/subprotocol_server.cpp (-1 / +1 lines)
Lines 39-45 int main() { Link Here
39
39
40
        s.init_asio();
40
        s.init_asio();
41
        s.listen(9005);
41
        s.listen(9005);
42
        s.start_accept();
42
        s.start_accept(NULL); // omit error handling to keep example consise
43
43
44
        s.run();
44
        s.run();
45
    } catch (websocketpp::exception const & e) {
45
    } catch (websocketpp::exception const & e) {
(-)websocketpp-zaphoyd/examples/telemetry_client/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/telemetry_client/telemetry_client.cpp (-2 / +2 lines)
Lines 62-71 public: Link Here
62
        m_hdl = con->get_handle();
62
        m_hdl = con->get_handle();
63
63
64
        // Queue the connection. No DNS queries or network connections will be
64
        // Queue the connection. No DNS queries or network connections will be
65
        // made until the io_service event loop is run.
65
        // made until the io_context event loop is run.
66
        m_client.connect(con);
66
        m_client.connect(con);
67
67
68
        // Create a thread to run the ASIO io_service event loop
68
        // Create a thread to run the ASIO io_context event loop
69
        websocketpp::lib::thread asio_thread(&client::run, &m_client);
69
        websocketpp::lib::thread asio_thread(&client::run, &m_client);
70
70
71
        // Create a thread to run the telemetry loop
71
        // Create a thread to run the telemetry loop
(-)websocketpp-zaphoyd/examples/telemetry_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/telemetry_server/telemetry_server.cpp (-6 / +14 lines)
Lines 8-13 Link Here
8
#include <streambuf>
8
#include <streambuf>
9
#include <string>
9
#include <string>
10
10
11
using websocketpp::lib::placeholders::_1;
12
using websocketpp::lib::placeholders::_2;
13
using websocketpp::lib::bind;
14
using websocketpp::lib::error_code;
15
11
/**
16
/**
12
 * The telemetry server accepts connections and sends a message every second to
17
 * The telemetry server accepts connections and sends a message every second to
13
 * each client containing an integer count. This example can be used as the
18
 * each client containing an integer count. This example can be used as the
Lines 43-50 public: Link Here
43
        m_endpoint.init_asio();
48
        m_endpoint.init_asio();
44
49
45
        // Bind the handlers we are using
50
        // Bind the handlers we are using
46
        using websocketpp::lib::placeholders::_1;
47
        using websocketpp::lib::bind;
48
        m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1));
51
        m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1));
49
        m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1));
52
        m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1));
50
        m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1));
53
        m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1));
Lines 61-72 public: Link Here
61
        m_endpoint.listen(port);
64
        m_endpoint.listen(port);
62
65
63
        // Start the server accept loop
66
        // Start the server accept loop
64
        m_endpoint.start_accept();
67
        m_endpoint.start_accept(bind(&telemetry_server::on_end_accept,this,_1,_2));
65
68
66
        // Set the initial timer to start telemetry
69
        // Set the initial timer to start telemetry
67
        set_timer();
70
        set_timer();
68
71
69
        // Start the ASIO io_service run loop
72
        // Start the ASIO io_context run loop
70
        try {
73
        try {
71
            m_endpoint.run();
74
            m_endpoint.run();
72
        } catch (websocketpp::exception const & e) {
75
        } catch (websocketpp::exception const & e) {
Lines 85-91 public: Link Here
85
        );
88
        );
86
    }
89
    }
87
90
88
    void on_timer(websocketpp::lib::error_code const & ec) {
91
    void on_timer(error_code const & ec) {
89
        if (ec) {
92
        if (ec) {
90
            // there was an error, stop telemetry
93
            // there was an error, stop telemetry
91
            m_endpoint.get_alog().write(websocketpp::log::alevel::app,
94
            m_endpoint.get_alog().write(websocketpp::log::alevel::app,
Lines 149-155 public: Link Here
149
        response.assign((std::istreambuf_iterator<char>(file)),
152
        response.assign((std::istreambuf_iterator<char>(file)),
150
                        std::istreambuf_iterator<char>());
153
                        std::istreambuf_iterator<char>());
151
    
154
    
152
        con->set_body(response);
155
        con->set_body(std::move(response));
153
        con->set_status(websocketpp::http::status_code::ok);
156
        con->set_status(websocketpp::http::status_code::ok);
154
    }
157
    }
155
158
Lines 160-165 public: Link Here
160
    void on_close(connection_hdl hdl) {
163
    void on_close(connection_hdl hdl) {
161
        m_connections.erase(hdl);
164
        m_connections.erase(hdl);
162
    }
165
    }
166
167
    void on_end_accept(error_code lib_ec, error_code trans_ec) {
168
        std::cout << "Accept loop ended "
169
                  << lib_ec.message() << "/" << trans_ec.message() << std::endl;
170
    }
163
private:
171
private:
164
    typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
172
    typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
165
    
173
    
(-)websocketpp-zaphoyd/examples/testee_client/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
18
   prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/testee_client/testee_client.cpp (-1 / +1 lines)
Lines 117-123 int main(int argc, char* argv[]) { Link Here
117
        client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec);
117
        client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec);
118
        c.connect(con);
118
        c.connect(con);
119
119
120
        // Start the ASIO io_service run loop
120
        // Start the ASIO io_context run loop
121
        c.run();
121
        c.run();
122
122
123
        std::cout << "case count: " << case_count << std::endl;
123
        std::cout << "case count: " << case_count << std::endl;
(-)websocketpp-zaphoyd/examples/testee_server/SConscript (-1 / +1 lines)
Lines 13-19 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
18
   prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
(-)websocketpp-zaphoyd/examples/testee_server/testee_server.cpp (-4 / +11 lines)
Lines 78-83 typedef websocketpp::server<testee_confi Link Here
78
using websocketpp::lib::placeholders::_1;
78
using websocketpp::lib::placeholders::_1;
79
using websocketpp::lib::placeholders::_2;
79
using websocketpp::lib::placeholders::_2;
80
using websocketpp::lib::bind;
80
using websocketpp::lib::bind;
81
using websocketpp::lib::error_code;
81
82
82
// pull out the type of messages sent by our config
83
// pull out the type of messages sent by our config
83
typedef server::message_ptr message_ptr;
84
typedef server::message_ptr message_ptr;
Lines 87-97 void on_message(server* s, websocketpp:: Link Here
87
    s->send(hdl, msg->get_payload(), msg->get_opcode());
88
    s->send(hdl, msg->get_payload(), msg->get_opcode());
88
}
89
}
89
90
90
void on_socket_init(websocketpp::connection_hdl, boost::asio::ip::tcp::socket & s) {
91
void on_socket_init(websocketpp::connection_hdl, websocketpp::lib::asio::ip::tcp::socket & s) {
91
    boost::asio::ip::tcp::no_delay option(true);
92
    websocketpp::lib::asio::ip::tcp::no_delay option(true);
92
    s.set_option(option);
93
    s.set_option(option);
93
}
94
}
94
95
96
// Define a callback to handle failures accepting connections
97
void on_end_accept(error_code lib_ec, error_code trans_ec) {
98
    std::cout << "Accept loop ended "
99
                << lib_ec.message() << "/" << trans_ec.message() << std::endl;
100
}
101
95
int main(int argc, char * argv[]) {
102
int main(int argc, char * argv[]) {
96
    // Create a server endpoint
103
    // Create a server endpoint
97
    server testee_server;
104
    server testee_server;
Lines 122-130 int main(int argc, char * argv[]) { Link Here
122
        testee_server.listen(port);
129
        testee_server.listen(port);
123
130
124
        // Start the server accept loop
131
        // Start the server accept loop
125
        testee_server.start_accept();
132
        testee_server.start_accept(&on_end_accept);
126
133
127
        // Start the ASIO io_service run loop
134
        // Start the ASIO io_context run loop
128
        if (num_threads == 1) {
135
        if (num_threads == 1) {
129
            testee_server.run();
136
            testee_server.run();
130
        } else {
137
        } else {
(-)websocketpp-zaphoyd/examples/utility_client/SConscript (-2 / +2 lines)
Lines 13-23 env_cpp11 = env_cpp11.Clone () Link Here
13
prgs = []
13
prgs = []
14
14
15
# if a C++11 environment is available build using that, otherwise use boost
15
# if a C++11 environment is available build using that, otherwise use boost
16
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
16
if 'WSPP_CPP11_ENABLED' in env_cpp11:
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
17
   ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs]
18
   prgs += env_cpp11.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
18
   prgs += env_cpp11.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
19
else:
19
else:
20
   ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
20
   ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs]
21
   prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
21
   prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS)
22
22
23
Return('prgs')
23
Return('prgs')
(-)websocketpp-zaphoyd/readme.md (-1 / +5 lines)
Lines 1-4 Link Here
1
WebSocket++ (0.8.2)
1
WebSocket++ (0.8.x-dev)
2
==========================
2
==========================
3
3
4
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
4
WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket
Lines 44-49 http://groups.google.com/group/websocket Link Here
44
**Discussion / Development / Support Mailing List / Forum**
44
**Discussion / Development / Support Mailing List / Forum**
45
http://groups.google.com/group/websocketpp/
45
http://groups.google.com/group/websocketpp/
46
46
47
License
48
======
49
3-Clause BSD (See COPYING for more details)
50
47
Author
51
Author
48
======
52
======
49
Peter Thorson - websocketpp@zaphoyd.com
53
Peter Thorson - websocketpp@zaphoyd.com
(-)websocketpp-zaphoyd/SConstruct (-24 / +26 lines)
Lines 1-18 Link Here
1
import os, sys, commands
1
import os, sys, SCons.Errors
2
from subprocess import check_output
3
2
env = Environment(ENV = os.environ)
4
env = Environment(ENV = os.environ)
3
5
4
# figure out a better way to configure this
6
# figure out a better way to configure this
5
if os.environ.has_key('CXX'):
7
if 'CXX' in os.environ:
6
    env['CXX'] = os.environ['CXX']
8
    env['CXX'] = os.environ['CXX']
7
9
8
if os.environ.has_key('DEBUG'):
10
if 'DEBUG' in os.environ:
9
    env['DEBUG'] = os.environ['DEBUG']
11
    env['DEBUG'] = os.environ['DEBUG']
10
12
11
if os.environ.has_key('CXXFLAGS'):
13
if 'CXXFLAGS' in os.environ:
12
    #env['CXXFLAGS'] = os.environ['CXXFLAGS']
14
    #env['CXXFLAGS'] = os.environ['CXXFLAGS']
13
    env.Append(CXXFLAGS = os.environ['CXXFLAGS'])
15
    env.Append(CXXFLAGS = os.environ['CXXFLAGS'])
14
16
15
if os.environ.has_key('LINKFLAGS'):
17
if 'LINKFLAGS' in os.environ:
16
    #env['LDFLAGS'] = os.environ['LDFLAGS']
18
    #env['LDFLAGS'] = os.environ['LDFLAGS']
17
    env.Append(LINKFLAGS = os.environ['LINKFLAGS'])
19
    env.Append(LINKFLAGS = os.environ['LINKFLAGS'])
18
20
Lines 22-45 if os.environ.has_key('LINKFLAGS'): Link Here
22
## or set BOOST_INCLUDES and BOOST_LIBS if Boost comes with your OS distro e.g. and
24
## or set BOOST_INCLUDES and BOOST_LIBS if Boost comes with your OS distro e.g. and
23
## needs BOOST_INCLUDES=/usr/include/boost and BOOST_LIBS=/usr/lib like Ubuntu.
25
## needs BOOST_INCLUDES=/usr/include/boost and BOOST_LIBS=/usr/lib like Ubuntu.
24
##
26
##
25
if os.environ.has_key('BOOSTROOT'):
27
if 'BOOSTROOT' in os.environ:
26
    os.environ['BOOST_ROOT'] = os.environ['BOOSTROOT']
28
    os.environ['BOOST_ROOT'] = os.environ['BOOSTROOT']
27
29
28
if os.environ.has_key('BOOST_ROOT'):
30
if 'BOOST_ROOT' in os.environ:
29
   env['BOOST_INCLUDES'] = os.environ['BOOST_ROOT']
31
   env['BOOST_INCLUDES'] = os.environ['BOOST_ROOT']
30
   env['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT'], 'stage', 'lib')
32
   env['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT'], 'stage', 'lib')
31
elif os.environ.has_key('BOOST_INCLUDES') and os.environ.has_key('BOOST_LIBS'):
33
elif 'BOOST_INCLUDES' in os.environ and 'BOOST_LIBS' in os.environ:
32
   env['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES']
34
   env['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES']
33
   env['BOOST_LIBS'] = os.environ['BOOST_LIBS']
35
   env['BOOST_LIBS'] = os.environ['BOOST_LIBS']
34
else:
36
else:
35
   raise SCons.Errors.UserError, "Neither BOOST_ROOT, nor BOOST_INCLUDES + BOOST_LIBS was set!"
37
   raise SCons.Errors.UserError("Neither BOOST_ROOT, nor BOOST_INCLUDES + BOOST_LIBS were set!")
36
38
37
## Custom OpenSSL
39
## Custom OpenSSL
38
if os.environ.has_key('OPENSSL_PATH'):
40
if 'OPENSSL_PATH' in os.environ:
39
   env.Append(CPPPATH = os.path.join(os.environ['OPENSSL_PATH'], 'include'))
41
   env.Append(CPPPATH = os.path.join(os.environ['OPENSSL_PATH'], 'include'))
40
   env.Append(LIBPATH = os.environ['OPENSSL_PATH'])
42
   env.Append(LIBPATH = os.environ['OPENSSL_PATH'])
41
43
42
if os.environ.has_key('WSPP_ENABLE_CPP11'):
44
if 'WSPP_ENABLE_CPP11' in os.environ:
43
   env['WSPP_ENABLE_CPP11'] = True
45
   env['WSPP_ENABLE_CPP11'] = True
44
else:
46
else:
45
   env['WSPP_ENABLE_CPP11'] = False
47
   env['WSPP_ENABLE_CPP11'] = False
Lines 76-82 if env['PLATFORM'].startswith('win'): Link Here
76
   env['CCFLAGS'] = '%s /EHsc /GR /GS- /MD /nologo %s %s' % (warn_flags, arch_flags, opt_flags)
78
   env['CCFLAGS'] = '%s /EHsc /GR /GS- /MD /nologo %s %s' % (warn_flags, arch_flags, opt_flags)
77
   env['LINKFLAGS'] = '/INCREMENTAL:NO /MANIFEST /NOLOGO /OPT:REF /OPT:ICF /MACHINE:X86'
79
   env['LINKFLAGS'] = '/INCREMENTAL:NO /MANIFEST /NOLOGO /OPT:REF /OPT:ICF /MACHINE:X86'
78
elif env['PLATFORM'] == 'posix':
80
elif env['PLATFORM'] == 'posix':
79
   if env.has_key('DEBUG'):
81
   if 'DEBUG' in env:
80
      env.Append(CCFLAGS = ['-g', '-O0'])
82
      env.Append(CCFLAGS = ['-g', '-O0'])
81
   else:
83
   else:
82
      env.Append(CPPDEFINES = ['NDEBUG'])
84
      env.Append(CPPDEFINES = ['NDEBUG'])
Lines 84-92 elif env['PLATFORM'] == 'posix': Link Here
84
   env.Append(CCFLAGS = ['-Wall'])
86
   env.Append(CCFLAGS = ['-Wall'])
85
   #env['LINKFLAGS'] = ''
87
   #env['LINKFLAGS'] = ''
86
elif env['PLATFORM'] == 'darwin':
88
elif env['PLATFORM'] == 'darwin':
87
   if not os.environ.has_key('CXX'):
89
   if not 'CXX' in os.environ:
88
      env['CXX'] = "clang++"
90
      env['CXX'] = "clang++"
89
   if env.has_key('DEBUG'):
91
   if 'DEBUG' in env:
90
      env.Append(CCFLAGS = ['-g', '-O0'])
92
      env.Append(CCFLAGS = ['-g', '-O0'])
91
   else:
93
   else:
92
      env.Append(CPPDEFINES = ['NDEBUG'])
94
      env.Append(CPPDEFINES = ['NDEBUG'])
Lines 157-185 env_cpp11 = env.Clone () Link Here
157
159
158
if env_cpp11['CXX'].startswith('g++'):
160
if env_cpp11['CXX'].startswith('g++'):
159
   # TODO: check g++ version
161
   # TODO: check g++ version
160
   GCC_VERSION = commands.getoutput(env_cpp11['CXX'] + ' -dumpversion')
162
   GCC_VERSION = check_output([env_cpp11['CXX'], '-dumpversion']).decode("utf-8")
161
163
162
   if GCC_VERSION > "4.4.0":
164
   if GCC_VERSION > "4.4.0":
163
      print "C++11 build environment partially enabled"
165
      print("C++11 build environment partially enabled")
164
      env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
166
      env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
165
   else:
167
   else:
166
      print "C++11 build environment is not supported on this version of G++"
168
      print("C++11 build environment is not supported on this version of G++")
167
elif env_cpp11['CXX'].startswith('clang++'):
169
elif env_cpp11['CXX'].startswith('clang++'):
168
   print "C++11 build environment enabled"
170
   print("C++11 build environment enabled")
169
   env.Append(CXXFLANGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++'])
171
   env.Append(CXXFLAGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++'])
170
   env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x','-stdlib=libc++'],LINKFLAGS = ['-stdlib=libc++'],TOOLSET = ['clang++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
172
   env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x','-stdlib=libc++'],LINKFLAGS = ['-stdlib=libc++'],TOOLSET = ['clang++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_'])
171
173
172
   # look for optional second boostroot compiled with clang's libc++ STL library
174
   # look for optional second boostroot compiled with clang's libc++ STL library
173
   # this prevents warnings/errors when linking code built with two different
175
   # this prevents warnings/errors when linking code built with two different
174
   # incompatible STL libraries.
176
   # incompatible STL libraries.
175
   if os.environ.has_key('BOOST_ROOT_CPP11'):
177
   if 'BOOST_ROOT_CPP11' in os.environ:
176
      env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_ROOT_CPP11']
178
      env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_ROOT_CPP11']
177
      env_cpp11['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT_CPP11'], 'stage', 'lib')
179
      env_cpp11['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT_CPP11'], 'stage', 'lib')
178
   elif os.environ.has_key('BOOST_INCLUDES_CPP11') and os.environ.has_key('BOOST_LIBS_CPP11'):
180
   elif 'BOOST_INCLUDES_CPP11' in os.environ and 'BOOST_LIBS_CPP11' in os.environ:
179
      env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES_CPP11']
181
      env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES_CPP11']
180
      env_cpp11['BOOST_LIBS'] = os.environ['BOOST_LIBS_CPP11']
182
      env_cpp11['BOOST_LIBS'] = os.environ['BOOST_LIBS_CPP11']
181
else:
183
else:
182
   print "C++11 build environment disabled"
184
   print("C++11 build environment disabled")
183
185
184
# if the build system is known to allow the isystem modifier for library include
186
# if the build system is known to allow the isystem modifier for library include
185
# values then use it for the boost libraries. Otherwise just add them to the
187
# values then use it for the boost libraries. Otherwise just add them to the
Lines 271-278 subprotocol_server = SConscript('#/examp Link Here
271
# telemetry_server
273
# telemetry_server
272
telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0)
274
telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0)
273
275
274
# external_io_service
276
# external_io_context
275
external_io_service = SConscript('#/examples/external_io_service/SConscript',variant_dir = builddir + 'external_io_service',duplicate = 0)
277
external_io_context = SConscript('#/examples/external_io_context/SConscript',variant_dir = builddir + 'external_io_context',duplicate = 0)
276
278
277
if not env['PLATFORM'].startswith('win'):
279
if not env['PLATFORM'].startswith('win'):
278
    # iostream_server
280
    # iostream_server
(-)websocketpp-zaphoyd/test/connection/connection.cpp (+26 lines)
Lines 175-180 void http_func(server* s, websocketpp::c Link Here
175
    BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
175
    BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
176
}
176
}
177
177
178
void http_func_with_move(server* s, websocketpp::connection_hdl hdl) {
179
    using namespace websocketpp::http;
180
181
    server::connection_ptr con = s->get_con_from_hdl(hdl);
182
183
    std::string res = con->get_resource();
184
185
    con->set_body(std::move(res));
186
    con->set_status(status_code::ok);
187
188
    BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok);
189
    BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
190
}
191
178
void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
192
void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
179
    *deferred = true;
193
    *deferred = true;
180
    
194
    
Lines 239-244 BOOST_AUTO_TEST_CASE( http_request ) { Link Here
239
253
240
    BOOST_CHECK_EQUAL(run_server_test(s,input), output);
254
    BOOST_CHECK_EQUAL(run_server_test(s,input), output);
241
}
255
}
256
257
BOOST_AUTO_TEST_CASE( http_request_with_move ) {
258
    std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
259
    std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
260
    output+=websocketpp::user_agent;
261
    output+="\r\n\r\n/foo/bar";
262
263
    server s;
264
    s.set_http_handler(bind(&http_func_with_move,&s,::_1));
265
266
    BOOST_CHECK_EQUAL(run_server_test(s,input), output);
267
}
242
268
243
BOOST_AUTO_TEST_CASE( deferred_http_request ) {
269
BOOST_AUTO_TEST_CASE( deferred_http_request ) {
244
    std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
270
    std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
(-)websocketpp-zaphoyd/test/connection/SConscript (-1 / +1 lines)
Lines 16-22 objs = env.Object('connection_boost.o', Link Here
16
objs = env.Object('connection_tu2_boost.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS)
16
objs = env.Object('connection_tu2_boost.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_connection_boost', ["connection_boost.o","connection_tu2_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_connection_boost', ["connection_boost.o","connection_tu2_boost.o"], LIBS = BOOST_LIBS)
18
18
19
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
19
if 'WSPP_CPP11_ENABLED' in env_cpp11:
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs]
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs]
21
   objs += env_cpp11.Object('connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11)
21
   objs += env_cpp11.Object('connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('connection_tu2_stl.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('connection_tu2_stl.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/endpoint/endpoint.cpp (-4 / +4 lines)
Lines 53-60 BOOST_AUTO_TEST_CASE( initialize_server_ Link Here
53
53
54
BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) {
54
BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) {
55
    websocketpp::server<websocketpp::config::asio> s;
55
    websocketpp::server<websocketpp::config::asio> s;
56
    boost::asio::io_service ios;
56
    websocketpp::lib::asio::io_context ctx;
57
    s.init_asio(&ios);
57
    s.init_asio(&ctx);
58
}
58
}
59
59
60
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
60
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
Lines 141-148 BOOST_AUTO_TEST_CASE( listen_after_liste Link Here
141
    server1.init_asio();
141
    server1.init_asio();
142
    server2.init_asio();
142
    server2.init_asio();
143
143
144
    boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345);
144
    websocketpp::lib::asio::ip::tcp::endpoint ep1(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 12345);
145
    boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456);
145
    websocketpp::lib::asio::ip::tcp::endpoint ep2(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 23456);
146
146
147
    server1.listen(ep1, ec);
147
    server1.listen(ep1, ec);
148
    BOOST_CHECK(!ec);
148
    BOOST_CHECK(!ec);
(-)websocketpp-zaphoyd/test/endpoint/SConscript (-1 / +1 lines)
Lines 16-22 BOOST_LIBS = boostlibs(['unit_test_frame Link Here
16
objs = env.Object('endpoint_boost.o', ["endpoint.cpp"], LIBS = BOOST_LIBS)
16
objs = env.Object('endpoint_boost.o', ["endpoint.cpp"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_endpoint_boost', ["endpoint_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_endpoint_boost', ["endpoint_boost.o"], LIBS = BOOST_LIBS)
18
18
19
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
19
if 'WSPP_CPP11_ENABLED' in env_cpp11:
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
21
   objs += env_cpp11.Object('endpoint_stl.o', ["endpoint.cpp"], LIBS = BOOST_LIBS_CPP11)
21
   objs += env_cpp11.Object('endpoint_stl.o', ["endpoint.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   prgs += env_cpp11.Program('test_endpoint_stl', ["endpoint_stl.o"], LIBS = BOOST_LIBS_CPP11)
22
   prgs += env_cpp11.Program('test_endpoint_stl', ["endpoint_stl.o"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/extension/SConscript (-1 / +1 lines)
Lines 17-23 objs += env.Object('permessage_deflate_b Link Here
17
prgs = env.Program('test_extension_boost', ["extension_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_extension_boost', ["extension_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_permessage_deflate_boost', ["permessage_deflate_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_permessage_deflate_boost', ["permessage_deflate_boost.o"], LIBS = BOOST_LIBS)
19
19
20
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
20
if 'WSPP_CPP11_ENABLED' in env_cpp11:
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
22
   objs += env_cpp11.Object('extension_stl.o', ["extension.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('extension_stl.o', ["extension.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('permessage_deflate_stl.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('permessage_deflate_stl.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/http/parser.cpp (-256 / +171 lines)
Lines 412-426 BOOST_AUTO_TEST_CASE( blank_consume ) { Link Here
412
412
413
    std::string raw;
413
    std::string raw;
414
414
415
    bool exception = false;
415
    websocketpp::lib::error_code ec;
416
416
    r.consume(raw.c_str(),raw.size(),ec);
417
    try {
417
    
418
        r.consume(raw.c_str(),raw.size());
418
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
419
    } catch (...) {
420
        exception = true;
421
    }
422
423
    BOOST_CHECK( exception == false );
424
    BOOST_CHECK( r.ready() == false );
419
    BOOST_CHECK( r.ready() == false );
425
}
420
}
426
421
Lines 429-443 BOOST_AUTO_TEST_CASE( blank_request ) { Link Here
429
424
430
    std::string raw = "\r\n\r\n";
425
    std::string raw = "\r\n\r\n";
431
426
432
    bool exception = false;
427
    websocketpp::lib::error_code ec;
428
    r.consume(raw.c_str(),raw.size(),ec);
433
429
434
    try {
430
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(websocketpp::http::error::incomplete_request));
435
        r.consume(raw.c_str(),raw.size());
436
    } catch (...) {
437
        exception = true;
438
    }
439
440
    BOOST_CHECK( exception == true );
441
    BOOST_CHECK( r.ready() == false );
431
    BOOST_CHECK( r.ready() == false );
442
}
432
}
443
433
Lines 446-460 BOOST_AUTO_TEST_CASE( bad_request_no_hos Link Here
446
436
447
    std::string raw = "GET / HTTP/1.1\r\n\r\n";
437
    std::string raw = "GET / HTTP/1.1\r\n\r\n";
448
438
449
    bool exception = false;
439
    websocketpp::lib::error_code ec;
440
    r.consume(raw.c_str(),raw.size(),ec);
450
441
451
    try {
442
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(websocketpp::http::error::incomplete_request));
452
        r.consume(raw.c_str(),raw.size());
453
    } catch (...) {
454
        exception = true;
455
    }
456
457
    BOOST_CHECK( exception == true );
458
    BOOST_CHECK( r.ready() == false );
443
    BOOST_CHECK( r.ready() == false );
459
}
444
}
460
445
Lines 463-479 BOOST_AUTO_TEST_CASE( basic_request ) { Link Here
463
448
464
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
449
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
465
450
466
    bool exception = false;
467
    size_t pos = 0;
451
    size_t pos = 0;
468
452
469
    try {
453
    websocketpp::lib::error_code ec;
470
        pos = r.consume(raw.c_str(),raw.size());
454
    pos += r.consume(raw.c_str(),raw.size(),ec);
471
    } catch (std::exception &e) {
472
        exception = true;
473
        std::cout << e.what() << std::endl;
474
    }
475
455
476
    BOOST_CHECK( exception == false );
456
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
477
    BOOST_CHECK( pos == 41 );
457
    BOOST_CHECK( pos == 41 );
478
    BOOST_CHECK( r.ready() == true );
458
    BOOST_CHECK( r.ready() == true );
479
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
459
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
Lines 487-503 BOOST_AUTO_TEST_CASE( basic_request_with Link Here
487
467
488
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 5\r\n\r\nabcdef";
468
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 5\r\n\r\nabcdef";
489
469
490
    bool exception = false;
491
    size_t pos = 0;
470
    size_t pos = 0;
492
471
493
    try {
472
    websocketpp::lib::error_code ec;
494
        pos = r.consume(raw.c_str(),raw.size());
473
    pos += r.consume(raw.c_str(),raw.size(),ec);
495
    } catch (std::exception &e) {
496
        exception = true;
497
        std::cout << e.what() << std::endl;
498
    }
499
474
500
    BOOST_CHECK( exception == false );
475
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
501
    BOOST_CHECK_EQUAL( pos, 65 );
476
    BOOST_CHECK_EQUAL( pos, 65 );
502
    BOOST_CHECK( r.ready() == true );
477
    BOOST_CHECK( r.ready() == true );
503
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
478
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 526-543 BOOST_AUTO_TEST_CASE( basic_request_with Link Here
526
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabc";
501
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabc";
527
    std::string raw2 = "def";
502
    std::string raw2 = "def";
528
503
529
    bool exception = false;
530
    size_t pos = 0;
504
    size_t pos = 0;
531
505
532
    try {
506
    websocketpp::lib::error_code ec;
533
        pos += r.consume(raw.c_str(),raw.size());
507
    pos += r.consume(raw.c_str(),raw.size(),ec);
534
        pos += r.consume(raw2.c_str(),raw2.size());
508
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
535
    } catch (std::exception &e) {
509
536
        exception = true;
510
    pos += r.consume(raw2.c_str(),raw2.size(),ec);
537
        std::cout << e.what() << std::endl;
511
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
538
    }
539
512
540
    BOOST_CHECK( exception == false );
541
    BOOST_CHECK_EQUAL( pos, 66 );
513
    BOOST_CHECK_EQUAL( pos, 66 );
542
    BOOST_CHECK( r.ready() == true );
514
    BOOST_CHECK( r.ready() == true );
543
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
515
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 555-570 BOOST_AUTO_TEST_CASE( trailing_body_char Link Here
555
527
556
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\na";
528
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\na";
557
529
558
    bool exception = false;
559
    size_t pos = 0;
530
    size_t pos = 0;
560
531
561
    try {
532
    websocketpp::lib::error_code ec;
562
        pos = r.consume(raw.c_str(),raw.size());
533
    pos += r.consume(raw.c_str(),raw.size(),ec);
563
    } catch (...) {
564
        exception = true;
565
    }
566
534
567
    BOOST_CHECK( exception == false );
535
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
568
    BOOST_CHECK( pos == 41 );
536
    BOOST_CHECK( pos == 41 );
569
    BOOST_CHECK( r.ready() == true );
537
    BOOST_CHECK( r.ready() == true );
570
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
538
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
Lines 579-594 BOOST_AUTO_TEST_CASE( trailing_body_char Link Here
579
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
547
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
580
    raw.append(websocketpp::http::max_header_size,'*');
548
    raw.append(websocketpp::http::max_header_size,'*');
581
549
582
    bool exception = false;
583
    size_t pos = 0;
550
    size_t pos = 0;
584
551
585
    try {
552
    websocketpp::lib::error_code ec;
586
        pos = r.consume(raw.c_str(),raw.size());
553
    pos += r.consume(raw.c_str(),raw.size(),ec);
587
    } catch (...) {
588
        exception = true;
589
    }
590
554
591
    BOOST_CHECK( exception == false );
555
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
592
    BOOST_CHECK( pos == 41 );
556
    BOOST_CHECK( pos == 41 );
593
    BOOST_CHECK( r.ready() == true );
557
    BOOST_CHECK( r.ready() == true );
594
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
558
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
Lines 603-620 BOOST_AUTO_TEST_CASE( basic_split1 ) { Link Here
603
    std::string raw = "GET / HTTP/1.1\r\n";
567
    std::string raw = "GET / HTTP/1.1\r\n";
604
    std::string raw2 = "Host: www.example.com\r\n\r\na";
568
    std::string raw2 = "Host: www.example.com\r\n\r\na";
605
569
606
    bool exception = false;
607
    size_t pos = 0;
570
    size_t pos = 0;
608
571
609
    try {
572
    websocketpp::lib::error_code ec;
610
        pos += r.consume(raw.c_str(),raw.size());
573
    pos += r.consume(raw.c_str(),raw.size(),ec);
611
        pos += r.consume(raw2.c_str(),raw2.size());
574
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
612
    } catch (std::exception &e) {
575
    BOOST_CHECK( pos == raw.size() );
613
        exception = true;
576
614
        std::cout << e.what() << std::endl;
577
    pos += r.consume(raw2.c_str(),raw2.size(),ec);
615
    }
578
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
616
579
617
    BOOST_CHECK( exception == false );
618
    BOOST_CHECK( pos == 41 );
580
    BOOST_CHECK( pos == 41 );
619
    BOOST_CHECK( r.ready() == true );
581
    BOOST_CHECK( r.ready() == true );
620
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
582
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
Lines 629-646 BOOST_AUTO_TEST_CASE( basic_split2 ) { Link Here
629
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r";
591
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r";
630
    std::string raw2 = "\n\r\na";
592
    std::string raw2 = "\n\r\na";
631
593
632
    bool exception = false;
633
    size_t pos = 0;
594
    size_t pos = 0;
634
595
635
    try {
596
    websocketpp::lib::error_code ec;
636
        pos += r.consume(raw.c_str(),raw.size());
597
    pos += r.consume(raw.c_str(),raw.size(),ec);
637
        pos += r.consume(raw2.c_str(),raw2.size());
598
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
638
    } catch (std::exception &e) {
599
    BOOST_CHECK( pos == raw.size() );
639
        exception = true;
600
640
        std::cout << e.what() << std::endl;
601
    pos += r.consume(raw2.c_str(),raw2.size(),ec);
641
    }
602
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
642
603
643
    BOOST_CHECK( exception == false );
644
    BOOST_CHECK( pos == 41 );
604
    BOOST_CHECK( pos == 41 );
645
    BOOST_CHECK( r.ready() == true );
605
    BOOST_CHECK( r.ready() == true );
646
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
606
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
Lines 655-672 BOOST_AUTO_TEST_CASE( max_header_len ) { Link Here
655
    std::string raw(websocketpp::http::max_header_size-1,'*');
615
    std::string raw(websocketpp::http::max_header_size-1,'*');
656
    raw += "\r\n";
616
    raw += "\r\n";
657
617
658
    bool exception = false;
618
    websocketpp::lib::error_code ec;
659
    size_t pos = 0;
619
    r.consume(raw.c_str(),raw.size(),ec);
660
620
661
    try {
621
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
662
        pos += r.consume(raw.c_str(),raw.size());
622
        websocketpp::http::error::request_header_fields_too_large));
663
    } catch (const websocketpp::http::exception& e) {
664
        if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
665
            exception = true;
666
        }
667
    }
668
669
    BOOST_CHECK( exception == true );
670
}
623
}
671
624
672
BOOST_AUTO_TEST_CASE( max_header_len_split ) {
625
BOOST_AUTO_TEST_CASE( max_header_len_split ) {
Lines 675-693 BOOST_AUTO_TEST_CASE( max_header_len_spl Link Here
675
    std::string raw(websocketpp::http::max_header_size-1,'*');
628
    std::string raw(websocketpp::http::max_header_size-1,'*');
676
    std::string raw2(2,'*');
629
    std::string raw2(2,'*');
677
630
678
    bool exception = false;
679
    size_t pos = 0;
631
    size_t pos = 0;
632
    websocketpp::lib::error_code ec;
680
633
681
    try {
634
    pos += r.consume(raw.c_str(),raw.size(),ec);
682
        pos += r.consume(raw.c_str(),raw.size());
635
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
683
        pos += r.consume(raw2.c_str(),raw2.size());
636
    BOOST_CHECK_EQUAL(pos, raw.size());
684
    } catch (const websocketpp::http::exception& e) {
637
685
        if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
638
    r.consume(raw2.c_str(),raw2.size(),ec);
686
            exception = true;
639
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
687
        }
640
        websocketpp::http::error::request_header_fields_too_large));
688
    }
689
690
    BOOST_CHECK( exception == true );
691
}
641
}
692
642
693
BOOST_AUTO_TEST_CASE( max_body_len ) {
643
BOOST_AUTO_TEST_CASE( max_body_len ) {
Lines 697-714 BOOST_AUTO_TEST_CASE( max_body_len ) { Link Here
697
647
698
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabcdef";
648
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabcdef";
699
649
700
    bool exception = false;
650
    websocketpp::lib::error_code ec;
701
    size_t pos = 0;
651
    r.consume(raw.c_str(),raw.size(),ec);
702
703
    try {
704
        pos += r.consume(raw.c_str(),raw.size());
705
    } catch (websocketpp::http::exception const & e) {
706
        exception = true;
707
        BOOST_CHECK_EQUAL(e.m_error_code,websocketpp::http::status_code::request_entity_too_large);
708
    }
709
652
653
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
654
        websocketpp::http::error::body_too_large));
710
    BOOST_CHECK_EQUAL(r.get_max_body_size(),5);
655
    BOOST_CHECK_EQUAL(r.get_max_body_size(),5);
711
    BOOST_CHECK( exception == true );
712
}
656
}
713
657
714
BOOST_AUTO_TEST_CASE( firefox_full_request ) {
658
BOOST_AUTO_TEST_CASE( firefox_full_request ) {
Lines 716-748 BOOST_AUTO_TEST_CASE( firefox_full_reque Link Here
716
660
717
    std::string raw = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
661
    std::string raw = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
718
662
719
    bool exception = false;
720
    size_t pos = 0;
663
    size_t pos = 0;
721
664
722
    try {
665
    websocketpp::lib::error_code ec;
723
        pos += r.consume(raw.c_str(),raw.size());
666
724
    } catch (...) {
667
    pos += r.consume(raw.c_str(),raw.size(),ec);
725
        exception = true;
668
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
726
    }
727
669
728
    BOOST_CHECK( exception == false );
670
    BOOST_CHECK_EQUAL( pos, 482 );
729
    BOOST_CHECK( pos == 482 );
730
    BOOST_CHECK( r.ready() == true );
671
    BOOST_CHECK( r.ready() == true );
731
    BOOST_CHECK( r.get_version() == "HTTP/1.1" );
672
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
732
    BOOST_CHECK( r.get_method() == "GET" );
673
    BOOST_CHECK_EQUAL( r.get_method(), "GET" );
733
    BOOST_CHECK( r.get_uri() == "/" );
674
    BOOST_CHECK_EQUAL( r.get_uri(), "/" );
734
    BOOST_CHECK( r.get_header("Host") == "localhost:5000" );
675
    BOOST_CHECK_EQUAL( r.get_header("Host"), "localhost:5000" );
735
    BOOST_CHECK( r.get_header("User-Agent") == "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0" );
676
    BOOST_CHECK_EQUAL( r.get_header("User-Agent"), "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0" );
736
    BOOST_CHECK( r.get_header("Accept") == "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" );
677
    BOOST_CHECK_EQUAL( r.get_header("Accept"), "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" );
737
    BOOST_CHECK( r.get_header("Accept-Language") == "en-us,en;q=0.5" );
678
    BOOST_CHECK_EQUAL( r.get_header("Accept-Language"), "en-us,en;q=0.5" );
738
    BOOST_CHECK( r.get_header("Accept-Encoding") == "gzip, deflate" );
679
    BOOST_CHECK_EQUAL( r.get_header("Accept-Encoding"), "gzip, deflate" );
739
    BOOST_CHECK( r.get_header("Connection") == "keep-alive, Upgrade" );
680
    BOOST_CHECK_EQUAL( r.get_header("Connection"), "keep-alive, Upgrade" );
740
    BOOST_CHECK( r.get_header("Sec-WebSocket-Version") == "8" );
681
    BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Version"), "8" );
741
    BOOST_CHECK( r.get_header("Sec-WebSocket-Origin") == "http://zaphoyd.com" );
682
    BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Origin"),"http://zaphoyd.com" );
742
    BOOST_CHECK( r.get_header("Sec-WebSocket-Key") == "pFik//FxwFk0riN4ZiPFjQ==" );
683
    BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Key"), "pFik//FxwFk0riN4ZiPFjQ==" );
743
    BOOST_CHECK( r.get_header("Pragma") == "no-cache" );
684
    BOOST_CHECK_EQUAL( r.get_header("Pragma"), "no-cache" );
744
    BOOST_CHECK( r.get_header("Cache-Control") == "no-cache" );
685
    BOOST_CHECK_EQUAL( r.get_header("Cache-Control"), "no-cache" );
745
    BOOST_CHECK( r.get_header("Upgrade") == "websocket" );
686
    BOOST_CHECK_EQUAL( r.get_header("Upgrade"),"websocket" );
746
}
687
}
747
688
748
BOOST_AUTO_TEST_CASE( bad_method ) {
689
BOOST_AUTO_TEST_CASE( bad_method ) {
Lines 750-764 BOOST_AUTO_TEST_CASE( bad_method ) { Link Here
750
691
751
    std::string raw = "GE]T / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
692
    std::string raw = "GE]T / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
752
693
753
    bool exception = false;
694
    websocketpp::lib::error_code ec;
754
695
    r.consume(raw.c_str(),raw.size(),ec);
755
    try {
756
        r.consume(raw.c_str(),raw.size());
757
    } catch (...) {
758
        exception = true;
759
    }
760
696
761
    BOOST_CHECK( exception == true );
697
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
698
        websocketpp::http::error::invalid_format));
762
}
699
}
763
700
764
BOOST_AUTO_TEST_CASE( bad_header_name ) {
701
BOOST_AUTO_TEST_CASE( bad_header_name ) {
Lines 766-780 BOOST_AUTO_TEST_CASE( bad_header_name ) Link Here
766
703
767
    std::string raw = "GET / HTTP/1.1\r\nHo]st: www.example.com\r\n\r\n";
704
    std::string raw = "GET / HTTP/1.1\r\nHo]st: www.example.com\r\n\r\n";
768
705
769
    bool exception = false;
706
    websocketpp::lib::error_code ec;
707
    r.consume(raw.c_str(),raw.size(),ec);
770
708
771
    try {
709
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
772
        r.consume(raw.c_str(),raw.size());
710
        websocketpp::http::error::invalid_header_name));
773
    } catch (...) {
774
        exception = true;
775
    }
776
777
    BOOST_CHECK( exception == true );
778
}
711
}
779
712
780
BOOST_AUTO_TEST_CASE( old_http_version ) {
713
BOOST_AUTO_TEST_CASE( old_http_version ) {
Lines 782-797 BOOST_AUTO_TEST_CASE( old_http_version ) Link Here
782
715
783
    std::string raw = "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n";
716
    std::string raw = "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n";
784
717
785
    bool exception = false;
786
    size_t pos = 0;
718
    size_t pos = 0;
719
    websocketpp::lib::error_code ec;
787
720
788
    try {
721
    pos += r.consume(raw.c_str(),raw.size(),ec);
789
        pos = r.consume(raw.c_str(),raw.size());
722
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
790
    } catch (...) {
791
        exception = true;
792
    }
793
723
794
    BOOST_CHECK( exception == false );
795
    BOOST_CHECK_EQUAL( pos, 41 );
724
    BOOST_CHECK_EQUAL( pos, 41 );
796
    BOOST_CHECK( r.ready() == true );
725
    BOOST_CHECK( r.ready() == true );
797
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.0" );
726
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.0" );
Lines 805-820 BOOST_AUTO_TEST_CASE( new_http_version1 Link Here
805
734
806
    std::string raw = "GET / HTTP/1.12\r\nHost: www.example.com\r\n\r\n";
735
    std::string raw = "GET / HTTP/1.12\r\nHost: www.example.com\r\n\r\n";
807
736
808
    bool exception = false;
809
    size_t pos = 0;
737
    size_t pos = 0;
738
    websocketpp::lib::error_code ec;
810
739
811
    try {
740
    pos += r.consume(raw.c_str(),raw.size(),ec);
812
        pos = r.consume(raw.c_str(),raw.size());
741
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
813
    } catch (...) {
814
        exception = true;
815
    }
816
742
817
    BOOST_CHECK( exception == false );
818
    BOOST_CHECK_EQUAL( pos, 42 );
743
    BOOST_CHECK_EQUAL( pos, 42 );
819
    BOOST_CHECK( r.ready() == true );
744
    BOOST_CHECK( r.ready() == true );
820
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.12" );
745
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.12" );
Lines 828-843 BOOST_AUTO_TEST_CASE( new_http_version2 Link Here
828
753
829
    std::string raw = "GET / HTTP/12.12\r\nHost: www.example.com\r\n\r\n";
754
    std::string raw = "GET / HTTP/12.12\r\nHost: www.example.com\r\n\r\n";
830
755
831
    bool exception = false;
832
    size_t pos = 0;
756
    size_t pos = 0;
757
    websocketpp::lib::error_code ec;
833
758
834
    try {
759
    pos += r.consume(raw.c_str(),raw.size(),ec);
835
        pos = r.consume(raw.c_str(),raw.size());
760
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
836
    } catch (...) {
837
        exception = true;
838
    }
839
761
840
    BOOST_CHECK( exception == false );
841
    BOOST_CHECK_EQUAL( pos, 43 );
762
    BOOST_CHECK_EQUAL( pos, 43 );
842
    BOOST_CHECK( r.ready() == true );
763
    BOOST_CHECK( r.ready() == true );
843
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/12.12" );
764
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/12.12" );
Lines 870-885 BOOST_AUTO_TEST_CASE( header_whitespace1 Link Here
870
791
871
    std::string raw = "GET / HTTP/1.1\r\nHost:  www.example.com \r\n\r\n";
792
    std::string raw = "GET / HTTP/1.1\r\nHost:  www.example.com \r\n\r\n";
872
793
873
    bool exception = false;
874
    size_t pos = 0;
794
    size_t pos = 0;
795
    websocketpp::lib::error_code ec;
875
796
876
    try {
797
    pos += r.consume(raw.c_str(),raw.size(),ec);
877
        pos = r.consume(raw.c_str(),raw.size());
798
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
878
    } catch (...) {
879
        exception = true;
880
    }
881
799
882
    BOOST_CHECK( exception == false );
883
    BOOST_CHECK_EQUAL( pos, 43 );
800
    BOOST_CHECK_EQUAL( pos, 43 );
884
    BOOST_CHECK( r.ready() == true );
801
    BOOST_CHECK( r.ready() == true );
885
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
802
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 893-908 BOOST_AUTO_TEST_CASE( header_whitespace2 Link Here
893
810
894
    std::string raw = "GET / HTTP/1.1\r\nHost:www.example.com\r\n\r\n";
811
    std::string raw = "GET / HTTP/1.1\r\nHost:www.example.com\r\n\r\n";
895
812
896
    bool exception = false;
897
    size_t pos = 0;
813
    size_t pos = 0;
814
    websocketpp::lib::error_code ec;
898
815
899
    try {
816
    pos += r.consume(raw.c_str(),raw.size(),ec);
900
        pos = r.consume(raw.c_str(),raw.size());
817
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
901
    } catch (...) {
902
        exception = true;
903
    }
904
818
905
    BOOST_CHECK( exception == false );
906
    BOOST_CHECK_EQUAL( pos, 40 );
819
    BOOST_CHECK_EQUAL( pos, 40 );
907
    BOOST_CHECK( r.ready() == true );
820
    BOOST_CHECK( r.ready() == true );
908
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
821
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 916-931 BOOST_AUTO_TEST_CASE( header_aggregation Link Here
916
829
917
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nFoo: bar\r\nFoo: bat\r\n\r\n";
830
    std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nFoo: bar\r\nFoo: bat\r\n\r\n";
918
831
919
    bool exception = false;
920
    size_t pos = 0;
832
    size_t pos = 0;
833
    websocketpp::lib::error_code ec;
921
834
922
    try {
835
    pos += r.consume(raw.c_str(),raw.size(),ec);
923
        pos = r.consume(raw.c_str(),raw.size());
836
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
924
    } catch (...) {
925
        exception = true;
926
    }
927
837
928
    BOOST_CHECK( exception == false );
929
    BOOST_CHECK_EQUAL( pos, 61 );
838
    BOOST_CHECK_EQUAL( pos, 61 );
930
    BOOST_CHECK( r.ready() == true );
839
    BOOST_CHECK( r.ready() == true );
931
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
840
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 939-955 BOOST_AUTO_TEST_CASE( wikipedia_example_ Link Here
939
848
940
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
849
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
941
850
942
    bool exception = false;
943
    size_t pos = 0;
851
    size_t pos = 0;
852
    websocketpp::lib::error_code ec;
944
853
945
    try {
854
    pos += r.consume(raw.c_str(),raw.size(),ec);
946
        pos += r.consume(raw.c_str(),raw.size());
855
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
947
    } catch (std::exception &e) {
948
        exception = true;
949
        std::cout << e.what() << std::endl;
950
    }
951
856
952
    BOOST_CHECK( exception == false );
953
    BOOST_CHECK_EQUAL( pos, 159 );
857
    BOOST_CHECK_EQUAL( pos, 159 );
954
    BOOST_CHECK( r.headers_ready() == true );
858
    BOOST_CHECK( r.headers_ready() == true );
955
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
859
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 967-983 BOOST_AUTO_TEST_CASE( wikipedia_example_ Link Here
967
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
871
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
968
    raw += "a";
872
    raw += "a";
969
873
970
    bool exception = false;
971
    size_t pos = 0;
874
    size_t pos = 0;
875
    websocketpp::lib::error_code ec;
972
876
973
    try {
877
    pos += r.consume(raw.c_str(),raw.size(),ec);
974
        pos += r.consume(raw.c_str(),raw.size());
878
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
975
    } catch (std::exception &e) {
976
        exception = true;
977
        std::cout << e.what() << std::endl;
978
    }
979
879
980
    BOOST_CHECK( exception == false );
981
    BOOST_CHECK_EQUAL( pos, 159 );
880
    BOOST_CHECK_EQUAL( pos, 159 );
982
    BOOST_CHECK( r.headers_ready() == true );
881
    BOOST_CHECK( r.headers_ready() == true );
983
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
882
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 995-1011 BOOST_AUTO_TEST_CASE( wikipedia_example_ Link Here
995
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
894
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
996
    raw.append(websocketpp::http::max_header_size,'*');
895
    raw.append(websocketpp::http::max_header_size,'*');
997
896
998
    bool exception = false;
999
    size_t pos = 0;
897
    size_t pos = 0;
898
    websocketpp::lib::error_code ec;
1000
899
1001
    try {
900
    pos += r.consume(raw.c_str(),raw.size(),ec);
1002
        pos += r.consume(raw.c_str(),raw.size());
901
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1003
    } catch (std::exception &e) {
1004
        exception = true;
1005
        std::cout << e.what() << std::endl;
1006
    }
1007
902
1008
    BOOST_CHECK( exception == false );
1009
    BOOST_CHECK_EQUAL( pos, 159 );
903
    BOOST_CHECK_EQUAL( pos, 159 );
1010
    BOOST_CHECK( r.headers_ready() == true );
904
    BOOST_CHECK( r.headers_ready() == true );
1011
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
905
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 1022-1038 BOOST_AUTO_TEST_CASE( response_with_non_ Link Here
1022
916
1023
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
917
    std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
1024
918
1025
    bool exception = false;
1026
    size_t pos = 0;
919
    size_t pos = 0;
920
    websocketpp::lib::error_code ec;
1027
921
1028
    try {
922
    pos += r.consume(raw.c_str(),raw.size(),ec);
1029
        pos += r.consume(raw.c_str(),raw.size());
923
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1030
    } catch (std::exception &e) {
1031
        exception = true;
1032
        std::cout << e.what() << std::endl;
1033
    }
1034
924
1035
    BOOST_CHECK( exception == false );
1036
    BOOST_CHECK_EQUAL( pos, 158 );
925
    BOOST_CHECK_EQUAL( pos, 158 );
1037
    BOOST_CHECK( r.headers_ready() );
926
    BOOST_CHECK( r.headers_ready() );
1038
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
927
    BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
Lines 1049-1065 BOOST_AUTO_TEST_CASE( plain_http_respons Link Here
1049
938
1050
    std::string raw = "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
939
    std::string raw = "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
1051
940
1052
    bool exception = false;
1053
    size_t pos = 0;
941
    size_t pos = 0;
942
    websocketpp::lib::error_code ec;
1054
943
1055
    try {
944
    pos += r.consume(raw.c_str(),raw.size(),ec);
1056
        pos += r.consume(raw.c_str(),raw.size());
945
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1057
    } catch (std::exception &e) {
1058
        exception = true;
1059
        std::cout << e.what() << std::endl;
1060
    }
1061
946
1062
    BOOST_CHECK( exception == false );
1063
    BOOST_CHECK_EQUAL( pos, 405 );
947
    BOOST_CHECK_EQUAL( pos, 405 );
1064
    BOOST_CHECK( r.headers_ready() == true );
948
    BOOST_CHECK( r.headers_ready() == true );
1065
    BOOST_CHECK( r.ready() == true );
949
    BOOST_CHECK( r.ready() == true );
Lines 1084-1100 BOOST_AUTO_TEST_CASE( parse_istream ) { Link Here
1084
968
1085
    s << "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
969
    s << "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
1086
970
1087
    bool exception = false;
1088
    size_t pos = 0;
971
    size_t pos = 0;
972
    websocketpp::lib::error_code ec;
1089
973
1090
    try {
974
    pos += r.consume(s,ec);
1091
        pos += r.consume(s);
975
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1092
    } catch (std::exception &e) {
1093
        exception = true;
1094
        std::cout << e.what() << std::endl;
1095
    }
1096
976
1097
    BOOST_CHECK_EQUAL( exception, false );
1098
    BOOST_CHECK_EQUAL( pos, 405 );
977
    BOOST_CHECK_EQUAL( pos, 405 );
1099
    BOOST_CHECK_EQUAL( r.headers_ready(), true );
978
    BOOST_CHECK_EQUAL( r.headers_ready(), true );
1100
    BOOST_CHECK_EQUAL( r.ready(), true );
979
    BOOST_CHECK_EQUAL( r.ready(), true );
Lines 1104-1126 BOOST_AUTO_TEST_CASE( write_request_basi Link Here
1104
    websocketpp::http::parser::request r;
983
    websocketpp::http::parser::request r;
1105
984
1106
    std::string raw = "GET / HTTP/1.1\r\n\r\n";
985
    std::string raw = "GET / HTTP/1.1\r\n\r\n";
986
    websocketpp::lib::error_code ec;
987
988
    ec = r.set_version("HTTP/1.1");
989
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
990
991
    ec = r.set_method("GET");
992
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1107
993
1108
    r.set_version("HTTP/1.1");
994
    ec = r.set_uri("/");
1109
    r.set_method("GET");
995
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1110
    r.set_uri("/");
1111
996
1112
    BOOST_CHECK_EQUAL( r.raw(), raw );
997
    BOOST_CHECK_EQUAL( r.raw(), raw );
1113
}
998
}
1114
999
1000
BOOST_AUTO_TEST_CASE( write_request_bad_method ) {
1001
    websocketpp::http::parser::request r;
1002
1003
    websocketpp::lib::error_code ec;
1004
1005
    ec = r.set_method("foo bar");
1006
    BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(
1007
        websocketpp::http::error::invalid_format));
1008
}
1009
1115
BOOST_AUTO_TEST_CASE( write_request_with_header ) {
1010
BOOST_AUTO_TEST_CASE( write_request_with_header ) {
1116
    websocketpp::http::parser::request r;
1011
    websocketpp::http::parser::request r;
1117
1012
1118
    std::string raw = "GET / HTTP/1.1\r\nHost: http://example.com\r\n\r\n";
1013
    std::string raw = "GET / HTTP/1.1\r\nHost: http://example.com\r\n\r\n";
1014
    websocketpp::lib::error_code ec;
1015
1016
    ec = r.set_version("HTTP/1.1");
1017
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1018
1019
    ec = r.set_method("GET");
1020
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1021
1022
    ec = r.set_uri("/");
1023
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1119
1024
1120
    r.set_version("HTTP/1.1");
1025
    ec = r.replace_header("Host","http://example.com");
1121
    r.set_method("GET");
1026
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1122
    r.set_uri("/");
1123
    r.replace_header("Host","http://example.com");
1124
1027
1125
    BOOST_CHECK_EQUAL( r.raw(), raw );
1028
    BOOST_CHECK_EQUAL( r.raw(), raw );
1126
}
1029
}
Lines 1129-1141 BOOST_AUTO_TEST_CASE( write_request_with Link Here
1129
    websocketpp::http::parser::request r;
1032
    websocketpp::http::parser::request r;
1130
1033
1131
    std::string raw = "POST / HTTP/1.1\r\nContent-Length: 48\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: http://example.com\r\n\r\nlicenseID=string&content=string&paramsXML=string";
1034
    std::string raw = "POST / HTTP/1.1\r\nContent-Length: 48\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: http://example.com\r\n\r\nlicenseID=string&content=string&paramsXML=string";
1035
    websocketpp::lib::error_code ec;
1036
1037
    ec = r.set_version("HTTP/1.1");
1038
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1039
1040
    ec = r.set_method("POST");
1041
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1042
1043
    ec = r.set_uri("/");
1044
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1045
1046
    ec = r.replace_header("Host","http://example.com");
1047
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1048
1049
    ec = r.replace_header("Content-Type","application/x-www-form-urlencoded");
1050
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1132
1051
1133
    r.set_version("HTTP/1.1");
1052
    ec = r.set_body("licenseID=string&content=string&paramsXML=string");
1134
    r.set_method("POST");
1053
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
1135
    r.set_uri("/");
1136
    r.replace_header("Host","http://example.com");
1137
    r.replace_header("Content-Type","application/x-www-form-urlencoded");
1138
    r.set_body("licenseID=string&content=string&paramsXML=string");
1139
1054
1140
    BOOST_CHECK_EQUAL( r.raw(), raw );
1055
    BOOST_CHECK_EQUAL( r.raw(), raw );
1141
}
1056
}
(-)websocketpp-zaphoyd/test/http/parser_perf.cpp (-2 / +2 lines)
Lines 31-41 Link Here
31
31
32
class scoped_timer {
32
class scoped_timer {
33
public:
33
public:
34
    scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) {
34
    scoped_timer(std::string i) : m_id(i),m_start(timer_ptr::element_type::clock_type::now()) {
35
        std::cout << "Clock " << i << ": ";
35
        std::cout << "Clock " << i << ": ";
36
    }
36
    }
37
    ~scoped_timer() {
37
    ~scoped_timer() {
38
        std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start;
38
        std::chrono::nanoseconds time_taken = timer_ptr::element_type::clock_type::now()-m_start;
39
39
40
        //nanoseconds_per_test
40
        //nanoseconds_per_test
41
41
(-)websocketpp-zaphoyd/test/http/SConscript (-1 / +1 lines)
Lines 15-21 BOOST_LIBS = boostlibs(['unit_test_frame Link Here
15
objs = env.Object('parser_boost.o', ["parser.cpp"], LIBS = BOOST_LIBS)
15
objs = env.Object('parser_boost.o', ["parser.cpp"], LIBS = BOOST_LIBS)
16
prgs = env.Program('test_http_boost', ["parser_boost.o"], LIBS = BOOST_LIBS)
16
prgs = env.Program('test_http_boost', ["parser_boost.o"], LIBS = BOOST_LIBS)
17
17
18
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
18
if 'WSPP_CPP11_ENABLED' in env_cpp11:
19
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
19
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
20
   objs += env_cpp11.Object('parser_stl.o', ["parser.cpp"], LIBS = BOOST_LIBS_CPP11)
20
   objs += env_cpp11.Object('parser_stl.o', ["parser.cpp"], LIBS = BOOST_LIBS_CPP11)
21
   prgs += env_cpp11.Program('test_http_stl', ["parser_stl.o"], LIBS = BOOST_LIBS_CPP11)
21
   prgs += env_cpp11.Program('test_http_stl', ["parser_stl.o"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/logger/SConscript (-1 / +1 lines)
Lines 15-21 BOOST_LIBS = boostlibs(['unit_test_frame Link Here
15
objs = env.Object('logger_basic_boost.o', ["basic.cpp"], LIBS = BOOST_LIBS)
15
objs = env.Object('logger_basic_boost.o', ["basic.cpp"], LIBS = BOOST_LIBS)
16
prgs = env.Program('logger_basic_boost', ["logger_basic_boost.o"], LIBS = BOOST_LIBS)
16
prgs = env.Program('logger_basic_boost', ["logger_basic_boost.o"], LIBS = BOOST_LIBS)
17
17
18
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
18
if 'WSPP_CPP11_ENABLED' in env_cpp11:
19
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs]
19
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs]
20
   objs += env_cpp11.Object('logger_basic_stl.o', ["basic.cpp"], LIBS = BOOST_LIBS_CPP11)
20
   objs += env_cpp11.Object('logger_basic_stl.o', ["basic.cpp"], LIBS = BOOST_LIBS_CPP11)
21
   prgs += env_cpp11.Program('logger_basic_stl', ["logger_basic_stl.o"], LIBS = BOOST_LIBS_CPP11)
21
   prgs += env_cpp11.Program('logger_basic_stl', ["logger_basic_stl.o"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/message_buffer/SConscript (-1 / +1 lines)
Lines 17-23 objs += env.Object('alloc_boost.o', ["al Link Here
17
prgs = env.Program('test_message_boost', ["message_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_message_boost', ["message_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_alloc_boost', ["alloc_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_alloc_boost', ["alloc_boost.o"], LIBS = BOOST_LIBS)
19
19
20
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
20
if 'WSPP_CPP11_ENABLED' in env_cpp11:
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
22
   objs += env_cpp11.Object('message_stl.o', ["message.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('message_stl.o', ["message.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('alloc_stl.o', ["alloc.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('alloc_stl.o', ["alloc.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/processors/hybi00.cpp (-6 / +12 lines)
Lines 68-74 BOOST_AUTO_TEST_CASE( exact_match ) { Link Here
68
68
69
    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";
69
    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";
70
70
71
    env.req.consume(handshake.c_str(),handshake.size());
71
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
72
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
72
    env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
73
    env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6");
73
74
74
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
75
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
Lines 100-106 BOOST_AUTO_TEST_CASE( non_get_method ) { Link Here
100
101
101
    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";
102
    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";
102
103
103
    env.req.consume(handshake.c_str(),handshake.size());
104
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
105
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
104
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
106
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
105
107
106
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
108
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
Lines 113-119 BOOST_AUTO_TEST_CASE( old_http_version ) Link Here
113
115
114
    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";
116
    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";
115
117
116
    env.req.consume(handshake.c_str(),handshake.size());
118
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
119
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
117
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
120
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
118
121
119
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
122
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
Lines 126-132 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
126
129
127
    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";
130
    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";
128
131
129
    env.req.consume(handshake.c_str(),handshake.size());
132
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
133
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
130
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
134
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
131
135
132
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
136
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
Lines 139-145 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
139
143
140
    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";
144
    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";
141
145
142
    env.req.consume(handshake.c_str(),handshake.size());
146
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
147
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
143
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
148
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
144
149
145
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
150
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
Lines 153-159 BOOST_AUTO_TEST_CASE( bad_host ) { Link Here
153
158
154
    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";
159
    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";
155
160
156
    env.req.consume(handshake.c_str(),handshake.size());
161
    env.req.consume(handshake.c_str(),handshake.size(),env.ec);
162
    BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code());
157
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
163
    env.req.replace_header("Sec-WebSocket-Key3","janelle!");
158
164
159
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
165
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
(-)websocketpp-zaphoyd/test/processors/hybi07.cpp (-6 / +12 lines)
Lines 76-82 BOOST_AUTO_TEST_CASE( exact_match ) { Link Here
76
76
77
    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";
77
    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";
78
78
79
    r.consume(handshake.c_str(),handshake.size());
79
    r.consume(handshake.c_str(),handshake.size(),ec);
80
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
80
81
81
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
82
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
82
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
83
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 110-116 BOOST_AUTO_TEST_CASE( non_get_method ) { Link Here
110
111
111
    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";
112
    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";
112
113
113
    r.consume(handshake.c_str(),handshake.size());
114
    r.consume(handshake.c_str(),handshake.size(),ec);
115
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
114
116
115
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
117
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
116
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
118
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 128-134 BOOST_AUTO_TEST_CASE( old_http_version ) Link Here
128
130
129
    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";
131
    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";
130
132
131
    r.consume(handshake.c_str(),handshake.size());
133
    r.consume(handshake.c_str(),handshake.size(),ec);
134
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
132
135
133
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
136
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
134
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
137
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 146-152 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
146
149
147
    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";
150
    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";
148
151
149
    r.consume(handshake.c_str(),handshake.size());
152
    r.consume(handshake.c_str(),handshake.size(),ec);
153
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
150
154
151
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
155
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
152
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
156
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 164-170 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
164
168
165
    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";
169
    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";
166
170
167
    r.consume(handshake.c_str(),handshake.size());
171
    r.consume(handshake.c_str(),handshake.size(),ec);
172
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
168
173
169
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
174
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
170
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
175
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 182-188 BOOST_AUTO_TEST_CASE( bad_host ) { Link Here
182
187
183
    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";
188
    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";
184
189
185
    r.consume(handshake.c_str(),handshake.size());
190
    r.consume(handshake.c_str(),handshake.size(),ec);
191
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
186
192
187
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
193
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
188
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
194
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
(-)websocketpp-zaphoyd/test/processors/hybi08.cpp (-6 / +12 lines)
Lines 76-82 BOOST_AUTO_TEST_CASE( exact_match ) { Link Here
76
76
77
    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";
77
    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";
78
78
79
    r.consume(handshake.c_str(),handshake.size());
79
    r.consume(handshake.c_str(),handshake.size(),ec);
80
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
80
81
81
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
82
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
82
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
83
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 110-116 BOOST_AUTO_TEST_CASE( non_get_method ) { Link Here
110
111
111
    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";
112
    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";
112
113
113
    r.consume(handshake.c_str(),handshake.size());
114
    r.consume(handshake.c_str(),handshake.size(),ec);
115
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
114
116
115
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
117
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
116
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
118
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 128-134 BOOST_AUTO_TEST_CASE( old_http_version ) Link Here
128
130
129
    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";
131
    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";
130
132
131
    r.consume(handshake.c_str(),handshake.size());
133
    r.consume(handshake.c_str(),handshake.size(),ec);
134
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
132
135
133
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
136
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
134
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
137
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 146-152 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
146
149
147
    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";
150
    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";
148
151
149
    r.consume(handshake.c_str(),handshake.size());
152
    r.consume(handshake.c_str(),handshake.size(),ec);
153
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
150
154
151
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
155
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
152
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
156
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 164-170 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
164
168
165
    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";
169
    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";
166
170
167
    r.consume(handshake.c_str(),handshake.size());
171
    r.consume(handshake.c_str(),handshake.size(),ec);
172
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
168
173
169
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
174
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
170
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
175
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
Lines 183-189 BOOST_AUTO_TEST_CASE( bad_host ) { Link Here
183
188
184
    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";
189
    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";
185
190
186
    r.consume(handshake.c_str(),handshake.size());
191
    r.consume(handshake.c_str(),handshake.size(),ec);
192
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
187
193
188
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
194
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
189
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
195
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version());
(-)websocketpp-zaphoyd/test/processors/hybi13.cpp (-11 / +40 lines)
Lines 122-128 BOOST_AUTO_TEST_CASE( exact_match ) { Link Here
122
122
123
    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";
123
    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";
124
124
125
    env.req.consume(handshake.c_str(),handshake.size());
125
    websocketpp::lib::error_code ec;
126
127
    env.req.consume(handshake.c_str(),handshake.size(),ec);
128
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
126
129
127
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
130
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
128
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
131
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
Lines 149-155 BOOST_AUTO_TEST_CASE( non_get_method ) { Link Here
149
152
150
    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";
153
    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";
151
154
152
    env.req.consume(handshake.c_str(),handshake.size());
155
    websocketpp::lib::error_code ec;
156
157
    env.req.consume(handshake.c_str(),handshake.size(),ec);
158
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
153
159
154
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
160
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
155
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
161
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
Lines 161-167 BOOST_AUTO_TEST_CASE( old_http_version ) Link Here
161
167
162
    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";
168
    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";
163
169
164
    env.req.consume(handshake.c_str(),handshake.size());
170
    websocketpp::lib::error_code ec;
171
172
    env.req.consume(handshake.c_str(),handshake.size(),ec);
173
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
165
174
166
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
175
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req));
167
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
176
    BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version());
Lines 173-179 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
173
182
174
    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";
183
    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";
175
184
176
    env.req.consume(handshake.c_str(),handshake.size());
185
    websocketpp::lib::error_code ec;
186
187
    env.req.consume(handshake.c_str(),handshake.size(),ec);
188
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
177
189
178
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
190
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
179
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
191
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
Lines 185-191 BOOST_AUTO_TEST_CASE( missing_handshake_ Link Here
185
197
186
    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";
198
    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";
187
199
188
    env.req.consume(handshake.c_str(),handshake.size());
200
    websocketpp::lib::error_code ec;
201
202
    env.req.consume(handshake.c_str(),handshake.size(),ec);
203
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
189
204
190
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
205
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
191
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
206
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
Lines 197-203 BOOST_AUTO_TEST_CASE( bad_host ) { Link Here
197
212
198
    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";
213
    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";
199
214
200
    env.req.consume(handshake.c_str(),handshake.size());
215
    websocketpp::lib::error_code ec;
216
217
    env.req.consume(handshake.c_str(),handshake.size(),ec);
218
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
201
219
202
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
220
    BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) );
203
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
221
    BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() );
Lines 558-564 BOOST_AUTO_TEST_CASE( client_handshake_r Link Here
558
    processor_setup env(false);
576
    processor_setup env(false);
559
577
560
    std::string res = "HTTP/1.1 404 Not Found\r\n\r\n";
578
    std::string res = "HTTP/1.1 404 Not Found\r\n\r\n";
561
    env.res.consume(res.data(),res.size());
579
580
    websocketpp::lib::error_code ec;
581
    env.res.consume(res.data(),res.size(),ec);
582
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
562
583
563
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::invalid_http_status );
584
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::invalid_http_status );
564
}
585
}
Lines 567-573 BOOST_AUTO_TEST_CASE( client_handshake_r Link Here
567
    processor_setup env(false);
588
    processor_setup env(false);
568
589
569
    std::string res = "HTTP/1.1 101 Switching Protocols\r\n\r\n";
590
    std::string res = "HTTP/1.1 101 Switching Protocols\r\n\r\n";
570
    env.res.consume(res.data(),res.size());
591
    websocketpp::lib::error_code ec;
592
    env.res.consume(res.data(),res.size(),ec);
593
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
571
594
572
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
595
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
573
}
596
}
Lines 576-582 BOOST_AUTO_TEST_CASE( client_handshake_r Link Here
576
    processor_setup env(false);
599
    processor_setup env(false);
577
600
578
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\n\r\n";
601
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\n\r\n";
579
    env.res.consume(res.data(),res.size());
602
    websocketpp::lib::error_code ec;
603
    env.res.consume(res.data(),res.size(),ec);
604
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
580
605
581
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
606
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
582
}
607
}
Lines 585-591 BOOST_AUTO_TEST_CASE( client_handshake_r Link Here
585
    processor_setup env(false);
610
    processor_setup env(false);
586
611
587
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\n\r\n";
612
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\n\r\n";
588
    env.res.consume(res.data(),res.size());
613
    websocketpp::lib::error_code ec;
614
    env.res.consume(res.data(),res.size(),ec);
615
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
589
616
590
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
617
    BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header );
591
}
618
}
Lines 596-602 BOOST_AUTO_TEST_CASE( client_handshake_r Link Here
596
    env.req.append_header("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
623
    env.req.append_header("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
597
624
598
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
625
    std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n";
599
    env.res.consume(res.data(),res.size());
626
    websocketpp::lib::error_code ec;
627
    env.res.consume(res.data(),res.size(),ec);
628
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
600
629
601
    BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) );
630
    BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) );
602
}
631
}
(-)websocketpp-zaphoyd/test/processors/processor.cpp (-10 / +30 lines)
Lines 39-45 BOOST_AUTO_TEST_CASE( exact_match ) { Link Here
39
39
40
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n";
40
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n";
41
41
42
    r.consume(handshake.c_str(),handshake.size());
42
    websocketpp::lib::error_code ec;
43
    r.consume(handshake.c_str(),handshake.size(),ec);
44
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
43
45
44
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
46
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
45
}
47
}
Lines 49-55 BOOST_AUTO_TEST_CASE( non_match ) { Link Here
49
51
50
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n\r\n";
52
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n\r\n";
51
53
52
    r.consume(handshake.c_str(),handshake.size());
54
    websocketpp::lib::error_code ec;
55
    r.consume(handshake.c_str(),handshake.size(),ec);
56
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
53
57
54
    BOOST_CHECK(!websocketpp::processor::is_websocket_handshake(r));
58
    BOOST_CHECK(!websocketpp::processor::is_websocket_handshake(r));
55
}
59
}
Lines 59-65 BOOST_AUTO_TEST_CASE( ci_exact_match ) { Link Here
59
63
60
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: UpGrAde\r\nUpgrade: WebSocket\r\n\r\n";
64
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: UpGrAde\r\nUpgrade: WebSocket\r\n\r\n";
61
65
62
    r.consume(handshake.c_str(),handshake.size());
66
    websocketpp::lib::error_code ec;
67
    r.consume(handshake.c_str(),handshake.size(),ec);
68
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
63
69
64
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
70
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
65
}
71
}
Lines 69-75 BOOST_AUTO_TEST_CASE( non_exact_match1 ) Link Here
69
75
70
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade,foo\r\nUpgrade: websocket,foo\r\n\r\n";
76
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade,foo\r\nUpgrade: websocket,foo\r\n\r\n";
71
77
72
    r.consume(handshake.c_str(),handshake.size());
78
    websocketpp::lib::error_code ec;
79
    r.consume(handshake.c_str(),handshake.size(),ec);
80
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
73
81
74
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
82
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
75
}
83
}
Lines 79-85 BOOST_AUTO_TEST_CASE( non_exact_match2 ) Link Here
79
87
80
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: keep-alive,Upgrade,foo\r\nUpgrade: foo,websocket,bar\r\n\r\n";
88
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: keep-alive,Upgrade,foo\r\nUpgrade: foo,websocket,bar\r\n\r\n";
81
89
82
    r.consume(handshake.c_str(),handshake.size());
90
    websocketpp::lib::error_code ec;
91
    r.consume(handshake.c_str(),handshake.size(),ec);
92
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
83
93
84
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
94
    BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r));
85
}
95
}
Lines 89-95 BOOST_AUTO_TEST_CASE( version_blank ) { Link Here
89
99
90
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\n\r\n";
100
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\n\r\n";
91
101
92
    r.consume(handshake.c_str(),handshake.size());
102
    websocketpp::lib::error_code ec;
103
    r.consume(handshake.c_str(),handshake.size(),ec);
104
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
93
105
94
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 0);
106
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 0);
95
}
107
}
Lines 99-105 BOOST_AUTO_TEST_CASE( version_7 ) { Link Here
99
111
100
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
112
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n";
101
113
102
    r.consume(handshake.c_str(),handshake.size());
114
    websocketpp::lib::error_code ec;
115
    r.consume(handshake.c_str(),handshake.size(),ec);
116
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
103
117
104
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 7);
118
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 7);
105
}
119
}
Lines 109-115 BOOST_AUTO_TEST_CASE( version_8 ) { Link Here
109
123
110
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
124
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n";
111
125
112
    r.consume(handshake.c_str(),handshake.size());
126
    websocketpp::lib::error_code ec;
127
    r.consume(handshake.c_str(),handshake.size(),ec);
128
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
113
129
114
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 8);
130
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 8);
115
}
131
}
Lines 119-125 BOOST_AUTO_TEST_CASE( version_13 ) { Link Here
119
135
120
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
136
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n";
121
137
122
    r.consume(handshake.c_str(),handshake.size());
138
    websocketpp::lib::error_code ec;
139
    r.consume(handshake.c_str(),handshake.size(),ec);
140
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
123
141
124
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 13);
142
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 13);
125
}
143
}
Lines 129-135 BOOST_AUTO_TEST_CASE( version_non_numeri Link Here
129
147
130
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: abc\r\n\r\n";
148
    std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: abc\r\n\r\n";
131
149
132
    r.consume(handshake.c_str(),handshake.size());
150
    websocketpp::lib::error_code ec;
151
    r.consume(handshake.c_str(),handshake.size(),ec);
152
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
133
153
134
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
154
    BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1);
135
}
155
}
(-)websocketpp-zaphoyd/test/processors/SConscript (-1 / +1 lines)
Lines 26-32 prgs += env.Program('test_hybi07_boost', Link Here
26
prgs += env.Program('test_hybi00_boost', ["test_hybi00_boost.o"], LIBS = BOOST_LIBS)
26
prgs += env.Program('test_hybi00_boost', ["test_hybi00_boost.o"], LIBS = BOOST_LIBS)
27
prgs += env.Program('test_extension_permessage_compress_boost', ["test_extension_permessage_compress_boost.o"], LIBS = BOOST_LIBS + ['z'])
27
prgs += env.Program('test_extension_permessage_compress_boost', ["test_extension_permessage_compress_boost.o"], LIBS = BOOST_LIBS + ['z'])
28
28
29
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
29
if 'WSPP_CPP11_ENABLED' in env_cpp11:
30
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
30
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z']
31
   # no C++11 features are used in processor so there are no C++11 versions of
31
   # no C++11 features are used in processor so there are no C++11 versions of
32
   # these tests.
32
   # these tests.
(-)websocketpp-zaphoyd/test/random/SConscript (-1 / +1 lines)
Lines 17-23 objs += env.Object('random_device_boost. Link Here
17
prgs = env.Program('test_random_none_boost', ["random_none_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_random_none_boost', ["random_none_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_random_device_boost', ["random_device_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_random_device_boost', ["random_device_boost.o"], LIBS = BOOST_LIBS)
19
19
20
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
20
if 'WSPP_CPP11_ENABLED' in env_cpp11:
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
22
   objs += env_cpp11.Object('random_none_stl.o', ["none.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('random_none_stl.o', ["none.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('random_device_stl.o', ["random_device.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('random_device_stl.o', ["random_device.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/roles/client.cpp (-3 / +7 lines)
Lines 104-114 BOOST_AUTO_TEST_CASE( connect_con ) { Link Here
104
    c.register_ostream(&out);
104
    c.register_ostream(&out);
105
105
106
    connection_ptr con = c.get_connection("ws://localhost/", ec);
106
    connection_ptr con = c.get_connection("ws://localhost/", ec);
107
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
107
    c.connect(con);
108
    c.connect(con);
108
109
109
    o = out.str();
110
    o = out.str();
110
    websocketpp::http::parser::request r;
111
    websocketpp::http::parser::request r;
111
    r.consume(o.data(),o.size());
112
    r.consume(o.data(),o.size(),ec);
113
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
112
114
113
    BOOST_CHECK( r.ready() );
115
    BOOST_CHECK( r.ready() );
114
    BOOST_CHECK_EQUAL( r.get_method(), "GET");
116
    BOOST_CHECK_EQUAL( r.get_method(), "GET");
Lines 174-183 BOOST_AUTO_TEST_CASE( add_subprotocols ) Link Here
174
    c.register_ostream(&out);
176
    c.register_ostream(&out);
175
177
176
    connection_ptr con = c.get_connection("ws://localhost/", ec);
178
    connection_ptr con = c.get_connection("ws://localhost/", ec);
179
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
177
    BOOST_CHECK( con );
180
    BOOST_CHECK( con );
178
181
179
    con->add_subprotocol("foo",ec);
182
    con->add_subprotocol("foo",ec);
180
    BOOST_CHECK( !ec );
183
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
181
184
182
    BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") );
185
    BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") );
183
186
Lines 185-191 BOOST_AUTO_TEST_CASE( add_subprotocols ) Link Here
185
188
186
    o = out.str();
189
    o = out.str();
187
    websocketpp::http::parser::request r;
190
    websocketpp::http::parser::request r;
188
    r.consume(o.data(),o.size());
191
    r.consume(o.data(),o.size(),ec);
192
    BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
189
193
190
    BOOST_CHECK( r.ready() );
194
    BOOST_CHECK( r.ready() );
191
    BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar");
195
    BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar");
(-)websocketpp-zaphoyd/test/roles/SConscript (-1 / +1 lines)
Lines 17-23 objs += env.Object('server_boost.o', ["s Link Here
17
prgs = env.Program('test_client_boost', ["client_boost.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_client_boost', ["client_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_server_boost', ["server_boost.o"], LIBS = BOOST_LIBS)
18
prgs += env.Program('test_server_boost', ["server_boost.o"], LIBS = BOOST_LIBS)
19
19
20
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
20
if 'WSPP_CPP11_ENABLED' in env_cpp11:
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
21
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
22
   objs += env_cpp11.Object('client_stl.o', ["client.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   objs += env_cpp11.Object('client_stl.o', ["client.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('server_stl.o', ["server.cpp"], LIBS = BOOST_LIBS_CPP11)
23
   objs += env_cpp11.Object('server_stl.o', ["server.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/roles/server.cpp (-1 / +253 lines)
Lines 35-40 Link Here
35
#include <websocketpp/config/core.hpp>
35
#include <websocketpp/config/core.hpp>
36
#include <websocketpp/server.hpp>
36
#include <websocketpp/server.hpp>
37
37
38
#include <websocketpp/transport/base/endpoint.hpp>
39
#include <websocketpp/transport/stub/endpoint.hpp>
40
38
typedef websocketpp::server<websocketpp::config::core> server;
41
typedef websocketpp::server<websocketpp::config::core> server;
39
typedef websocketpp::config::core::message_type::ptr message_ptr;
42
typedef websocketpp::config::core::message_type::ptr message_ptr;
40
43
Lines 71-77 std::string run_server_test(server& s, s Link Here
71
    s.clear_access_channels(websocketpp::log::alevel::all);
74
    s.clear_access_channels(websocketpp::log::alevel::all);
72
    s.clear_error_channels(websocketpp::log::elevel::all);
75
    s.clear_error_channels(websocketpp::log::elevel::all);
73
76
74
    con = s.get_connection();
77
    websocketpp::lib::error_code ec;
78
    con = s.get_connection(ec);
75
    con->start();
79
    con->start();
76
80
77
    std::stringstream channel;
81
    std::stringstream channel;
Lines 236-241 BOOST_AUTO_TEST_CASE( accept_subprotocol Link Here
236
    BOOST_CHECK_EQUAL(open, "bar");
240
    BOOST_CHECK_EQUAL(open, "bar");
237
}
241
}
238
242
243
void handle_start_accept(websocketpp::lib::error_code * rec, websocketpp::lib::error_code * rtec, websocketpp::lib::error_code const & ec, websocketpp::lib::error_code const & tec) {
244
    *rec = ec;
245
    *rtec = tec;
246
}
247
248
namespace test_transport {
249
250
template <typename config>
251
struct endpoint : websocketpp::transport::stub::endpoint<config> {
252
    void config_test(int accept_cons, bool init_connections) {
253
        m_accept_cons = accept_cons;
254
        m_init_connections = init_connections;
255
    }
256
257
    bool is_listening() const {
258
        if (m_accept_cons > 0) {
259
            return true;
260
        } else {
261
            return false;
262
        }
263
    }
264
265
    typedef typename websocketpp::transport::stub::endpoint<config>::transport_con_ptr transport_con_ptr;
266
267
    websocketpp::lib::error_code init(transport_con_ptr tcon) {
268
        if (m_init_connections) {
269
            return websocketpp::lib::error_code();
270
        } else {
271
            return websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented);
272
        }
273
    }
274
275
    void async_accept(transport_con_ptr tcon, websocketpp::transport::accept_handler cb, websocketpp::lib::error_code & ec) {
276
        m_accept_cons--;
277
278
        ec = websocketpp::lib::error_code();
279
        cb(ec);
280
    }
281
282
    int m_accept_cons;
283
    bool m_init_connections;
284
};
285
286
} // namespace test_transport
287
288
struct test_config : public websocketpp::config::core {
289
    typedef test_transport::endpoint<websocketpp::config::core::transport_config> transport_type;
290
};
291
292
void handle_fail(websocketpp::server<test_config> * s, websocketpp::lib::error_code * rec, websocketpp::connection_hdl hdl) {
293
    websocketpp::server<test_config>::connection_ptr con = s->get_con_from_hdl(hdl);
294
295
    *rec = con->get_ec();
296
}
297
298
void handle_fail_count(websocketpp::server<test_config> * s, websocketpp::lib::error_code rec, int * count, websocketpp::connection_hdl hdl) {
299
    websocketpp::server<test_config>::connection_ptr con = s->get_con_from_hdl(hdl);
300
301
    if (con->get_ec() == rec) {
302
        (*count)++;
303
    }
304
}
305
306
BOOST_AUTO_TEST_CASE( start_accept_not_listening ) {
307
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
308
    websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test);
309
310
    websocketpp::server<test_config> s;
311
312
    // config the test endpoint to report that it is not listening or generating connections
313
    s.config_test(0, false);
314
315
    // attempt to start accepting connections
316
    s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2));
317
318
    // confirm the right library and transport error codes
319
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error));
320
    BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening));
321
}
322
323
BOOST_AUTO_TEST_CASE( start_accept_con_creation_failed ) {
324
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
325
    websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test);
326
327
    websocketpp::server<test_config> s;
328
329
    // config the test endpoint to report that is listening but not generating connections
330
    s.config_test(1,false);
331
332
    // attempt to start accepting connections
333
    s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2));
334
335
    // confirm the right library and transport error codes
336
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed));
337
    BOOST_CHECK_EQUAL(rtec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented));
338
}
339
340
BOOST_AUTO_TEST_CASE( start_accept_con_1 ) {
341
    // this case tests the full successful start accept loop up to connection initialization.
342
343
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
344
    websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test);
345
    websocketpp::lib::error_code rsec = websocketpp::error::make_error_code(websocketpp::error::test);
346
347
    websocketpp::server<test_config> s;
348
349
    // config the test endpoint to report that it is listening for exactly
350
    // one connection and generating connections
351
    s.config_test(1,true);
352
353
    // we are expecting to fail due to connection initiation being "not implemented"
354
    s.set_fail_handler(bind(&handle_fail,&s,&rsec,::_1));
355
356
    // attempt to start accepting connections
357
    s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2));
358
359
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error));
360
    BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening));
361
    BOOST_CHECK_EQUAL(rsec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented));
362
}
363
364
BOOST_AUTO_TEST_CASE( start_accept_con_2 ) {
365
    // this case tests the full successful start accept loop up to connection initialization
366
    // for two full accept cycles before cancelling listening.
367
368
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
369
    websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test);
370
371
    websocketpp::server<test_config> s;
372
373
    // config the test endpoint to report that it is listening for exactly
374
    // one connection and generating connections
375
    s.config_test(2,true);
376
377
    websocketpp::lib::error_code xec = websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented);
378
    int count = 0;
379
380
    // we are expecting to fail due to connection initiation being "not implemented"
381
    // this handler will count the number of times it is called with "not implemented"
382
    s.set_fail_handler(bind(&handle_fail_count,&s,xec,&count,::_1));
383
384
    // attempt to start accepting connections
385
    s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2));
386
387
    // confirm that the final return was as expected
388
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error));
389
    BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening));
390
    // confirm that we saw two init attempts
391
    BOOST_CHECK_EQUAL(count, 2);
392
}
393
394
BOOST_AUTO_TEST_CASE( start_accept_not_listening_deprecated ) {
395
    // test deprecated start_accept(ec) failure path 1
396
397
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
398
399
    websocketpp::server<test_config> s;
400
401
    // config the test endpoint to report that it is listening for exactly
402
    // one connection and generating connections
403
    s.config_test(0,false);
404
405
    // attempt to start accepting connections
406
    s.start_accept(rec);
407
408
    // confirm that the final return was as expected
409
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening));
410
}
411
412
BOOST_AUTO_TEST_CASE( start_accept_con_creation_failed_deprecated ) {
413
    // test deprecated start_accept(ec) failure path 2
414
415
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
416
417
    websocketpp::server<test_config> s;
418
419
    // config the test endpoint to report that it is listening for exactly
420
    // one connection and generating connections
421
    s.config_test(1,false);
422
423
    // attempt to start accepting connections
424
    s.start_accept(rec);
425
426
    // confirm that the final return was as expected
427
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed));
428
}
429
430
BOOST_AUTO_TEST_CASE( start_accept_deprecated ) {
431
    // this case tests the full successful start accept loop up to connection initialization.
432
433
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
434
    websocketpp::lib::error_code rsec = websocketpp::error::make_error_code(websocketpp::error::test);
435
436
    websocketpp::server<test_config> s;
437
438
    // config the test endpoint to report that it is listening for exactly
439
    // one connection and generating connections
440
    s.config_test(1,true);
441
442
    // we are expecting to fail due to connection initiation being "not implemented"
443
    s.set_fail_handler(bind(&handle_fail,&s,&rsec,::_1));
444
445
    // attempt to start accepting connections
446
    s.start_accept(rec);
447
448
    BOOST_CHECK_EQUAL(rec, websocketpp::lib::error_code());
449
    BOOST_CHECK_EQUAL(rsec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented));
450
    // we can't automated test how/why the accept loop ends because this version has
451
    // no method for capturing that output other than the error log
452
}
453
454
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
455
BOOST_AUTO_TEST_CASE( start_accept_exception_con_creation_failed_deprecated ) {
456
    // this case tests two things:
457
    // 1. the existance of the deprecated start_accept() [with exceptions] function
458
    // 2. Error handling of the deprecated start_accept() in the case that the transport
459
    //    cannot create new connections.
460
461
    websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test);
462
463
    websocketpp::server<test_config> s;
464
465
    // config the test endpoint to report that it is listening for exactly
466
    // one connection and generating connections
467
    s.config_test(1,false);
468
469
    // attempt to start accepting connections
470
    try {
471
        s.start_accept();
472
    } catch (websocketpp::exception const & e) {
473
        rec = e.code();
474
    }
475
476
    // confirm that the final return was as expected
477
    BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed));
478
}
479
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
480
481
BOOST_AUTO_TEST_CASE( get_connection_deprecated ) {
482
    // exercise the deprecated get_connection function to help avoid regressions.
483
    // this test should be removed if the deprecated function is removed.
484
485
    server s;
486
    server::connection_ptr con = s.get_connection();
487
488
    BOOST_CHECK(con);
489
}
490
239
/*BOOST_AUTO_TEST_CASE( user_reject_origin ) {
491
/*BOOST_AUTO_TEST_CASE( user_reject_origin ) {
240
    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";
492
    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";
241
    std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n";
493
    std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n";
(-)websocketpp-zaphoyd/test/transport/asio/SConscript (-1 / +1 lines)
Lines 20-26 prgs = env.Program('test_base_boost', [" Link Here
20
prgs += env.Program('test_timers_boost', ["timers_boost.o"], LIBS = BOOST_LIBS)
20
prgs += env.Program('test_timers_boost', ["timers_boost.o"], LIBS = BOOST_LIBS)
21
prgs += env.Program('test_security_boost', ["security_boost.o"], LIBS = BOOST_LIBS)
21
prgs += env.Program('test_security_boost', ["security_boost.o"], LIBS = BOOST_LIBS)
22
22
23
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
23
if 'WSPP_CPP11_ENABLED' in env_cpp11:
24
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
24
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
25
   objs += env_cpp11.Object('base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11)
25
   objs += env_cpp11.Object('base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11)
26
   objs += env_cpp11.Object('timers_stl.o', ["timers.cpp"], LIBS = BOOST_LIBS_CPP11)
26
   objs += env_cpp11.Object('timers_stl.o', ["timers.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/transport/asio/timers.cpp (-7 / +8 lines)
Lines 54-62 void run_dummy_server(int port) { Link Here
54
    using boost::asio::ip::tcp;
54
    using boost::asio::ip::tcp;
55
55
56
    try {
56
    try {
57
        boost::asio::io_service io_service;
57
        boost::asio::io_context io_context;
58
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
58
        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port));
59
        tcp::socket socket(io_service);
59
        tcp::socket socket(io_context);
60
60
61
        acceptor.accept(socket);
61
        acceptor.accept(socket);
62
        for (;;) {
62
        for (;;) {
Lines 79-86 void run_dummy_server(int port) { Link Here
79
79
80
// Wait for the specified time period then fail the test
80
// Wait for the specified time period then fail the test
81
void run_test_timer(long value) {
81
void run_test_timer(long value) {
82
    boost::asio::io_service ios;
82
    boost::asio::io_context ctx;
83
    boost::asio::deadline_timer t(ios,boost::posix_time::milliseconds(value));
83
    boost::asio::system_timer t(ctx);
84
    t.expires_after(std::chrono::milliseconds(value));
84
    boost::system::error_code ec;
85
    boost::system::error_code ec;
85
    t.wait(ec);
86
    t.wait(ec);
86
    BOOST_FAIL( "Test timed out" );
87
    BOOST_FAIL( "Test timed out" );
Lines 106-114 struct config { Link Here
106
};
107
};
107
108
108
// Mock context that does no validation
109
// Mock context that does no validation
109
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
110
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;
110
context_ptr on_tls_init(websocketpp::connection_hdl) {
111
context_ptr on_tls_init(websocketpp::connection_hdl) {
111
    return context_ptr(new boost::asio::ssl::context(boost::asio::ssl::context::sslv23));
112
    return context_ptr(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::sslv23));
112
}
113
}
113
114
114
// Mock connection
115
// Mock connection
(-)websocketpp-zaphoyd/test/transport/integration.cpp (-38 / +40 lines)
Lines 38-43 Link Here
38
#include <websocketpp/server.hpp>
38
#include <websocketpp/server.hpp>
39
#include <websocketpp/client.hpp>
39
#include <websocketpp/client.hpp>
40
40
41
#include "boost/date_time/posix_time/posix_time.hpp"
42
41
struct config : public websocketpp::config::asio_client {
43
struct config : public websocketpp::config::asio_client {
42
    typedef config type;
44
    typedef config type;
43
    typedef websocketpp::config::asio base;
45
    typedef websocketpp::config::asio base;
Lines 218-236 void run_time_limited_client(client & c, Link Here
218
}
220
}
219
221
220
void run_dummy_server(int port) {
222
void run_dummy_server(int port) {
221
    using boost::asio::ip::tcp;
223
    using websocketpp::lib::asio::ip::tcp;
222
224
223
    try {
225
    try {
224
        boost::asio::io_service io_service;
226
        websocketpp::lib::asio::io_context io_context;
225
        tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port));
227
        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port));
226
        tcp::socket socket(io_service);
228
        tcp::socket socket(io_context);
227
229
228
        acceptor.accept(socket);
230
        acceptor.accept(socket);
229
        for (;;) {
231
        for (;;) {
230
            char data[512];
232
            char data[512];
231
            boost::system::error_code ec;
233
            websocketpp::lib::asio::error_code ec;
232
            socket.read_some(boost::asio::buffer(data), ec);
234
            socket.read_some(websocketpp::lib::asio::buffer(data), ec);
233
            if (ec == boost::asio::error::eof) {
235
            if (ec == websocketpp::lib::asio::error::eof) {
234
                break;
236
                break;
235
            } else if (ec) {
237
            } else if (ec) {
236
                // other error
238
                // other error
Lines 239-265 void run_dummy_server(int port) { Link Here
239
        }
241
        }
240
    } catch (std::exception & e) {
242
    } catch (std::exception & e) {
241
        std::cout << e.what() << std::endl;
243
        std::cout << e.what() << std::endl;
242
    } catch (boost::system::error_code & ec) {
244
    } catch (websocketpp::lib::asio::error_code & ec) {
243
        std::cout << ec.message() << std::endl;
245
        std::cout << ec.message() << std::endl;
244
    }
246
    }
245
}
247
}
246
248
247
void run_dummy_client(std::string port) {
249
void run_dummy_client(std::string port) {
248
    using boost::asio::ip::tcp;
250
    using websocketpp::lib::asio::ip::tcp;
249
251
250
    try {
252
    try {
251
        boost::asio::io_service io_service;
253
        websocketpp::lib::asio::io_context io_context;
252
        tcp::resolver resolver(io_service);
254
        tcp::resolver resolver(io_context);
253
        tcp::resolver::query query("localhost", port);
255
        tcp::resolver::results_type results = resolver.resolve("localhost", port);
254
        tcp::resolver::iterator iterator = resolver.resolve(query);
256
        tcp::socket socket(io_context);
255
        tcp::socket socket(io_service);
256
257
257
        boost::asio::connect(socket, iterator);
258
        websocketpp::lib::asio::connect(socket, results);
258
        for (;;) {
259
        for (;;) {
259
            char data[512];
260
            char data[512];
260
            boost::system::error_code ec;
261
            websocketpp::lib::asio::error_code ec;
261
            socket.read_some(boost::asio::buffer(data), ec);
262
            socket.read_some(websocketpp::lib::asio::buffer(data), ec);
262
            if (ec == boost::asio::error::eof) {
263
            if (ec == websocketpp::lib::asio::error::eof) {
263
                break;
264
                break;
264
            } else if (ec) {
265
            } else if (ec) {
265
                // other error
266
                // other error
Lines 268-274 void run_dummy_client(std::string port) Link Here
268
        }
269
        }
269
    } catch (std::exception & e) {
270
    } catch (std::exception & e) {
270
        std::cout << e.what() << std::endl;
271
        std::cout << e.what() << std::endl;
271
    } catch (boost::system::error_code & ec) {
272
    } catch (websocketpp::lib::asio::error_code & ec) {
272
        std::cout << ec.message() << std::endl;
273
        std::cout << ec.message() << std::endl;
273
    }
274
    }
274
}
275
}
Lines 354-386 void close(T * e, websocketpp::connectio Link Here
354
    e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,"");
355
    e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,"");
355
}
356
}
356
357
357
class test_deadline_timer
358
class test_system_timer
358
{
359
{
359
public:
360
public:
360
    test_deadline_timer(int seconds)
361
    test_system_timer(int seconds)
361
    : m_timer(m_io_service, boost::posix_time::seconds(seconds))
362
    : m_timer(m_io_context)
362
    {
363
    {
363
        m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1));
364
        m_timer.expires_after(std::chrono::seconds(seconds));
364
        std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run;
365
        m_timer.async_wait(bind(&test_system_timer::expired, this, ::_1));
365
        m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_service));
366
        std::size_t (websocketpp::lib::asio::io_context::*run)() = &websocketpp::lib::asio::io_context::run;
367
        m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context));
366
    }
368
    }
367
    ~test_deadline_timer()
369
    ~test_system_timer()
368
    {
370
    {
369
        m_timer.cancel();
371
        m_timer.cancel();
370
        m_timer_thread.join();
372
        m_timer_thread.join();
371
    }
373
    }
372
374
373
  private:
375
  private:
374
    void expired(const boost::system::error_code & ec)
376
    void expired(const websocketpp::lib::asio::error_code & ec)
375
    {
377
    {
376
        if (ec == boost::asio::error::operation_aborted)
378
        if (ec == websocketpp::lib::asio::error::operation_aborted)
377
            return;
379
            return;
378
        BOOST_CHECK(!ec);
380
        BOOST_CHECK(!ec);
379
        BOOST_FAIL("Test timed out");
381
        BOOST_FAIL("Test timed out");
380
    }
382
    }
381
383
382
    boost::asio::io_service m_io_service;
384
    websocketpp::lib::asio::io_context m_io_context;
383
    boost::asio::deadline_timer m_timer;
385
    websocketpp::lib::asio::system_timer m_timer;
384
    websocketpp::lib::thread m_timer_thread;
386
    websocketpp::lib::thread m_timer_thread;
385
};
387
};
386
388
Lines 426-432 BOOST_AUTO_TEST_CASE( pong_timeout ) { Link Here
426
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
428
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
427
    sleep(1); // give the server thread some time to start
429
    sleep(1); // give the server thread some time to start
428
430
429
    test_deadline_timer deadline(10);
431
    test_system_timer deadline(10);
430
432
431
    run_client(c, "http://localhost:9005",false);
433
    run_client(c, "http://localhost:9005",false);
432
434
Lines 447-453 BOOST_AUTO_TEST_CASE( client_open_handsh Link Here
447
449
448
    sleep(1); // give the server thread some time to start
450
    sleep(1); // give the server thread some time to start
449
451
450
    test_deadline_timer deadline(10);
452
    test_system_timer deadline(10);
451
453
452
    run_client(c, "http://localhost:9005");
454
    run_client(c, "http://localhost:9005");
453
}
455
}
Lines 463-469 BOOST_AUTO_TEST_CASE( server_open_handsh Link Here
463
465
464
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
466
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
465
467
466
    test_deadline_timer deadline(10);
468
    test_system_timer deadline(10);
467
469
468
    sleep(1); // give the server thread some time to start
470
    sleep(1); // give the server thread some time to start
469
471
Lines 488-494 BOOST_AUTO_TEST_CASE( client_self_initia Link Here
488
490
489
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
491
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
490
492
491
    test_deadline_timer deadline(10);
493
    test_system_timer deadline(10);
492
494
493
    sleep(1); // give the server thread some time to start
495
    sleep(1); // give the server thread some time to start
494
496
Lines 521-527 BOOST_AUTO_TEST_CASE( server_self_initia Link Here
521
    c.set_open_handler(bind(&delay,::_1,1));
523
    c.set_open_handler(bind(&delay,::_1,1));
522
524
523
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
525
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
524
    test_deadline_timer deadline(10);
526
    test_system_timer deadline(10);
525
527
526
    sleep(1); // give the server thread some time to start
528
    sleep(1); // give the server thread some time to start
527
529
Lines 533-539 BOOST_AUTO_TEST_CASE( server_self_initia Link Here
533
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
535
BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) {
534
    client c;
536
    client c;
535
537
536
    test_deadline_timer deadline(3);
538
    test_system_timer deadline(3);
537
539
538
    websocketpp::lib::error_code ec;
540
    websocketpp::lib::error_code ec;
539
    c.init_asio(ec);
541
    c.init_asio(ec);
Lines 541-547 BOOST_AUTO_TEST_CASE( client_runs_out_of Link Here
541
543
542
    c.run();
544
    c.run();
543
545
544
    // This test checks that an io_service with no work ends immediately.
546
    // This test checks that an io_context with no work ends immediately.
545
    BOOST_CHECK(true);
547
    BOOST_CHECK(true);
546
}
548
}
547
549
Lines 599-605 BOOST_AUTO_TEST_CASE( stop_listening ) { Link Here
599
    c.set_open_handler(bind(&close<client>,&c,::_1));
601
    c.set_open_handler(bind(&close<client>,&c,::_1));
600
602
601
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
603
    websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false));
602
    test_deadline_timer deadline(5);
604
    test_system_timer deadline(5);
603
605
604
    sleep(1); // give the server thread some time to start
606
    sleep(1); // give the server thread some time to start
605
607
(-)websocketpp-zaphoyd/test/transport/iostream/SConscript (-1 / +1 lines)
Lines 19-25 prgs = env.Program('test_iostream_base_b Link Here
19
prgs += env.Program('test_iostream_connection_boost', ["iostream_connection_boost.o"], LIBS = BOOST_LIBS)
19
prgs += env.Program('test_iostream_connection_boost', ["iostream_connection_boost.o"], LIBS = BOOST_LIBS)
20
prgs += env.Program('test_iostream_endpoint_boost', ["iostream_endpoint_boost.o"], LIBS = BOOST_LIBS)
20
prgs += env.Program('test_iostream_endpoint_boost', ["iostream_endpoint_boost.o"], LIBS = BOOST_LIBS)
21
21
22
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
22
if 'WSPP_CPP11_ENABLED' in env_cpp11:
23
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
23
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
24
   objs += env_cpp11.Object('iostream_base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11)
24
   objs += env_cpp11.Object('iostream_base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11)
25
   objs += env_cpp11.Object('iostream_connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11)
25
   objs += env_cpp11.Object('iostream_connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/transport/SConscript (-1 / +1 lines)
Lines 16-22 BOOST_LIBS = boostlibs(['unit_test_frame Link Here
16
objs = env.Object('boost_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS)
16
objs = env.Object('boost_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_boost_integration', ["boost_integration.o"], LIBS = BOOST_LIBS)
17
prgs = env.Program('test_boost_integration', ["boost_integration.o"], LIBS = BOOST_LIBS)
18
18
19
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
19
if 'WSPP_CPP11_ENABLED' in env_cpp11:
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
20
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs]
21
   objs += env_cpp11.Object('stl_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS_CPP11)
21
   objs += env_cpp11.Object('stl_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS_CPP11)
22
   prgs += env_cpp11.Program('test_stl_integration', ["stl_integration.o"], LIBS = BOOST_LIBS_CPP11)
22
   prgs += env_cpp11.Program('test_stl_integration', ["stl_integration.o"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/utility/SConscript (-1 / +1 lines)
Lines 24-30 prgs += env.Program('test_close_boost', Link Here
24
prgs += env.Program('test_sha1_boost', ["sha1_boost.o"], LIBS = BOOST_LIBS)
24
prgs += env.Program('test_sha1_boost', ["sha1_boost.o"], LIBS = BOOST_LIBS)
25
prgs += env.Program('test_error_boost', ["error_boost.o"], LIBS = BOOST_LIBS)
25
prgs += env.Program('test_error_boost', ["error_boost.o"], LIBS = BOOST_LIBS)
26
26
27
if env_cpp11.has_key('WSPP_CPP11_ENABLED'):
27
if 'WSPP_CPP11_ENABLED' in env_cpp11:
28
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
28
   BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs]
29
   objs += env_cpp11.Object('utilities_stl.o', ["utilities.cpp"], LIBS = BOOST_LIBS_CPP11)
29
   objs += env_cpp11.Object('utilities_stl.o', ["utilities.cpp"], LIBS = BOOST_LIBS_CPP11)
30
   objs += env_cpp11.Object('uri_stl.o', ["uri.cpp"], LIBS = BOOST_LIBS_CPP11)
30
   objs += env_cpp11.Object('uri_stl.o', ["uri.cpp"], LIBS = BOOST_LIBS_CPP11)
(-)websocketpp-zaphoyd/test/utility/uri.cpp (-8 / +160 lines)
Lines 33-38 Link Here
33
33
34
#include <websocketpp/uri.hpp>
34
#include <websocketpp/uri.hpp>
35
35
36
// Many URI tests are inspired by the comprehensive test suite from
37
// the uriparser project (https://uriparser.github.io)
38
36
// Test a regular valid ws URI
39
// Test a regular valid ws URI
37
BOOST_AUTO_TEST_CASE( uri_valid ) {
40
BOOST_AUTO_TEST_CASE( uri_valid ) {
38
    websocketpp::uri uri("ws://localhost:9000/chat");
41
    websocketpp::uri uri("ws://localhost:9000/chat");
Lines 46-51 BOOST_AUTO_TEST_CASE( uri_valid ) { Link Here
46
    BOOST_CHECK_EQUAL( uri.get_query(), "" );
49
    BOOST_CHECK_EQUAL( uri.get_query(), "" );
47
}
50
}
48
51
52
BOOST_AUTO_TEST_CASE( uri_valid_ipv4 ) {
53
    //BOOST_CHECK( !websocketpp::uri("ws://01.0.0.0").get_valid() );
54
    //BOOST_CHECK( !websocketpp::uri("ws://001.0.0.0").get_valid() );
55
56
57
}
58
59
BOOST_AUTO_TEST_CASE( uri_valid_ipv6 ) {
60
    // Quad length
61
    BOOST_CHECK( websocketpp::uri("ws://[abcd::]").get_valid() );
62
    BOOST_CHECK( websocketpp::uri("ws://[abcd::1]").get_valid() );
63
    BOOST_CHECK( websocketpp::uri("ws://[abcd::12]").get_valid() );
64
    BOOST_CHECK( websocketpp::uri("ws://[abcd::123]").get_valid() );
65
    BOOST_CHECK( websocketpp::uri("ws://[abcd::1234]").get_valid() );
66
67
    // Full length
68
    BOOST_CHECK( websocketpp::uri("ws://[2001:0db8:0100:f101:0210:a4ff:fee3:9566]").get_valid() );
69
    BOOST_CHECK( websocketpp::uri("ws://[2001:0DB8:0100:F101:0210:A4FF:FEE3:9566]").get_valid() );
70
    BOOST_CHECK( websocketpp::uri("ws://[2001:db8:100:f101:210:a4ff:fee3:9566]").get_valid() );
71
    BOOST_CHECK( websocketpp::uri("ws://[2001:0db8:100:f101:0:0:0:1]").get_valid() );
72
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6:255.255.255.255]").get_valid() );
73
74
    // Legal IPv4
75
    BOOST_CHECK( websocketpp::uri("ws://[::1.2.3.4]").get_valid() );
76
    BOOST_CHECK( websocketpp::uri("ws://[3:4::5:1.2.3.4]").get_valid() );
77
    BOOST_CHECK( websocketpp::uri("ws://[::ffff:1.2.3.4]").get_valid() );
78
    BOOST_CHECK( websocketpp::uri("ws://[::0.0.0.0]").get_valid() );
79
    BOOST_CHECK( websocketpp::uri("ws://[::255.255.255.255]").get_valid() );
80
81
    // Zipper position
82
    BOOST_CHECK( websocketpp::uri("ws://[::1:2:3:4:5:6:7]").get_valid() );
83
    BOOST_CHECK( websocketpp::uri("ws://[1::1:2:3:4:5:6]").get_valid() );
84
    BOOST_CHECK( websocketpp::uri("ws://[1:2::1:2:3:4:5]").get_valid() );
85
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3::1:2:3:4]").get_valid() );
86
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4::1:2:3]").get_valid() );
87
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5::1:2]").get_valid() );
88
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6::1]").get_valid() );
89
    BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6:7::]").get_valid() );
90
91
    // Zipper length
92
    BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1:1:1]").get_valid() );
93
    BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1:1]").get_valid() );
94
    BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1]").get_valid() );
95
    BOOST_CHECK( websocketpp::uri("ws://[1:1::1:1]").get_valid() );
96
    BOOST_CHECK( websocketpp::uri("ws://[1:1::1]").get_valid() );
97
    BOOST_CHECK( websocketpp::uri("ws://[1::1]").get_valid() );
98
    BOOST_CHECK( websocketpp::uri("ws://[::1]").get_valid() );
99
    BOOST_CHECK( websocketpp::uri("ws://[::]").get_valid() );
100
101
    // Misc
102
    BOOST_CHECK( websocketpp::uri("ws://[21ff:abcd::1]").get_valid() );
103
    BOOST_CHECK( websocketpp::uri("ws://[2001:db8:100:f101::1]").get_valid() );
104
    BOOST_CHECK( websocketpp::uri("ws://[a:b:c::12:1]").get_valid() );
105
    BOOST_CHECK( websocketpp::uri("ws://[a:b::0:1:2:3]").get_valid() );
106
}
107
108
BOOST_AUTO_TEST_CASE( uri_invalid_ipv6 ) {
109
    // 5 char quad
110
    BOOST_CHECK( !websocketpp::uri("ws://[::12345]").get_valid() );
111
112
    // Two zippers
113
    BOOST_CHECK( !websocketpp::uri("ws://[abcd::abcd::abcd]").get_valid() );
114
115
    // Triple-colon zipper
116
    BOOST_CHECK( !websocketpp::uri("ws://[:::1234]").get_valid() );
117
    BOOST_CHECK( !websocketpp::uri("ws://[1234:::1234:1234]").get_valid() );
118
    BOOST_CHECK( !websocketpp::uri("ws://[1234:1234:::1234]").get_valid() );
119
    BOOST_CHECK( !websocketpp::uri("ws://[1234:::]").get_valid() );
120
121
    // No quads, just IPv4. These are valid uris, just shouldn't parse as IPv6 literal
122
    websocketpp::uri ipv4_1("ws://1.2.3.4");
123
    BOOST_CHECK( ipv4_1.get_valid() );
124
    BOOST_CHECK( !ipv4_1.is_ipv6_literal() );
125
126
    // Five quads
127
    BOOST_CHECK( !websocketpp::uri("ws://[0000:0000:0000:0000:0000:1.2.3.4]").get_valid() );
128
129
    // Seven quads
130
    BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0]").get_valid() );
131
    BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0:]").get_valid() );
132
    BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0:1.2.3.4]").get_valid() );
133
134
    // Nine quads (or more)
135
    BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4:5:6:7:8:9]").get_valid() );
136
    BOOST_CHECK( !websocketpp::uri("ws://[::2:3:4:5:6:7:8:9]").get_valid() );
137
    BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4::6:7:8:9]").get_valid() );
138
    BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4:5:6:7:8::]").get_valid() );
139
140
    // Invalid IPv4 part
141
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:001.02.03.004]").get_valid() );
142
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.1111]").get_valid() );
143
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.256]").get_valid() );
144
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:311.2.3.4]").get_valid() );
145
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3:4]").get_valid() );
146
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3]").get_valid() );
147
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.]").get_valid() );
148
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3a.4]").get_valid() );
149
    BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.4:123]").get_valid() );
150
151
    // Nonhex
152
    BOOST_CHECK( !websocketpp::uri("ws://[g:0:0:0:0:0:0]").get_valid() );
153
154
    // missing end bracket
155
    BOOST_CHECK( !websocketpp::uri("ws://[::1").get_valid() );
156
    BOOST_CHECK( !websocketpp::uri("ws://[::1:80").get_valid() );
157
    BOOST_CHECK( !websocketpp::uri("ws://[::1/foo").get_valid() );
158
    BOOST_CHECK( !websocketpp::uri("ws://[::1#foo").get_valid() );
159
}
160
161
BOOST_AUTO_TEST_CASE( uri_valid_no_slash ) {
162
    websocketpp::uri uri("ws://localhost");
163
164
    BOOST_CHECK( uri.get_valid() );
165
    BOOST_CHECK( !uri.get_secure() );
166
    BOOST_CHECK_EQUAL( uri.get_scheme(), "ws");
167
    BOOST_CHECK_EQUAL( uri.get_host(), "localhost");
168
    BOOST_CHECK_EQUAL( uri.get_port(), 80 );
169
    BOOST_CHECK_EQUAL( uri.get_resource(), "/" );
170
}
171
172
BOOST_AUTO_TEST_CASE( uri_valid_no_slash_with_fragment ) {
173
    websocketpp::uri uri("ws://localhost#foo");
174
175
    BOOST_CHECK( uri.get_valid() );
176
    BOOST_CHECK( !uri.get_secure() );
177
    BOOST_CHECK_EQUAL( uri.get_scheme(), "ws");
178
    BOOST_CHECK_EQUAL( uri.get_host(), "localhost");
179
    BOOST_CHECK_EQUAL( uri.get_port(), 80 );
180
    BOOST_CHECK_EQUAL( uri.get_resource(), "#foo" );
181
}
182
49
// Test a regular valid ws URI
183
// Test a regular valid ws URI
50
BOOST_AUTO_TEST_CASE( uri_valid_no_port_unsecure ) {
184
BOOST_AUTO_TEST_CASE( uri_valid_no_port_unsecure ) {
51
    websocketpp::uri uri("ws://localhost/chat");
185
    websocketpp::uri uri("ws://localhost/chat");
Lines 92-97 BOOST_AUTO_TEST_CASE( uri_valid_ipv6_lit Link Here
92
    BOOST_CHECK_EQUAL( uri.get_host(), "::1");
226
    BOOST_CHECK_EQUAL( uri.get_host(), "::1");
93
    BOOST_CHECK_EQUAL( uri.get_port(), 9000 );
227
    BOOST_CHECK_EQUAL( uri.get_port(), 9000 );
94
    BOOST_CHECK_EQUAL( uri.get_resource(), "/chat" );
228
    BOOST_CHECK_EQUAL( uri.get_resource(), "/chat" );
229
    BOOST_CHECK_EQUAL( uri.str(), "wss://[::1]:9000/chat" );
230
    BOOST_CHECK_EQUAL( uri.get_host_port(), "[::1]:9000" );
231
    BOOST_CHECK_EQUAL( uri.get_authority(), "[::1]:9000" );
232
}
233
234
// Valid URI IPv6 Literal with default port
235
BOOST_AUTO_TEST_CASE( uri_valid_ipv6_literal_default_port ) {
236
    websocketpp::uri uri("wss://[::1]/chat");
237
238
    BOOST_CHECK( uri.get_valid() );
239
    BOOST_CHECK( uri.get_secure() );
240
    BOOST_CHECK_EQUAL( uri.get_scheme(), "wss");
241
    BOOST_CHECK_EQUAL( uri.get_host(), "::1");
242
    BOOST_CHECK_EQUAL( uri.get_port(), 443 );
243
    BOOST_CHECK_EQUAL( uri.get_resource(), "/chat" );
244
    BOOST_CHECK_EQUAL( uri.str(), "wss://[::1]/chat" );
245
    BOOST_CHECK_EQUAL( uri.get_host_port(), "::1" );
246
    BOOST_CHECK_EQUAL( uri.get_authority(), "[::1]:443" );
95
}
247
}
96
248
97
// Valid URI with more complicated host
249
// Valid URI with more complicated host
Lines 192-197 BOOST_AUTO_TEST_CASE( uri_invalid_bad_v6 Link Here
192
    BOOST_CHECK( !uri.get_valid() );
344
    BOOST_CHECK( !uri.get_valid() );
193
}
345
}
194
346
347
// Invalid URI with stray []
348
BOOST_AUTO_TEST_CASE( uri_invalid_free_delim ) {
349
    websocketpp::uri uri("wss://localhos[]t/chat");
350
351
    BOOST_CHECK( !uri.get_valid() );
352
}
353
195
// Valid URI complicated resource path with query
354
// Valid URI complicated resource path with query
196
BOOST_AUTO_TEST_CASE( uri_valid_4 ) {
355
BOOST_AUTO_TEST_CASE( uri_valid_4 ) {
197
    websocketpp::uri uri("wss://localhost:9000/chat/foo/bar?foo=bar");
356
    websocketpp::uri uri("wss://localhost:9000/chat/foo/bar?foo=bar");
Lines 236-246 BOOST_AUTO_TEST_CASE( uri_invalid_no_sch Link Here
236
    BOOST_CHECK( !uri.get_valid() );
395
    BOOST_CHECK( !uri.get_valid() );
237
}
396
}
238
397
239
// Invalid IPv6 literal
398
// TODO: tests for the other constructors, especially with IP literals
240
/*BOOST_AUTO_TEST_CASE( uri_invalid_v6_nonhex ) {
241
    websocketpp::uri uri("wss://[g::1]:9000/");
242
243
    BOOST_CHECK( uri.get_valid() == false );
244
}*/
245
246
// TODO: tests for the other two constructors
(-)websocketpp-zaphoyd/test/utility/utilities.cpp (-3 / +3 lines)
Lines 56-65 BOOST_AUTO_TEST_CASE( substr_not_found ) Link Here
56
    BOOST_CHECK(websocketpp::utility::ci_find_substr(haystack,needle) == haystack.end());
56
    BOOST_CHECK(websocketpp::utility::ci_find_substr(haystack,needle) == haystack.end());
57
}
57
}
58
58
59
BOOST_AUTO_TEST_CASE( to_lower ) {
59
BOOST_AUTO_TEST_CASE( to_hex ) {
60
    std::string in = "AbCd";
60
    std::string in = "\x01\x23\x45\x67\x89\xAB\xCD\xEF";
61
61
62
    BOOST_CHECK_EQUAL(websocketpp::utility::to_lower(in), "abcd");
62
    BOOST_CHECK_EQUAL(websocketpp::utility::to_hex(in), "01 23 45 67 89 AB CD EF ");
63
}
63
}
64
64
65
BOOST_AUTO_TEST_CASE( string_replace_all ) {
65
BOOST_AUTO_TEST_CASE( string_replace_all ) {
(-)websocketpp-zaphoyd/.travis.yml (-7 / +16 lines)
Lines 1-18 Link Here
1
language: cpp
1
language: cpp
2
dist: bionic
2
compiler:
3
compiler:
3
  - gcc
4
  - gcc
4
before_install:
5
addons:
5
 #- sudo apt-get install libboost-chrono1.48-dev libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y
6
  apt:
6
 - sudo add-apt-repository -y ppa:boost-latest/ppa && sudo apt-get update -q && sudo apt-get install -y libboost-chrono1.55-dev libboost-random1.55-dev libboost-regex1.55-dev libboost-system1.55-dev libboost-thread1.55-dev libboost-test1.55-dev
7
    packages:
8
      - libboost-random-dev
9
      - libboost-system-dev
10
      - libboost-test-dev
11
      - libboost-thread-dev
12
      - zlib1g-dev
13
      - cmake
7
env:
14
env:
8
  global:
15
  global:
9
    - BOOST_INCLUDES=/usr/include
16
    - BOOST_INCLUDES=/usr/include
10
    - BOOST_LIBS=/usr/lib/x86_64-linux-gnu
17
    - BOOST_LIBS=/usr/lib/x86_64-linux-gnu
11
script: scons -j 2 && scons test
18
script: cmake -DBUILD_EXAMPLES=1 -DBUILD_TESTS=1 . && make -j 2 && make test
12
branches:
19
branches:
13
  only:
20
  except:
14
    - master
21
    - 0.2.x
15
    - develop
22
    - experimental
23
    - legacy
24
16
notifications:
25
notifications:
17
  recipients:
26
  recipients:
18
    - travis@zaphoyd.com
27
    - travis@zaphoyd.com
(-)websocketpp-zaphoyd/tutorials/utility_server/step1.cpp (-1 / +1 lines)
Lines 57-63 public: Link Here
57
        // Queues a connection accept operation
57
        // Queues a connection accept operation
58
        m_endpoint.start_accept();
58
        m_endpoint.start_accept();
59
59
60
        // Start the Asio io_service run loop
60
        // Start the Asio io_context run loop
61
        m_endpoint.run();
61
        m_endpoint.run();
62
    }
62
    }
63
private:
63
private:
(-)websocketpp-zaphoyd/tutorials/utility_server/step2.cpp (-1 / +1 lines)
Lines 68-74 public: Link Here
68
        // Queues a connection accept operation
68
        // Queues a connection accept operation
69
        m_endpoint.start_accept();
69
        m_endpoint.start_accept();
70
70
71
        // Start the Asio io_service run loop
71
        // Start the Asio io_context run loop
72
        m_endpoint.run();
72
        m_endpoint.run();
73
    }
73
    }
74
private:
74
private:
(-)websocketpp-zaphoyd/tutorials/utility_server/utility_server.md (-4 / +4 lines)
Lines 56-62 m_endpoint.set_access_channels(websocket Link Here
56
56
57
Next, we initialize the transport system underlying the endpoint. This method is specific to the Asio transport not WebSocket++ core. It will not be necessary or present in endpoints that use a non-asio config.
57
Next, we initialize the transport system underlying the endpoint. This method is specific to the Asio transport not WebSocket++ core. It will not be necessary or present in endpoints that use a non-asio config.
58
58
59
> **Note:** This example uses an internal Asio `io_service` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_service` object or want to build a new program where WebSocket++ handlers share an io_service with other handlers you can pass the `io_service` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?]
59
> **Note:** This example uses an internal Asio `io_context` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_context` object or want to build a new program where WebSocket++ handlers share an io_context with other handlers you can pass the `io_context` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?]
60
60
61
~~~{.cpp}
61
~~~{.cpp}
62
m_endpoint.init_asio();
62
m_endpoint.init_asio();
Lines 64-70 m_endpoint.init_asio(); Link Here
64
64
65
#### `utility_server::run` method
65
#### `utility_server::run` method
66
66
67
In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_service event loop.
67
In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_context event loop.
68
68
69
~~~{.cpp}
69
~~~{.cpp}
70
// Listen on port 9002
70
// Listen on port 9002
Lines 73-79 m_endpoint.listen(9002); Link Here
73
// Queues a connection accept operation
73
// Queues a connection accept operation
74
m_endpoint.start_accept();
74
m_endpoint.start_accept();
75
75
76
// Start the Asio io_service run loop
76
// Start the Asio io_context run loop
77
m_endpoint.run();
77
m_endpoint.run();
78
~~~
78
~~~
79
79
Lines 123-129 public: Link Here
123
        // Queues a connection accept operation
123
        // Queues a connection accept operation
124
        m_endpoint.start_accept();
124
        m_endpoint.start_accept();
125
125
126
        // Start the Asio io_service run loop
126
        // Start the Asio io_context run loop
127
        m_endpoint.run();
127
        m_endpoint.run();
128
    }
128
    }
129
private:
129
private:
(-)websocketpp-zaphoyd/websocketpp/common/asio.hpp (-1 / +1 lines)
Lines 51-57 Link Here
51
    
51
    
52
    #include <asio.hpp>
52
    #include <asio.hpp>
53
    #include <asio/steady_timer.hpp>
53
    #include <asio/steady_timer.hpp>
54
    #include <websocketpp/common/chrono.hpp> 
54
    #include <websocketpp/common/chrono.hpp>
55
#else
55
#else
56
    #include <boost/version.hpp>
56
    #include <boost/version.hpp>
57
    
57
    
(-)websocketpp-zaphoyd/websocketpp/common/cpp11.hpp (-1 / +3 lines)
Lines 88-96 Link Here
88
    #endif
88
    #endif
89
    
89
    
90
    #ifndef __GNUC__
90
    #ifndef __GNUC__
91
        // GCC as of version 4.9 (latest) does not support std::put_time yet.
91
        // GCC as of version 4.9 does not support std::put_time yet.
92
        // so ignore it
92
        // so ignore it
93
        #define _WEBSOCKETPP_PUTTIME_
93
        #define _WEBSOCKETPP_PUTTIME_
94
95
        // todo: std::put_time may be present in version 5+
94
    #endif
96
    #endif
95
#else
97
#else
96
    // In the absence of a blanket define, try to use compiler versions or
98
    // In the absence of a blanket define, try to use compiler versions or
(-)websocketpp-zaphoyd/websocketpp/common/md5.hpp (-1 / +1 lines)
Lines 364-370 void md5_append(md5_state_t *pms, md5_by Link Here
364
    return;
364
    return;
365
365
366
    /* Update the message length. */
366
    /* Update the message length. */
367
    pms->count[1] += nbytes >> 29;
367
    pms->count[1] += static_cast<md5_word_t>(nbytes >> 29);
368
    pms->count[0] += nbits;
368
    pms->count[0] += nbits;
369
    if (pms->count[0] < nbits)
369
    if (pms->count[0] < nbits)
370
    pms->count[1]++;
370
    pms->count[1]++;
(-)websocketpp-zaphoyd/websocketpp/connection.hpp (-60 / +211 lines)
Lines 82-88 typedef lib::function<void(connection_hd Link Here
82
/**
82
/**
83
 * The interrupt handler is called when a connection receives an interrupt
83
 * The interrupt handler is called when a connection receives an interrupt
84
 * request from the application. Interrupts allow the application to trigger a
84
 * request from the application. Interrupts allow the application to trigger a
85
 * handler to be run in the absense of a WebSocket level handler trigger (like
85
 * handler to be run in the absence of a WebSocket level handler trigger (like
86
 * a new message).
86
 * a new message).
87
 *
87
 *
88
 * This is typically used by another application thread to schedule some tasks
88
 * This is typically used by another application thread to schedule some tasks
Lines 687-708 public: Link Here
687
     */
687
     */
688
    lib::error_code send(message_ptr msg);
688
    lib::error_code send(message_ptr msg);
689
689
690
    /// Asyncronously invoke handler::on_inturrupt
690
    /// Asynchronously invoke handler::on_interrupt
691
    /**
691
    /**
692
     * Signals to the connection to asyncronously invoke the on_inturrupt
692
     * Signals to the connection to asynchronously invoke the on_interrupt
693
     * callback for this connection's handler once it is safe to do so.
693
     * callback for this connection's handler once it is safe to do so.
694
     *
694
     *
695
     * When the on_inturrupt handler callback is called it will be from
695
     * When the on_interrupt handler callback is called it will be from
696
     * within the transport event loop with all the thread safety features
696
     * within the transport event loop with all the thread safety features
697
     * guaranteed by the transport to regular handlers
697
     * guaranteed by the transport to regular handlers
698
     *
698
     *
699
     * Multiple inturrupt signals can be active at once on the same connection
699
     * Multiple interrupt signals can be active at once on the same connection
700
     *
700
     *
701
     * @return An error code
701
     * @return An error code
702
     */
702
     */
703
    lib::error_code interrupt();
703
    lib::error_code interrupt();
704
    
704
    
705
    /// Transport inturrupt callback
705
    /// Transport interrupt callback
706
    void handle_interrupt();
706
    void handle_interrupt();
707
    
707
    
708
    /// Pause reading of new data
708
    /// Pause reading of new data
Lines 865-871 public: Link Here
865
    // Subprotocol negotiation //
865
    // Subprotocol negotiation //
866
    /////////////////////////////
866
    /////////////////////////////
867
867
868
    /// Gets the negotated subprotocol
868
    /// Gets the negotiated subprotocol
869
    /**
869
    /**
870
     * Retrieves the subprotocol that was negotiated during the handshake. This
870
     * Retrieves the subprotocol that was negotiated during the handshake. This
871
     * method is valid in the open handler and later.
871
     * method is valid in the open handler and later.
Lines 888-913 public: Link Here
888
     * Adds a subprotocol to the list to send with the opening handshake. This
888
     * Adds a subprotocol to the list to send with the opening handshake. This
889
     * may be called multiple times to request more than one. If the server
889
     * may be called multiple times to request more than one. If the server
890
     * supports one of these, it may choose one. If so, it will return it
890
     * supports one of these, it may choose one. If so, it will return it
891
     * in it's handshake reponse and the value will be available via
891
     * in it's handshake response and the value will be available via
892
     * get_subprotocol(). Subprotocol requests should be added in order of
892
     * get_subprotocol(). Subprotocol requests should be added in order of
893
     * preference.
893
     * preference.
894
     *
894
     *
895
     * @param request The subprotocol to request
895
     * @param[in] request The subprotocol to request
896
     * @param ec A reference to an error code that will be filled in the case of
896
     * @param[out] ec A status code describing the outcome of the operation
897
     * errors
898
     */
897
     */
899
    void add_subprotocol(std::string const & request, lib::error_code & ec);
898
    void add_subprotocol(std::string const & request, lib::error_code & ec);
900
899
901
    /// Adds the given subprotocol string to the request list
900
    /// Adds the given subprotocol string to the request list (exception)
902
    /**
901
    /**
903
     * Adds a subprotocol to the list to send with the opening handshake. This
902
     * Adds a subprotocol to the list to send with the opening handshake. This
904
     * may be called multiple times to request more than one. If the server
903
     * may be called multiple times to request more than one. If the server
905
     * supports one of these, it may choose one. If so, it will return it
904
     * supports one of these, it may choose one. If so, it will return it
906
     * in it's handshake reponse and the value will be available via
905
     * in it's handshake response and the value will be available via
907
     * get_subprotocol(). Subprotocol requests should be added in order of
906
     * get_subprotocol(). Subprotocol requests should be added in order of
908
     * preference.
907
     * preference.
909
     *
908
     *
910
     * @param request The subprotocol to request
909
     * @param[in] request The subprotocol to request
911
     */
910
     */
912
    void add_subprotocol(std::string const & request);
911
    void add_subprotocol(std::string const & request);
913
912
Lines 920-932 public: Link Here
920
     *
919
     *
921
     * This member function is valid on server endpoints/connections only
920
     * This member function is valid on server endpoints/connections only
922
     *
921
     *
923
     * @param value The subprotocol to select
922
     * @param[in] value The subprotocol to select
924
     * @param ec A reference to an error code that will be filled in the case of
923
     * @param[out] ec A status code describing the outcome of the operation
925
     * errors
926
     */
924
     */
927
    void select_subprotocol(std::string const & value, lib::error_code & ec);
925
    void select_subprotocol(std::string const & value, lib::error_code & ec);
928
926
929
    /// Select a subprotocol to use
927
    /// Select a subprotocol to use (exception)
930
    /**
928
    /**
931
     * Indicates which subprotocol should be used for this connection. Valid
929
     * Indicates which subprotocol should be used for this connection. Valid
932
     * only during the validate handler callback. Subprotocol selected must have
930
     * only during the validate handler callback. Subprotocol selected must have
Lines 935-941 public: Link Here
935
     *
933
     *
936
     * This member function is valid on server endpoints/connections only
934
     * This member function is valid on server endpoints/connections only
937
     *
935
     *
938
     * @param value The subprotocol to select
936
     * @param[in] value The subprotocol to select
939
     */
937
     */
940
    void select_subprotocol(std::string const & value);
938
    void select_subprotocol(std::string const & value);
941
939
Lines 947-953 public: Link Here
947
    /**
945
    /**
948
     * Retrieve the value of a header from the handshake HTTP request.
946
     * Retrieve the value of a header from the handshake HTTP request.
949
     *
947
     *
950
     * @param key Name of the header to get
948
     * @param[in] key Name of the header to get
951
     * @return The value of the header
949
     * @return The value of the header
952
     */
950
     */
953
    std::string const & get_request_header(std::string const & key) const;
951
    std::string const & get_request_header(std::string const & key) const;
Lines 967-973 public: Link Here
967
    /**
965
    /**
968
     * Retrieve the value of a header from the handshake HTTP request.
966
     * Retrieve the value of a header from the handshake HTTP request.
969
     *
967
     *
970
     * @param key Name of the header to get
968
     * @param[in] key Name of the header to get
971
     * @return The value of the header
969
     * @return The value of the header
972
     */
970
     */
973
    std::string const & get_response_header(std::string const & key) const;
971
    std::string const & get_response_header(std::string const & key) const;
Lines 996-1002 public: Link Here
996
        return m_response.get_status_msg();
994
        return m_response.get_status_msg();
997
    }
995
    }
998
    
996
    
999
    /// Set response status code and message
997
    /// Set response status code and message (exception free)
1000
    /**
998
    /**
1001
     * Sets the response status code to `code` and looks up the corresponding
999
     * Sets the response status code to `code` and looks up the corresponding
1002
     * message for standard codes. Non-standard codes will be entered as Unknown
1000
     * message for standard codes. Non-standard codes will be entered as Unknown
Lines 1006-1018 public: Link Here
1006
     * This member function is valid only from the http() and validate() handler
1004
     * This member function is valid only from the http() and validate() handler
1007
     * callbacks.
1005
     * callbacks.
1008
     *
1006
     *
1009
     * @param code Code to set
1007
     * @since 0.9.0
1010
     * @param msg Message to set
1008
     * 
1011
     * @see websocketpp::http::response::set_status
1009
     * @param[in] code Code to set
1010
     * @param[in] msg Message to set
1011
     * @param[out] ec A status code describing the outcome of the operation
1012
     * @see websocketpp::http::parser::response::set_status
1013
     * @see websocketpp::http::status_code::value (list of valid codes)
1014
     */
1015
    void set_status(http::status_code::value code, lib::error_code & ec);
1016
1017
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
1018
    /// Set response status code and message (exception)
1019
    /**
1020
     * Sets the response status code and message to independent custom values.
1021
     * use set_status(status_code::value) to set the code and have the standard
1022
     * message be automatically set.
1023
     *
1024
     * This member function is valid only from the http() and validate() handler
1025
     * callbacks.
1026
     *
1027
     * @param[in] code Code to set
1028
     * @param[in] msg Message to set
1029
     * @throw websocketpp::exception
1030
     * @see websocketpp::http::parser::response::set_status()
1031
     * @see websocketpp::http::status_code::value (list of valid codes)
1012
     */
1032
     */
1013
    void set_status(http::status_code::value code);
1033
    void set_status(http::status_code::value code);
1034
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
1014
1035
1015
    /// Set response status code and message
1036
    /// Set response status code and message (exception free)
1016
    /**
1037
    /**
1017
     * Sets the response status code and message to independent custom values.
1038
     * Sets the response status code and message to independent custom values.
1018
     * use set_status(status_code::value) to set the code and have the standard
1039
     * use set_status(status_code::value) to set the code and have the standard
Lines 1021-1033 public: Link Here
1021
     * This member function is valid only from the http() and validate() handler
1042
     * This member function is valid only from the http() and validate() handler
1022
     * callbacks.
1043
     * callbacks.
1023
     *
1044
     *
1024
     * @param code Code to set
1045
     * @since 0.9.0
1025
     * @param msg Message to set
1046
     * 
1026
     * @see websocketpp::http::response::set_status
1047
     * @param[in] code Code to set
1048
     * @param[in] msg Message to set
1049
     * @param[out] ec A status code describing the outcome of the operation
1050
     * @see websocketpp::http::response::set_status()
1051
     * @see websocketpp::http::status_code::value (list of valid codes)
1052
     */
1053
    void set_status(http::status_code::value code, std::string const & msg,
1054
        lib::error_code & ec);
1055
1056
    /// Set response status code and message (exception)
1057
    /**
1058
     * Sets the response status code and message to independent custom values.
1059
     * use set_status(status_code::value) to set the code and have the standard
1060
     * message be automatically set.
1061
     *
1062
     * This member function is valid only from the http() and validate() handler
1063
     * callbacks.
1064
     *
1065
     * @param[in] code Code to set
1066
     * @param[in] msg Message to set
1067
     * @throw websocketpp::exception
1068
     * @see websocketpp::http::parser::response::set_status()
1069
     * @see websocketpp::http::status_code::value (list of valid codes)
1027
     */
1070
     */
1028
    void set_status(http::status_code::value code, std::string const & msg);
1071
    void set_status(http::status_code::value code, std::string const & msg);
1029
1072
1030
    /// Set response body content
1073
    /// Set response body content (exception free)
1031
    /**
1074
    /**
1032
     * Set the body content of the HTTP response to the parameter string. Note
1075
     * Set the body content of the HTTP response to the parameter string. Note
1033
     * set_body will also set the Content-Length HTTP header to the appropriate
1076
     * set_body will also set the Content-Length HTTP header to the appropriate
Lines 1037-1087 public: Link Here
1037
     * This member function is valid only from the http() and validate() handler
1080
     * This member function is valid only from the http() and validate() handler
1038
     * callbacks.
1081
     * callbacks.
1039
     *
1082
     *
1040
     * @param value String data to include as the body content.
1083
     * @since 0.9.0
1084
     *
1085
     * @param[in] value String data to include as the body content.
1086
     * @param[out] ec A status code describing the outcome of the operation
1041
     * @see websocketpp::http::response::set_body
1087
     * @see websocketpp::http::response::set_body
1088
     * @see set_body(std::string const &) (exception version)
1042
     */
1089
     */
1043
    void set_body(std::string const & value);
1090
    void set_body(std::string const & value, lib::error_code & ec);
1044
1091
1045
    /// Append a header
1092
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
1093
    /// Set response body content (exception)
1046
    /**
1094
    /**
1047
     * If a header with this name already exists the value will be appended to
1095
     * Set the body content of the HTTP response to the parameter string. Note
1048
     * the existing header to form a comma separated list of values. Use
1096
     * set_body will also set the Content-Length HTTP header to the appropriate
1049
     * `connection::replace_header` to overwrite existing values.
1097
     * value. If you want the Content-Length header to be something else set it
1098
     * to something else after calling set_body
1050
     *
1099
     *
1051
     * This member function is valid only from the http() and validate() handler
1100
     * This member function is valid only from the http() and validate() handler
1052
     * callbacks, or to a client connection before connect has been called.
1101
     * callbacks.
1102
     *
1103
     * @param[in] value String data to include as the body content.
1104
     * @throw websocketpp::exception
1105
     * @see websocketpp::http::response::set_body
1106
     * @see set_body(std::string const &, lib::error_code &)
1107
     *      (exception free version)
1108
     */
1109
    void set_body(std::string const & value);
1110
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
1111
1112
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
1113
    /// @copydoc websocketpp::connection::set_body(std::string const &, lib::error_code &)
1114
    void set_body(std::string && value, lib::error_code & ec);
1115
1116
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
1117
    /// @copydoc websocketpp::connection::set_body(std::string const &)
1118
    void set_body(std::string && value);
1119
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
1120
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
1121
1122
    /// Append a header (exception free)
1123
    /**
1124
     * Set the value of a header in the handshake HTTP request or response. If
1125
     * a header with this name already exists the value will be appended to the
1126
     * existing header to form a comma separated list of values. Use
1127
     * `connection::replace_header` to overwrite existing values.
1128
     *
1129
     * *When can this member function be called?*
1130
     *  - Servers: Valid from the http and validate handlers
1131
     *  - Clients: Valid before websocketpp::client::connect() has been called
1132
     *
1133
     * @since 0.9.0
1134
     *
1135
     * @param[in] key Name of the header to set
1136
     * @param[in] val Value to add
1137
     * @param[out] ec A status code describing the outcome of the operation
1138
     * @see connection::replace_header
1139
     * @see websocketpp::http::parser::parser::append_header
1140
     * @see append_header(std::string const &, std::string const &)
1141
     *      (exception version)
1142
     */
1143
    void append_header(std::string const & key, std::string const & val,
1144
        lib::error_code & ec);
1145
1146
    /// Append a header (exception)
1147
    /**
1148
     * Set the value of a header in the handshake HTTP request or response. If
1149
     * a header with this name already exists the value will be appended to the
1150
     * existing header to form a comma separated list of values. Use
1151
     * `connection::replace_header` to overwrite existing values.
1053
     *
1152
     *
1054
     * @param key Name of the header to set
1153
     * *When can this member function be called?*
1055
     * @param val Value to add
1154
     *  - Servers: Valid from the http and validate handlers
1056
     * @see replace_header
1155
     *  - Clients: Valid before websocketpp::client::connect() has been called
1057
     * @see websocketpp::http::parser::append_header
1156
     *
1157
     * @param[in] key Name of the header to set
1158
     * @param[in] val Value to add
1159
     * @throw websocketpp::exception
1160
     * @see connection::replace_header
1161
     * @see websocketpp::http::parser::parser::append_header
1162
     * @see append_header(std::string const &, std::string const &,
1163
     *      lib::error_code &) (exception free version)
1058
     */
1164
     */
1059
    void append_header(std::string const & key, std::string const & val);
1165
    void append_header(std::string const & key, std::string const & val);
1060
1166
1061
    /// Replace a header
1167
    /// Replace a header (exception free)
1062
    /**
1168
    /**
1063
     * If a header with this name already exists the old value will be replaced
1169
     * Set the value of a header in the handshake HTTP request or response. If
1170
     * a header with this name already exists the old value will be replaced
1064
     * Use `connection::append_header` to append to a list of existing values.
1171
     * Use `connection::append_header` to append to a list of existing values.
1065
     *
1172
     *
1066
     * This member function is valid only from the http() and validate() handler
1173
     * *When can this member function be called?*
1067
     * callbacks, or to a client connection before connect has been called.
1174
     *  - Servers: Valid from the http and validate handlers
1175
     *  - Clients: Valid before websocketpp::client::connect() has been called
1176
     *
1177
     * @param[in] key Name of the header to set
1178
     * @param[in] val Value to set
1179
     * @param[out] ec A status code describing the outcome of the operation
1180
     * @see connection::append_header
1181
     * @see websocketpp::http::parser::parser::replace_header
1182
     * @see replace_header(std::string const &, std::string const &)
1183
     *      (exception version)
1184
     */
1185
    void replace_header(std::string const & key, std::string const & val,
1186
        lib::error_code & ec);
1187
1188
    /// Replace a header (exception)
1189
    /**
1190
     * Set the value of a header in the handshake HTTP request or response. If
1191
     * a header with this name already exists the old value will be replaced
1192
     * Use `connection::append_header` to append to a list of existing values.
1068
     *
1193
     *
1069
     * @param key Name of the header to set
1194
     * *When can this member function be called?*
1070
     * @param val Value to set
1195
     *  - Servers: Valid from the http and validate handlers
1071
     * @see append_header
1196
     *  - Clients: Valid before websocketpp::client::connect() has been called
1072
     * @see websocketpp::http::parser::replace_header
1197
     *
1198
     * @param[in] key Name of the header to set
1199
     * @param[in] val Value to set
1200
     * @throw websocketpp::exception
1201
     * @see connection::append_header
1202
     * @see websocketpp::http::parser::parser::replace_header
1203
     * @see replace_header(std::string const & key, std::string const & val,
1204
     *      lib::error_code & ec) (exception free version)
1073
     */
1205
     */
1074
    void replace_header(std::string const & key, std::string const & val);
1206
    void replace_header(std::string const & key, std::string const & val);
1075
1207
1076
    /// Remove a header
1208
    /// Remove a header (exception free)
1077
    /**
1209
    /**
1078
     * Removes a header from the response.
1210
     * Removes a header from the handshake HTTP request or response.
1079
     *
1211
     *
1080
     * This member function is valid only from the http() and validate() handler
1212
     * *When can this member function be called?*
1081
     * callbacks, or to a client connection before connect has been called.
1213
     *  - Servers: Valid from the http and validate handlers
1214
     *  - Clients: Valid before websocketpp::client::connect() has been called
1215
     *
1216
     * @param[in] key The name of the header to remove
1217
     * @param[out] ec A status code describing the outcome of the operation
1218
     * @see websocketpp::http::parser::parser::remove_header
1219
     * @see remove_header(std::string const &) (exception version)
1220
     */
1221
    void remove_header(std::string const & key, lib::error_code & ec);
1222
1223
    /// Remove a header (exception)
1224
    /**
1225
     * Removes a header from the handshake HTTP request or response.
1226
     *
1227
     * *When can this member function be called?*
1228
     *  - Servers: Valid from the http and validate handlers
1229
     *  - Clients: Valid before websocketpp::client::connect() has been called
1082
     *
1230
     *
1083
     * @param key The name of the header to remove
1231
     * @param[in] key The name of the header to remove
1084
     * @see websocketpp::http::parser::remove_header
1232
     * @throw websocketpp::exception
1233
     * @see websocketpp::http::parser::parser::remove_header
1234
     * @see remove_header(std::string const &, lib::error_code &) 
1235
     *      (exception free version)
1085
     */
1236
     */
1086
    void remove_header(std::string const & key);
1237
    void remove_header(std::string const & key);
1087
1238
Lines 1125-1132 public: Link Here
1125
    /// Defer HTTP Response until later (Exception free)
1276
    /// Defer HTTP Response until later (Exception free)
1126
    /**
1277
    /**
1127
     * Used in the http handler to defer the HTTP response for this connection
1278
     * Used in the http handler to defer the HTTP response for this connection
1128
     * until later. Handshake timers will be canceled and the connection will be
1279
     * until later. Handshake timers will be canceled and the connection will
1129
     * left open until `send_http_response` or an equivalent is called.
1280
     * be left open until `send_http_response` or an equivalent is called.
1130
     *
1281
     *
1131
     * Warning: deferred connections won't time out and as a result can tie up
1282
     * Warning: deferred connections won't time out and as a result can tie up
1132
     * resources.
1283
     * resources.
Lines 1389-1395 private: Link Here
1389
    /**
1540
    /**
1390
     * If no arguments are present no close code/reason will be specified.
1541
     * If no arguments are present no close code/reason will be specified.
1391
     *
1542
     *
1392
     * Note: the close code/reason values provided here may be overrided by
1543
     * Note: the close code/reason values provided here may be overridden by
1393
     * other settings (such as silent close).
1544
     * other settings (such as silent close).
1394
     *
1545
     *
1395
     * @param code The close code to send
1546
     * @param code The close code to send
Lines 1403-1409 private: Link Here
1403
    /**
1554
    /**
1404
     * If no arguments are present no close code/reason will be specified.
1555
     * If no arguments are present no close code/reason will be specified.
1405
     *
1556
     *
1406
     * Note: the close code/reason values provided here may be overrided by
1557
     * Note: the close code/reason values provided here may be overridden by
1407
     * other settings (such as silent close).
1558
     * other settings (such as silent close).
1408
     *
1559
     *
1409
     * The ack flag determines what to do in the case of a blank status and
1560
     * The ack flag determines what to do in the case of a blank status and
Lines 1573-1579 private: Link Here
1573
     */
1724
     */
1574
    size_t m_send_buffer_size;
1725
    size_t m_send_buffer_size;
1575
1726
1576
    /// buffer holding the various parts of the current message being writen
1727
    /// buffer holding the various parts of the current message being written
1577
    /**
1728
    /**
1578
     * Lock m_write_lock
1729
     * Lock m_write_lock
1579
     */
1730
     */
(-)websocketpp-zaphoyd/websocketpp/endpoint.hpp (-4 / +7 lines)
Lines 28-33 Link Here
28
#ifndef WEBSOCKETPP_ENDPOINT_HPP
28
#ifndef WEBSOCKETPP_ENDPOINT_HPP
29
#define WEBSOCKETPP_ENDPOINT_HPP
29
#define WEBSOCKETPP_ENDPOINT_HPP
30
30
31
#include <websocketpp/transport/base/endpoint.hpp>
32
31
#include <websocketpp/connection.hpp>
33
#include <websocketpp/connection.hpp>
32
34
33
#include <websocketpp/logger/levels.hpp>
35
#include <websocketpp/logger/levels.hpp>
Lines 109-115 public: Link Here
109
111
110
112
111
    /// Destructor
113
    /// Destructor
112
    ~endpoint<connection,config>() {}
114
    ~endpoint() {}
113
115
114
    #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
116
    #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
115
        // no copy constructor because endpoints are not copyable
117
        // no copy constructor because endpoints are not copyable
Lines 476-482 public: Link Here
476
     * can produce one additional type of error, the bad_connection error, that
478
     * can produce one additional type of error, the bad_connection error, that
477
     * indicates that the conversion from connection_hdl to connection_ptr
479
     * indicates that the conversion from connection_hdl to connection_ptr
478
     * failed due to the connection not existing anymore. Each method has a
480
     * failed due to the connection not existing anymore. Each method has a
479
     * default and an exception free varient.
481
     * default and an exception free variant.
480
     */
482
     */
481
483
482
    void interrupt(connection_hdl hdl, lib::error_code & ec);
484
    void interrupt(connection_hdl hdl, lib::error_code & ec);
Lines 566-572 public: Link Here
566
     * @param [in] hdl The handle identifying the connection to send via.
568
     * @param [in] hdl The handle identifying the connection to send via.
567
     * @param [in] payload The payload string to generated the message with
569
     * @param [in] payload The payload string to generated the message with
568
     * @param [in] op The opcode to generated the message with.
570
     * @param [in] op The opcode to generated the message with.
569
     * @param [out] ec A code to fill in for errors
570
     */
571
     */
571
    void send(connection_hdl hdl, std::string const & payload,
572
    void send(connection_hdl hdl, std::string const & payload,
572
        frame::opcode::value op);
573
        frame::opcode::value op);
Lines 649-654 public: Link Here
649
        return con;
650
        return con;
650
    }
651
    }
651
652
653
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
652
    /// Retrieves a connection_ptr from a connection_hdl (exception version)
654
    /// Retrieves a connection_ptr from a connection_hdl (exception version)
653
    connection_ptr get_con_from_hdl(connection_hdl hdl) {
655
    connection_ptr get_con_from_hdl(connection_hdl hdl) {
654
        lib::error_code ec;
656
        lib::error_code ec;
Lines 658-665 public: Link Here
658
        }
660
        }
659
        return con;
661
        return con;
660
    }
662
    }
663
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
661
protected:
664
protected:
662
    connection_ptr create_connection();
665
    connection_ptr create_connection(lib::error_code & ec);
663
666
664
    lib::shared_ptr<alog_type> m_alog;
667
    lib::shared_ptr<alog_type> m_alog;
665
    lib::shared_ptr<elog_type> m_elog;
668
    lib::shared_ptr<elog_type> m_elog;
(-)websocketpp-zaphoyd/websocketpp/error.hpp (-1 / +6 lines)
Lines 143-149 enum value { Link Here
143
    http_parse_error,
143
    http_parse_error,
144
    
144
    
145
    /// Extension negotiation failed
145
    /// Extension negotiation failed
146
    extension_neg_failed
146
    extension_neg_failed,
147
148
    /// General transport error, consult more specific transport error code
149
    transport_error
147
}; // enum value
150
}; // enum value
148
151
149
152
Lines 221-226 public: Link Here
221
                return "HTTP parse error";
224
                return "HTTP parse error";
222
            case error::extension_neg_failed:
225
            case error::extension_neg_failed:
223
                return "Extension negotiation failed";
226
                return "Extension negotiation failed";
227
            case error::transport_error:
228
                return "An error occurred in the underlying transport. Consult transport error code for more details.";
224
            default:
229
            default:
225
                return "Unknown";
230
                return "Unknown";
226
        }
231
        }
(-)websocketpp-zaphoyd/websocketpp/frame.hpp (-4 / +4 lines)
Lines 234-250 struct basic_header { Link Here
234
/// The variable size component of a WebSocket frame header
234
/// The variable size component of a WebSocket frame header
235
struct extended_header {
235
struct extended_header {
236
    extended_header() {
236
    extended_header() {
237
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
237
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00));
238
    }
238
    }
239
239
240
    extended_header(uint64_t payload_size) {
240
    extended_header(uint64_t payload_size) {
241
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
241
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00));
242
242
243
        copy_payload(payload_size);
243
        copy_payload(payload_size);
244
    }
244
    }
245
245
246
    extended_header(uint64_t payload_size, uint32_t masking_key) {
246
    extended_header(uint64_t payload_size, uint32_t masking_key) {
247
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
247
        std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00));
248
248
249
        // Copy payload size
249
        // Copy payload size
250
        int offset = copy_payload(payload_size);
250
        int offset = copy_payload(payload_size);
Lines 831-837 inline size_t byte_mask_circ(uint8_t * i Link Here
831
    size_t prepared_key)
831
    size_t prepared_key)
832
{
832
{
833
    uint32_converter key;
833
    uint32_converter key;
834
    key.i = prepared_key;
834
    key.i = static_cast<uint32_t>(prepared_key);
835
835
836
    for (size_t i = 0; i < length; ++i) {
836
    for (size_t i = 0; i < length; ++i) {
837
        output[i] = input[i] ^ key.c[i % 4];
837
        output[i] = input[i] ^ key.c[i % 4];
(-)websocketpp-zaphoyd/websocketpp/http/constants.hpp (-249 / +402 lines)
Lines 34-308 Link Here
34
#include <vector>
34
#include <vector>
35
#include <utility>
35
#include <utility>
36
36
37
#include <websocketpp/common/system_error.hpp>
38
37
namespace websocketpp {
39
namespace websocketpp {
38
/// HTTP handling support
40
/// HTTP handling support
39
namespace http {
41
namespace http {
40
    /// The type of an HTTP attribute list
42
    
41
    /**
43
/// The type of an HTTP attribute list
42
     * The attribute list is an unordered key/value map. Encoded attribute
44
/**
43
     * values are delimited by semicolons.
45
 * The attribute list is an unordered key/value map. Encoded attribute
44
     */
46
 * values are delimited by semicolons.
45
    typedef std::map<std::string,std::string> attribute_list;
47
 */
46
48
typedef std::map<std::string,std::string> attribute_list;
47
    /// The type of an HTTP parameter list
49
48
    /**
50
/// The type of an HTTP parameter list
49
     * The parameter list is an ordered pairing of a parameter and its
51
/**
50
     * associated attribute list. Encoded parameter values are delimited by
52
 * The parameter list is an ordered pairing of a parameter and its
51
     * commas.
53
 * associated attribute list. Encoded parameter values are delimited by
52
     */
54
 * commas.
53
    typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
55
 */
54
56
typedef std::vector< std::pair<std::string,attribute_list> > parameter_list;
55
    /// Literal value of the HTTP header delimiter
57
56
    static char const header_delimiter[] = "\r\n";
58
/// Literal value of the HTTP header delimiter
57
59
static char const header_delimiter[] = "\r\n";
58
    /// Literal value of the HTTP header separator
60
59
    static char const header_separator[] = ":";
61
/// Literal value of the HTTP header separator
62
static char const header_separator[] = ":";
63
64
/// Literal value of an empty header
65
static std::string const empty_header;
66
67
/// Maximum size in bytes before rejecting an HTTP header as too big.
68
size_t const max_header_size = 16000;
69
70
/// Default Maximum size in bytes for HTTP message bodies.
71
size_t const max_body_size = 32000000;
72
73
/// Number of bytes to use for temporary istream read buffers
74
size_t const istream_buffer = 512;
75
76
/// invalid HTTP token characters
77
/**
78
 * 0x00 - 0x32, 0x7f-0xff
79
 * ( ) < > @ , ; : \ " / [ ] ? = { }
80
 */
81
static char const header_token[] = {
82
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f
83
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f
84
    0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f
85
    1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f
86
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f
87
    1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f
88
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f
89
    1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f
90
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f
91
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f
92
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af
93
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf
94
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf
95
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df
96
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef
97
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
98
};
99
100
/// Is the character a token
101
inline bool is_token_char(unsigned char c) {
102
    return (header_token[c] == 1);
103
}
60
104
61
    /// Literal value of an empty header
105
/// Is the character a non-token
62
    static std::string const empty_header;
106
inline bool is_not_token_char(unsigned char c) {
107
    return !header_token[c];
108
}
63
109
64
    /// Maximum size in bytes before rejecting an HTTP header as too big.
110
/// Is the character whitespace
65
    size_t const max_header_size = 16000;
111
/**
66
    
112
 * whitespace is space (32) or horizontal tab (9)
67
    /// Default Maximum size in bytes for HTTP message bodies.
113
 */
68
    size_t const max_body_size = 32000000;
114
inline bool is_whitespace_char(unsigned char c) {
115
    return (c == 9 || c == 32);
116
}
69
117
70
    /// Number of bytes to use for temporary istream read buffers
118
/// Is the character non-whitespace
71
    size_t const istream_buffer = 512;
119
inline bool is_not_whitespace_char(unsigned char c) {
120
    return (c != 9 && c != 32);
121
}
72
122
73
    /// invalid HTTP token characters
123
/// HTTP Status codes
74
    /**
124
namespace status_code {
75
     * 0x00 - 0x32, 0x7f-0xff
125
/// Known values for HTTP Status codes
76
     * ( ) < > @ , ; : \ " / [ ] ? = { }
126
enum value {
77
     */
127
    uninitialized = 0,
78
    static char const header_token[] = {
128
79
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f
129
    continue_code = 100,
80
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f
130
    switching_protocols = 101,
81
        0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f
131
82
        1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f
132
    ok = 200,
83
        0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f
133
    created = 201,
84
        1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f
134
    accepted = 202,
85
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f
135
    non_authoritative_information = 203,
86
        1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f
136
    no_content = 204,
87
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f
137
    reset_content = 205,
88
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f
138
    partial_content = 206,
89
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af
139
90
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf
140
    multiple_choices = 300,
91
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf
141
    moved_permanently = 301,
92
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df
142
    found = 302,
93
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef
143
    see_other = 303,
94
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff
144
    not_modified = 304,
95
    };
145
    use_proxy = 305,
96
146
    temporary_redirect = 307,
97
    /// Is the character a token
147
98
    inline bool is_token_char(unsigned char c) {
148
    bad_request = 400,
99
        return (header_token[c] == 1);
149
    unauthorized = 401,
150
    payment_required = 402,
151
    forbidden = 403,
152
    not_found = 404,
153
    method_not_allowed = 405,
154
    not_acceptable = 406,
155
    proxy_authentication_required = 407,
156
    request_timeout = 408,
157
    conflict = 409,
158
    gone = 410,
159
    length_required = 411,
160
    precondition_failed = 412,
161
    request_entity_too_large = 413,
162
    request_uri_too_long = 414,
163
    unsupported_media_type = 415,
164
    request_range_not_satisfiable = 416,
165
    expectation_failed = 417,
166
    im_a_teapot = 418,
167
    upgrade_required = 426,
168
    precondition_required = 428,
169
    too_many_requests = 429,
170
    request_header_fields_too_large = 431,
171
172
    internal_server_error = 500,
173
    not_implemented = 501,
174
    bad_gateway = 502,
175
    service_unavailable = 503,
176
    gateway_timeout = 504,
177
    http_version_not_supported = 505,
178
    not_extended = 510,
179
    network_authentication_required = 511
180
};
181
182
/// Given a status code value, return the default status message
183
/**
184
 * 
185
 * @param[in] code The HTTP status code to look up
186
 * @return A string representing the default status message for this code
187
 * @see websocketpp::http::status_code::value (list of valid codes)
188
 */
189
inline std::string get_string(value code) {
190
    switch (code) {
191
        case uninitialized:
192
            return "Uninitialized";
193
        case continue_code:
194
            return "Continue";
195
        case switching_protocols:
196
            return "Switching Protocols";
197
        case ok:
198
            return "OK";
199
        case created:
200
            return "Created";
201
        case accepted:
202
            return "Accepted";
203
        case non_authoritative_information:
204
            return "Non Authoritative Information";
205
        case no_content:
206
            return "No Content";
207
        case reset_content:
208
            return "Reset Content";
209
        case partial_content:
210
            return "Partial Content";
211
        case multiple_choices:
212
            return "Multiple Choices";
213
        case moved_permanently:
214
            return "Moved Permanently";
215
        case found:
216
            return "Found";
217
        case see_other:
218
            return "See Other";
219
        case not_modified:
220
            return "Not Modified";
221
        case use_proxy:
222
            return "Use Proxy";
223
        case temporary_redirect:
224
            return "Temporary Redirect";
225
        case bad_request:
226
            return "Bad Request";
227
        case unauthorized:
228
            return "Unauthorized";
229
        case payment_required:
230
            return "Payment Required";
231
        case forbidden:
232
            return "Forbidden";
233
        case not_found:
234
            return "Not Found";
235
        case method_not_allowed:
236
            return "Method Not Allowed";
237
        case not_acceptable:
238
            return "Not Acceptable";
239
        case proxy_authentication_required:
240
            return "Proxy Authentication Required";
241
        case request_timeout:
242
            return "Request Timeout";
243
        case conflict:
244
            return "Conflict";
245
        case gone:
246
            return "Gone";
247
        case length_required:
248
            return "Length Required";
249
        case precondition_failed:
250
            return "Precondition Failed";
251
        case request_entity_too_large:
252
            return "Request Entity Too Large";
253
        case request_uri_too_long:
254
            return "Request-URI Too Long";
255
        case unsupported_media_type:
256
            return "Unsupported Media Type";
257
        case request_range_not_satisfiable:
258
            return "Requested Range Not Satisfiable";
259
        case expectation_failed:
260
            return "Expectation Failed";
261
        case im_a_teapot:
262
            return "I'm a teapot";
263
        case upgrade_required:
264
            return "Upgrade Required";
265
        case precondition_required:
266
            return "Precondition Required";
267
        case too_many_requests:
268
            return "Too Many Requests";
269
        case request_header_fields_too_large:
270
            return "Request Header Fields Too Large";
271
        case internal_server_error:
272
            return "Internal Server Error";
273
        case not_implemented:
274
            return "Not Implemented";
275
        case bad_gateway:
276
            return "Bad Gateway";
277
        case service_unavailable:
278
            return "Service Unavailable";
279
        case gateway_timeout:
280
            return "Gateway Timeout";
281
        case http_version_not_supported:
282
            return "HTTP Version Not Supported";
283
        case not_extended:
284
            return "Not Extended";
285
        case network_authentication_required:
286
            return "Network Authentication Required";
287
        default:
288
            return "Unknown";
100
    }
289
    }
290
}
291
292
} // namespace status_code
101
293
102
    /// Is the character a non-token
294
/// An exception type specific to HTTP errors
103
    inline bool is_not_token_char(unsigned char c) {
295
/**
104
        return !header_token[c];
296
 * Includes additional details, such as HTTP error code,
297
 * HTTP error message, and a body to return with the HTTP
298
 * error response.
299
 */
300
class exception : public std::exception {
301
public:
302
    exception(const std::string& log_msg,
303
                status_code::value error_code,
304
                const std::string& error_msg = std::string(),
305
                const std::string& body = std::string())
306
        : m_msg(log_msg)
307
        , m_error_msg(error_msg)
308
        , m_body(body)
309
        , m_error_code(error_code) {}
310
311
    ~exception() throw() {}
312
313
    virtual const char* what() const throw() {
314
        return m_msg.c_str();
105
    }
315
    }
106
316
107
    /// Is the character whitespace
317
    std::string         m_msg;
108
    /**
318
    std::string         m_error_msg;
109
     * whitespace is space (32) or horizontal tab (9)
319
    std::string         m_body;
110
     */
320
    status_code::value  m_error_code;
111
    inline bool is_whitespace_char(unsigned char c) {
321
};
112
        return (c == 9 || c == 32);
322
323
324
/// HTTP parser errors
325
namespace error {
326
enum value {
327
    /// Catch-all error for http parser errors that don't fit in other
328
    /// categories
329
    general = 1,
330
331
    /// The specified data contains illegal characters for the context
332
    invalid_format,
333
334
    /// The header name specified contains illegal characters
335
    invalid_header_name,
336
337
    /// The body value is larger than the configured maximum size
338
    body_too_large,
339
340
    /// The transfer encoding is not supported
341
    unsupported_transfer_encoding,
342
343
    /// The transfer encoding is unknown
344
    unknown_transfer_encoding,
345
346
    /// A header line was missing a separator
347
    missing_header_separator,
348
349
    /// The request headers are larger than the configured maximum size
350
    request_header_fields_too_large,
351
352
    /// The request was missing some required values
353
    incomplete_request,
354
355
    /// The response status line was missing some required values
356
    incomplete_status_line,
357
358
    /// An istream read command returned with the bad flag set
359
    istream_bad,
360
361
    /// An istream read succeeded but read (and discarded) more bits from the
362
    /// stream than it needed
363
    istream_overread,
364
};
365
366
/// Get the HTTP status code associated with the error
367
inline status_code::value get_status_code(error::value value) {
368
    switch(value) {
369
        case error::general:
370
            return status_code::bad_request;
371
        case error::invalid_format:
372
            return status_code::bad_request;
373
        case error::invalid_header_name:
374
            return status_code::bad_request;
375
        case error::body_too_large:
376
            return status_code::request_entity_too_large;
377
        case error::unsupported_transfer_encoding:
378
            return status_code::internal_server_error;
379
        case error::unknown_transfer_encoding:
380
            return status_code::bad_request;
381
        case error::missing_header_separator:
382
            return status_code::bad_request;
383
        case error::request_header_fields_too_large:
384
            return status_code::request_header_fields_too_large;
385
        case error::incomplete_request:
386
            return status_code::bad_request;
387
        case error::incomplete_status_line:
388
            return status_code::bad_request;
389
        case error::istream_bad:
390
            return status_code::internal_server_error;
391
        case error::istream_overread:
392
            return status_code::internal_server_error;
393
        default:
394
            return status_code::bad_request;
113
    }
395
    }
396
}
114
397
115
    /// Is the character non-whitespace
398
/// HTTP parser error category
116
    inline bool is_not_whitespace_char(unsigned char c) {
399
class category : public lib::error_category {
117
        return (c != 9 && c != 32);
400
public:
401
    char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
402
        return "websocketpp.http";
118
    }
403
    }
119
404
120
    /// HTTP Status codes
405
    std::string message(int value) const {
121
    namespace status_code {
406
        switch(value) {
122
        enum value {
407
            case error::general:
123
            uninitialized = 0,
408
                return "Generic http parser error";
124
409
            case error::invalid_format:
125
            continue_code = 100,
410
                return "The specified data contains illegal characters for the context";
126
            switching_protocols = 101,
411
            case error::invalid_header_name:
127
412
                return "The header name specified contains illegal characters";
128
            ok = 200,
413
            case error::body_too_large:
129
            created = 201,
414
                return "The body value is larger than the configured maximum size";
130
            accepted = 202,
415
            case error::unsupported_transfer_encoding:
131
            non_authoritative_information = 203,
416
                return "The transfer encoding is not supported";
132
            no_content = 204,
417
            case error::unknown_transfer_encoding:
133
            reset_content = 205,
418
                return "The transfer encoding is unknown";
134
            partial_content = 206,
419
            case error::missing_header_separator:
135
420
                return "A header line was missing a separator";
136
            multiple_choices = 300,
421
            case error::request_header_fields_too_large:
137
            moved_permanently = 301,
422
                return "The request headers are larger than the configured maximum size";
138
            found = 302,
423
            case error::incomplete_request:
139
            see_other = 303,
424
                return "The request was missing some required values";
140
            not_modified = 304,
425
            case error::incomplete_status_line:
141
            use_proxy = 305,
426
                return "The response status line was missing some required values";
142
            temporary_redirect = 307,
427
            case error::istream_bad:
143
428
                return "An istream read command returned with the bad flag set";
144
            bad_request = 400,
429
            case error::istream_overread:
145
            unauthorized = 401,
430
                return "An istream read succeeded but read (and discarded) more bits from the stream than it needed";
146
            payment_required = 402,
431
            default:
147
            forbidden = 403,
432
                return "Unknown";
148
            not_found = 404,
149
            method_not_allowed = 405,
150
            not_acceptable = 406,
151
            proxy_authentication_required = 407,
152
            request_timeout = 408,
153
            conflict = 409,
154
            gone = 410,
155
            length_required = 411,
156
            precondition_failed = 412,
157
            request_entity_too_large = 413,
158
            request_uri_too_long = 414,
159
            unsupported_media_type = 415,
160
            request_range_not_satisfiable = 416,
161
            expectation_failed = 417,
162
            im_a_teapot = 418,
163
            upgrade_required = 426,
164
            precondition_required = 428,
165
            too_many_requests = 429,
166
            request_header_fields_too_large = 431,
167
168
            internal_server_error = 500,
169
            not_implemented = 501,
170
            bad_gateway = 502,
171
            service_unavailable = 503,
172
            gateway_timeout = 504,
173
            http_version_not_supported = 505,
174
            not_extended = 510,
175
            network_authentication_required = 511
176
        };
177
178
        // TODO: should this be inline?
179
        inline std::string get_string(value c) {
180
            switch (c) {
181
                case uninitialized:
182
                    return "Uninitialized";
183
                case continue_code:
184
                    return "Continue";
185
                case switching_protocols:
186
                    return "Switching Protocols";
187
                case ok:
188
                    return "OK";
189
                case created:
190
                    return "Created";
191
                case accepted:
192
                    return "Accepted";
193
                case non_authoritative_information:
194
                    return "Non Authoritative Information";
195
                case no_content:
196
                    return "No Content";
197
                case reset_content:
198
                    return "Reset Content";
199
                case partial_content:
200
                    return "Partial Content";
201
                case multiple_choices:
202
                    return "Multiple Choices";
203
                case moved_permanently:
204
                    return "Moved Permanently";
205
                case found:
206
                    return "Found";
207
                case see_other:
208
                    return "See Other";
209
                case not_modified:
210
                    return "Not Modified";
211
                case use_proxy:
212
                    return "Use Proxy";
213
                case temporary_redirect:
214
                    return "Temporary Redirect";
215
                case bad_request:
216
                    return "Bad Request";
217
                case unauthorized:
218
                    return "Unauthorized";
219
                case payment_required:
220
                    return "Payment Required";
221
                case forbidden:
222
                    return "Forbidden";
223
                case not_found:
224
                    return "Not Found";
225
                case method_not_allowed:
226
                    return "Method Not Allowed";
227
                case not_acceptable:
228
                    return "Not Acceptable";
229
                case proxy_authentication_required:
230
                    return "Proxy Authentication Required";
231
                case request_timeout:
232
                    return "Request Timeout";
233
                case conflict:
234
                    return "Conflict";
235
                case gone:
236
                    return "Gone";
237
                case length_required:
238
                    return "Length Required";
239
                case precondition_failed:
240
                    return "Precondition Failed";
241
                case request_entity_too_large:
242
                    return "Request Entity Too Large";
243
                case request_uri_too_long:
244
                    return "Request-URI Too Long";
245
                case unsupported_media_type:
246
                    return "Unsupported Media Type";
247
                case request_range_not_satisfiable:
248
                    return "Requested Range Not Satisfiable";
249
                case expectation_failed:
250
                    return "Expectation Failed";
251
                case im_a_teapot:
252
                    return "I'm a teapot";
253
                case upgrade_required:
254
                    return "Upgrade Required";
255
                case precondition_required:
256
                    return "Precondition Required";
257
                case too_many_requests:
258
                    return "Too Many Requests";
259
                case request_header_fields_too_large:
260
                    return "Request Header Fields Too Large";
261
                case internal_server_error:
262
                    return "Internal Server Error";
263
                case not_implemented:
264
                    return "Not Implemented";
265
                case bad_gateway:
266
                    return "Bad Gateway";
267
                case service_unavailable:
268
                    return "Service Unavailable";
269
                case gateway_timeout:
270
                    return "Gateway Timeout";
271
                case http_version_not_supported:
272
                    return "HTTP Version Not Supported";
273
                case not_extended:
274
                    return "Not Extended";
275
                case network_authentication_required:
276
                    return "Network Authentication Required";
277
                default:
278
                    return "Unknown";
279
            }
280
        }
433
        }
281
    }
434
    }
435
};
282
436
283
    class exception : public std::exception {
437
/// Get a reference to a static copy of the asio transport error category
284
    public:
438
inline lib::error_category const & get_category() {
285
        exception(const std::string& log_msg,
439
    static category instance;
286
                  status_code::value error_code,
440
    return instance;
287
                  const std::string& error_msg = std::string(),
441
}
288
                  const std::string& body = std::string())
289
          : m_msg(log_msg)
290
          , m_error_msg(error_msg)
291
          , m_body(body)
292
          , m_error_code(error_code) {}
293
442
294
        ~exception() throw() {}
443
/// Create an error code with the given value and the asio transport category
444
inline lib::error_code make_error_code(error::value e) {
445
    return lib::error_code(static_cast<int>(e), get_category());
446
}
447
448
} // namespace error
449
} // namespace http
450
} // namespace websocketpp
451
452
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
453
template<> struct is_error_code_enum<websocketpp::http::error::value>
454
{
455
    static bool const value = true;
456
};
457
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
295
458
296
        virtual const char* what() const throw() {
297
            return m_msg.c_str();
298
        }
299
459
300
        std::string         m_msg;
301
        std::string         m_error_msg;
302
        std::string         m_body;
303
        status_code::value  m_error_code;
304
    };
305
}
306
}
307
460
308
#endif // HTTP_CONSTANTS_HPP
461
#endif // HTTP_CONSTANTS_HPP
(-)websocketpp-zaphoyd/websocketpp/http/impl/parser.hpp (-25 / +57 lines)
Lines 38-48 namespace websocketpp { Link Here
38
namespace http {
38
namespace http {
39
namespace parser {
39
namespace parser {
40
40
41
inline void parser::set_version(std::string const & version) {
41
inline lib::error_code parser::set_version(std::string const & version) {
42
    // todo: validation?
42
    m_version = version;
43
    m_version = version;
44
45
    return lib::error_code();
43
}
46
}
44
47
45
inline std::string const & parser::get_header(std::string const & key) const {
48
inline std::string const & parser::get_header(std::string const & key) const {
49
    // This find is case insensitive due to the case insensitive comparator
50
    // templated into header_list.
46
    header_list::const_iterator h = m_headers.find(key);
51
    header_list::const_iterator h = m_headers.find(key);
47
52
48
    if (h == m_headers.end()) {
53
    if (h == m_headers.end()) {
Lines 64-74 inline bool parser::get_header_as_plist( Link Here
64
    return this->parse_parameter_list(it->second,out);
69
    return this->parse_parameter_list(it->second,out);
65
}
70
}
66
71
67
inline void parser::append_header(std::string const & key, std::string const &
72
inline lib::error_code parser::append_header(std::string const & key, std::string const &
68
    val)
73
    val)
69
{
74
{
70
    if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
75
    if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
71
        throw exception("Invalid header name",status_code::bad_request);
76
        return error::make_error_code(error::invalid_header_name);
72
    }
77
    }
73
78
74
    if (this->get_header(key).empty()) {
79
    if (this->get_header(key).empty()) {
Lines 76-107 inline void parser::append_header(std::s Link Here
76
    } else {
81
    } else {
77
        m_headers[key] += ", " + val;
82
        m_headers[key] += ", " + val;
78
    }
83
    }
84
    return lib::error_code();
79
}
85
}
80
86
81
inline void parser::replace_header(std::string const & key, std::string const &
87
inline lib::error_code parser::replace_header(std::string const & key, std::string const &
82
    val)
88
    val)
83
{
89
{
90
    if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
91
        return error::make_error_code(error::invalid_header_name);
92
    }
93
84
    m_headers[key] = val;
94
    m_headers[key] = val;
95
    return lib::error_code();
85
}
96
}
86
97
87
inline void parser::remove_header(std::string const & key) {
98
inline lib::error_code parser::remove_header(std::string const & key)
99
{
100
    if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) {
101
        return error::make_error_code(error::invalid_header_name);
102
    }
103
88
    m_headers.erase(key);
104
    m_headers.erase(key);
105
    return lib::error_code();
89
}
106
}
90
107
91
inline void parser::set_body(std::string const & value) {
108
inline lib::error_code parser::set_body(std::string const & value) {
109
    lib::error_code ec;
92
    if (value.size() == 0) {
110
    if (value.size() == 0) {
93
        remove_header("Content-Length");
111
        ec = remove_header("Content-Length");
112
        if (ec) { return ec; }
113
94
        m_body.clear();
114
        m_body.clear();
95
        return;
115
        return lib::error_code();
96
    }
116
    }
97
117
98
    // TODO: should this method respect the max size? If so how should errors
118
    if (value.size() > m_body_bytes_max) {
99
    // be indicated?
119
        return error::make_error_code(error::body_too_large);
120
    }
100
121
101
    std::stringstream len;
122
    std::stringstream len;
102
    len << value.size();
123
    len << value.size();
103
    replace_header("Content-Length", len.str());
124
    ec = replace_header("Content-Length", len.str());
125
    if (ec) { return ec; }
126
104
    m_body = value;
127
    m_body = value;
128
    return lib::error_code();
105
}
129
}
106
130
107
inline bool parser::parse_parameter_list(std::string const & in,
131
inline bool parser::parse_parameter_list(std::string const & in,
Lines 116-122 inline bool parser::parse_parameter_list Link Here
116
    return (it == in.begin());
140
    return (it == in.begin());
117
}
141
}
118
142
119
inline bool parser::prepare_body() {
143
inline bool parser::prepare_body(lib::error_code & ec) {
120
    if (!get_header("Content-Length").empty()) {
144
    if (!get_header("Content-Length").empty()) {
121
        std::string const & cl_header = get_header("Content-Length");
145
        std::string const & cl_header = get_header("Content-Length");
122
        char * end;
146
        char * end;
Lines 127-164 inline bool parser::prepare_body() { Link Here
127
        m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
151
        m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10);
128
        
152
        
129
        if (m_body_bytes_needed > m_body_bytes_max) {
153
        if (m_body_bytes_needed > m_body_bytes_max) {
130
            throw exception("HTTP message body too large",
154
            ec = error::make_error_code(error::body_too_large);
131
                status_code::request_entity_too_large);
155
            return false;
132
        }
156
        }
133
        
157
        
134
        m_body_encoding = body_encoding::plain;
158
        m_body_encoding = body_encoding::plain;
159
        ec = lib::error_code();
135
        return true;
160
        return true;
136
    } else if (get_header("Transfer-Encoding") == "chunked") {
161
    } else if (get_header("Transfer-Encoding") == "chunked") {
137
        // TODO
162
        // ec = error::make_error_code(error::unsupported_transfer_encoding);
163
        // TODO: support for chunked transfers? Is that too much HTTP logic?
138
        //m_body_encoding = body_encoding::chunked;
164
        //m_body_encoding = body_encoding::chunked;
139
        return false;
165
        return false;
140
    } else {
166
    } else {
167
        ec = lib::error_code();
141
        return false;
168
        return false;
142
    }
169
    }
143
}
170
}
144
171
145
inline size_t parser::process_body(char const * buf, size_t len) {
172
inline size_t parser::process_body(char const * buf, size_t len,
173
    lib::error_code & ec)
174
{
146
    if (m_body_encoding == body_encoding::plain) {
175
    if (m_body_encoding == body_encoding::plain) {
147
        size_t processed = (std::min)(m_body_bytes_needed,len);
176
        size_t processed = (std::min)(m_body_bytes_needed,len);
148
        m_body.append(buf,processed);
177
        m_body.append(buf,processed);
149
        m_body_bytes_needed -= processed;
178
        m_body_bytes_needed -= processed;
179
        ec = lib::error_code();
150
        return processed;
180
        return processed;
151
    } else if (m_body_encoding == body_encoding::chunked) {
181
    } else if (m_body_encoding == body_encoding::chunked) {
152
        // TODO: 
182
        ec = error::make_error_code(error::unsupported_transfer_encoding);
153
        throw exception("Unexpected body encoding",
183
        return 0;
154
            status_code::internal_server_error);
184
        // TODO: support for chunked transfers?
155
    } else {
185
    } else {
156
        throw exception("Unexpected body encoding",
186
        ec = error::make_error_code(error::unknown_transfer_encoding);
157
            status_code::internal_server_error);
187
        return 0;
158
    }
188
    }
159
}
189
}
160
190
161
inline void parser::process_header(std::string::iterator begin,
191
inline lib::error_code parser::process_header(std::string::iterator begin,
162
    std::string::iterator end)
192
    std::string::iterator end)
163
{
193
{
164
    std::string::iterator cursor = std::search(
194
    std::string::iterator cursor = std::search(
Lines 169-179 inline void parser::process_header(std:: Link Here
169
    );
199
    );
170
200
171
    if (cursor == end) {
201
    if (cursor == end) {
172
        throw exception("Invalid header line",status_code::bad_request);
202
        return error::make_error_code(error::body_too_large);
173
    }
203
    }
174
204
175
    append_header(strip_lws(std::string(begin,cursor)),
205
    // any error from append header represents our final error status
176
                  strip_lws(std::string(cursor+sizeof(header_separator)-1,end)));
206
    return append_header(
207
        strip_lws(std::string(begin,cursor)),
208
        strip_lws(std::string(cursor+sizeof(header_separator)-1,end)));
177
}
209
}
178
210
179
inline header_list const & parser::get_headers() const {
211
inline header_list const & parser::get_headers() const {
(-)websocketpp-zaphoyd/websocketpp/http/impl/request.hpp (-35 / +108 lines)
Lines 38-57 namespace websocketpp { Link Here
38
namespace http {
38
namespace http {
39
namespace parser {
39
namespace parser {
40
40
41
inline size_t request::consume(char const * buf, size_t len) {
41
inline size_t request::consume(char const * buf, size_t len, lib::error_code & ec)
42
    size_t bytes_processed;
42
{
43
    size_t bytes_processed = 0;
43
    
44
    
44
    if (m_ready) {return 0;}
45
    if (m_ready) {
46
        // the request is already complete. End immediately without reading.
47
        ec = lib::error_code();
48
        return 0;
49
    }
45
    
50
    
46
    if (m_body_bytes_needed > 0) {
51
    if (m_body_bytes_needed > 0) {
47
        bytes_processed = process_body(buf,len);
52
        // The headers are complete, but we are still expecting more body
53
        // bytes. Process body bytes.
54
        bytes_processed = process_body(buf, len, ec);
55
        if (ec) {
56
            return bytes_processed;
57
        }
58
59
        // if we have ready all the expected body bytes set the ready flag
48
        if (body_ready()) {
60
        if (body_ready()) {
49
            m_ready = true;
61
            m_ready = true;
50
        }
62
        }
51
        return bytes_processed;
63
        return bytes_processed;
52
    }
64
    }
53
65
54
    // copy new header bytes into buffer
66
    // at this point we have an incomplete request still waiting for headers
67
68
    // copy new candidate bytes into our local buffer. This buffer may have
69
    // leftover bytes from previous calls. Not all of these bytes are 
70
    // necessarily header bytes (they might be body or even data after this
71
    // request entirely for a keepalive request)
55
    m_buf->append(buf,len);
72
    m_buf->append(buf,len);
56
73
57
    // Search for delimiter in buf. If found read until then. If not read all
74
    // Search for delimiter in buf. If found read until then. If not read all
Lines 59-97 inline size_t request::consume(char cons Link Here
59
    std::string::iterator end;
76
    std::string::iterator end;
60
77
61
    for (;;) {
78
    for (;;) {
62
        // search for line delimiter
79
        // search for line delimiter in our local buffer
63
        end = std::search(
80
        end = std::search(
64
            begin,
81
            begin,
65
            m_buf->end(),
82
            m_buf->end(),
66
            header_delimiter,
83
            header_delimiter,
67
            header_delimiter+sizeof(header_delimiter)-1
84
            header_delimiter+sizeof(header_delimiter)-1
68
        );
85
        );
69
        
70
        m_header_bytes += (end-begin+sizeof(header_delimiter));
71
        
72
        if (m_header_bytes > max_header_size) {
73
            // exceeded max header size
74
            throw exception("Maximum header size exceeded.",
75
                status_code::request_header_fields_too_large);
76
        }
77
86
78
        if (end == m_buf->end()) {
87
        if (end == m_buf->end()) {
79
            // we are out of bytes. Discard the processed bytes and copy the
88
            // we didn't find the delimiter
80
            // remaining unprecessed bytes to the beginning of the buffer
89
81
            std::copy(begin,end,m_buf->begin());
90
            // check that the confirmed header bytes plus the outstanding
82
            m_buf->resize(static_cast<std::string::size_type>(end-begin));
91
            // candidate bytes do not put us over the header size limit.
83
            m_header_bytes -= m_buf->size();
92
            if (m_header_bytes + (end - begin) > max_header_size) {
93
                ec = error::make_error_code(error::request_header_fields_too_large);
94
                return 0;
95
            }
84
96
97
            // We are out of bytes but not over any limits yet. Discard the
98
            // processed bytes and copy the remaining unprecessed bytes to the 
99
            // beginning of the buffer in prep for another call to consume.
100
            
101
            // If there are no processed bytes in the buffer right now don't
102
            // copy the unprocessed ones over themselves.
103
            if (begin != m_buf->begin()) {
104
                std::copy(begin,end,m_buf->begin());
105
                m_buf->resize(static_cast<std::string::size_type>(end-begin));
106
            }
107
108
            ec = lib::error_code();
85
            return len;
109
            return len;
86
        }
110
        }
87
111
88
        //the range [begin,end) now represents a line to be processed.
112
        // at this point we have found a delimiter and the range [begin,end)
113
        // represents a line to be processed
114
115
        // update count of header bytes read so far
116
        m_header_bytes += (end-begin+sizeof(header_delimiter));
117
        
118
119
        if (m_header_bytes > max_header_size) {
120
            // This read exceeded max header size
121
            ec = error::make_error_code(error::request_header_fields_too_large);
122
            return 0;
123
        }
124
89
        if (end-begin == 0) {
125
        if (end-begin == 0) {
90
            // we got a blank line
126
            // we got a blank line, which indicates the end of the headers
127
128
            // If we never got a valid method or are missing a host header then
129
            // this request is invalid.
91
            if (m_method.empty() || get_header("Host").empty()) {
130
            if (m_method.empty() || get_header("Host").empty()) {
92
                throw exception("Incomplete Request",status_code::bad_request);
131
                ec = error::make_error_code(error::incomplete_request);
132
                return 0;
93
            }
133
            }
94
134
135
            // any bytes left over in the local buffer are bytes we didn't use.
136
            // When we report how many bytes we consumed we need to subtract
137
            // these so the caller knows that they need to be processed by some
138
            // other logic.
95
            bytes_processed = (
139
            bytes_processed = (
96
                len - static_cast<std::string::size_type>(m_buf->end()-end)
140
                len - static_cast<std::string::size_type>(m_buf->end()-end)
97
                    + sizeof(header_delimiter) - 1
141
                    + sizeof(header_delimiter) - 1
Lines 104-130 inline size_t request::consume(char cons Link Here
104
            // continue capturing content-length bytes and expose them as a 
148
            // continue capturing content-length bytes and expose them as a 
105
            // request body.
149
            // request body.
106
            
150
            
107
            if (prepare_body()) {
151
            bool need_more = prepare_body(ec);
108
                bytes_processed += process_body(buf+bytes_processed,len-bytes_processed);
152
            if (ec) {
153
                return 0;
154
            }
155
156
            if (need_more) {
157
                bytes_processed += process_body(buf+bytes_processed,len-bytes_processed,ec);
158
                if (ec) {
159
                    return 0;
160
                }
109
                if (body_ready()) {
161
                if (body_ready()) {
110
                    m_ready = true;
162
                    m_ready = true;
111
                }
163
                }
164
                ec = lib::error_code();
112
                return bytes_processed;
165
                return bytes_processed;
113
            } else {
166
            } else {
114
                m_ready = true;
167
                m_ready = true;
115
168
116
                // return number of bytes processed (starting bytes - bytes left)
169
                // return number of bytes processed (starting bytes - bytes left)
170
                ec = lib::error_code();
117
                return bytes_processed;
171
                return bytes_processed;
118
            }
172
            }
119
        } else {
173
        } else {
174
            // we got a line with content
120
            if (m_method.empty()) {
175
            if (m_method.empty()) {
121
                this->process(begin,end);
176
                // if we haven't found a method yet process this line as a first line
177
                ec = this->process(begin, end);
122
            } else {
178
            } else {
123
                this->process_header(begin,end);
179
                // this is a second (or later) line, process as a header
180
                ec = this->process_header(begin, end);
181
            }
182
            if (ec) {
183
                return 0;
124
            }
184
            }
125
        }
185
        }
126
186
187
        // if we got here it means there is another header line to read.
188
        // advance our cursor to the first character after the most recent
189
        // delimiter found.
127
        begin = end+(sizeof(header_delimiter)-1);
190
        begin = end+(sizeof(header_delimiter)-1);
191
128
    }
192
    }
129
}
193
}
130
194
Lines 148-187 inline std::string request::raw_head() c Link Here
148
    return ret.str();
212
    return ret.str();
149
}
213
}
150
214
151
inline void request::set_method(std::string const & method) {
215
inline lib::error_code request::set_method(std::string const & method)
216
{
152
    if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
217
    if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) {
153
        throw exception("Invalid method token.",status_code::bad_request);
218
        return error::make_error_code(error::invalid_format);
154
    }
219
    }
155
220
156
    m_method = method;
221
    m_method = method;
222
    return lib::error_code();
157
}
223
}
158
224
159
inline void request::set_uri(std::string const & uri) {
225
inline lib::error_code request::set_uri(std::string const & uri) {
160
    // TODO: validation?
226
    // TODO: validation?
161
    m_uri = uri;
227
    m_uri = uri;
228
229
    return lib::error_code();
162
}
230
}
163
231
164
inline void request::process(std::string::iterator begin, std::string::iterator
232
inline lib::error_code request::process(std::string::iterator begin, std::string::iterator
165
    end)
233
    end)
166
{
234
{
235
    lib::error_code ec;
236
167
    std::string::iterator cursor_start = begin;
237
    std::string::iterator cursor_start = begin;
168
    std::string::iterator cursor_end = std::find(begin,end,' ');
238
    std::string::iterator cursor_end = std::find(begin,end,' ');
169
239
170
    if (cursor_end == end) {
240
    if (cursor_end == end) {
171
        throw exception("Invalid request line1",status_code::bad_request);
241
        return error::make_error_code(error::incomplete_request);
172
    }
242
    }
173
243
174
    set_method(std::string(cursor_start,cursor_end));
244
    ec = set_method(std::string(cursor_start,cursor_end));
245
    if (ec) { return ec; }
175
246
176
    cursor_start = cursor_end+1;
247
    cursor_start = cursor_end+1;
177
    cursor_end = std::find(cursor_start,end,' ');
248
    cursor_end = std::find(cursor_start,end,' ');
178
249
179
    if (cursor_end == end) {
250
    if (cursor_end == end) {
180
        throw exception("Invalid request line2",status_code::bad_request);
251
        return error::make_error_code(error::incomplete_request);
181
    }
252
    }
182
253
183
    set_uri(std::string(cursor_start,cursor_end));
254
    ec = set_uri(std::string(cursor_start,cursor_end));
184
    set_version(std::string(cursor_end+1,end));
255
    if (ec) { return ec; }
256
257
    return set_version(std::string(cursor_end+1,end));
185
}
258
}
186
259
187
} // namespace parser
260
} // namespace parser
(-)websocketpp-zaphoyd/websocketpp/http/impl/response.hpp (-48 / +135 lines)
Lines 39-52 namespace websocketpp { Link Here
39
namespace http {
39
namespace http {
40
namespace parser {
40
namespace parser {
41
41
42
inline size_t response::consume(char const * buf, size_t len) {
42
inline size_t response::consume(char const * buf, size_t len, lib::error_code & ec) {
43
    if (m_state == DONE) {return 0;}
43
    if (m_state == DONE) {
44
        // the response is already complete. End immediately without reading.
45
        ec = lib::error_code();
46
        return 0;
47
    }
44
48
45
    if (m_state == BODY) {
49
    if (m_state == BODY) {
46
        return this->process_body(buf,len);
50
        // The headers are complete, but we are still expecting more body
51
        // bytes. Process body bytes.
52
        return this->process_body(buf,len,ec);
47
    }
53
    }
48
54
49
    // copy new header bytes into buffer
55
    // at this point we have an incomplete response still waiting for headers
56
57
    // copy new candidate bytes into our local buffer. This buffer may have
58
    // leftover bytes from previous calls. Not all of these bytes are 
59
    // necessarily header bytes (they might be body or even data after this
60
    // request entirely for a keepalive request)
50
    m_buf->append(buf,len);
61
    m_buf->append(buf,len);
51
62
52
    // Search for delimiter in buf. If found read until then. If not read all
63
    // Search for delimiter in buf. If found read until then. If not read all
Lines 63-142 inline size_t response::consume(char con Link Here
63
            header_delimiter + sizeof(header_delimiter) - 1
74
            header_delimiter + sizeof(header_delimiter) - 1
64
        );
75
        );
65
76
66
        m_header_bytes += (end-begin+sizeof(header_delimiter));
67
        
68
        if (m_header_bytes > max_header_size) {
69
            // exceeded max header size
70
            throw exception("Maximum header size exceeded.",
71
                status_code::request_header_fields_too_large);
72
        }
73
74
        if (end == m_buf->end()) {
77
        if (end == m_buf->end()) {
75
            // we are out of bytes. Discard the processed bytes and copy the
78
            // we didn't find the delimiter
76
            // remaining unprecessed bytes to the beginning of the buffer
79
77
            std::copy(begin,end,m_buf->begin());
80
            // check that the confirmed header bytes plus the outstanding
78
            m_buf->resize(static_cast<std::string::size_type>(end-begin));
81
            // candidate bytes do not put us over the header size limit.
82
            if (m_header_bytes + (end - begin) > max_header_size) {
83
                ec = error::make_error_code(error::request_header_fields_too_large);
84
                return 0;
85
            }
86
87
            // We are out of bytes but not over any limits yet. Discard the
88
            // processed bytes and copy the remaining unprecessed bytes to the 
89
            // beginning of the buffer in prep for another call to consume.
90
91
            // If there are no processed bytes in the buffer right now don't
92
            // copy the unprocessed ones over themselves.
93
            if (begin != m_buf->begin()) {
94
                std::copy(begin,end,m_buf->begin());
95
                m_buf->resize(static_cast<std::string::size_type>(end-begin));
96
            }
79
97
80
            m_read += len;
98
            m_read += len;
81
            m_header_bytes -= m_buf->size();
82
99
100
            ec = lib::error_code();
83
            return len;
101
            return len;
84
        }
102
        }
85
103
86
        //the range [begin,end) now represents a line to be processed.
104
        // at this point we have found a delimiter and the range [begin,end)
105
        // represents a line to be processed
106
107
        // update count of header bytes read so far
108
        m_header_bytes += (end-begin+sizeof(header_delimiter));
109
        
110
        if (m_header_bytes > max_header_size) {
111
            // This read exceeded max header size
112
            ec = error::make_error_code(error::request_header_fields_too_large);
113
            return 0;
114
        }
115
87
116
88
        if (end-begin == 0) {
117
        if (end-begin == 0) {
89
            // we got a blank line
118
            // we got a blank line, which indicates the end of the headers
119
120
            // If we are still looking for a response line then this request
121
            // is incomplete
90
            if (m_state == RESPONSE_LINE) {
122
            if (m_state == RESPONSE_LINE) {
91
                throw exception("Incomplete Request",status_code::bad_request);
123
                ec = error::make_error_code(error::incomplete_request);
124
                return 0;
92
            }
125
            }
93
126
94
            // TODO: grab content-length
127
            // TODO: grab content-length
95
            std::string length = get_header("Content-Length");
128
            std::string length = get_header("Content-Length");
96
129
97
            if (length.empty()) {
130
            if (length.empty()) {
98
                // no content length found, read indefinitely
131
                // no content length found, read indefinitely?
99
                m_read = 0;
132
                m_read = 0;
100
            } else {
133
            } else {
101
                std::istringstream ss(length);
134
                std::istringstream ss(length);
102
135
103
                if ((ss >> m_read).fail()) {
136
                if ((ss >> m_read).fail()) {
104
                    throw exception("Unable to parse Content-Length header",
137
                    ec = error::make_error_code(error::invalid_format);
105
                                    status_code::bad_request);
138
                    return 0;
106
                }
139
                }
107
            }
140
            }
108
141
142
            // transition state to reading the response body
109
            m_state = BODY;
143
            m_state = BODY;
110
144
111
            // calc header bytes processed (starting bytes - bytes left)
145
            // calculate how many bytes in the local buffer are bytes we didn't
146
            // use for the headers. 
112
            size_t read = (
147
            size_t read = (
113
                len - static_cast<std::string::size_type>(m_buf->end() - end)
148
                len - static_cast<std::string::size_type>(m_buf->end() - end)
114
                + sizeof(header_delimiter) - 1
149
                + sizeof(header_delimiter) - 1
115
            );
150
            );
116
151
117
            // if there were bytes left process them as body bytes
152
            // if there were bytes left process them as body bytes.
153
            // read is incremented with the number of body bytes processed.
154
            // It is possible that there are still some bytes not read. These
155
            // will be 'returned' to the caller by having the return value be
156
            // less than len.
118
            if (read < len) {
157
            if (read < len) {
119
                read += this->process_body(buf+read,(len-read));
158
                read += this->process_body(buf+read,(len-read),ec);
159
            }
160
            if (ec) {
161
                return 0;
120
            }
162
            }
121
163
122
            // frees memory used temporarily during header parsing
164
            // frees memory used temporarily during header parsing
123
            m_buf.reset();
165
            m_buf.reset();
124
166
167
            ec = lib::error_code();
125
            return read;
168
            return read;
126
        } else {
169
        } else {
170
            // we got a line 
127
            if (m_state == RESPONSE_LINE) {
171
            if (m_state == RESPONSE_LINE) {
128
                this->process(begin,end);
172
                ec = this->process(begin,end);
129
                m_state = HEADERS;
173
                m_state = HEADERS;
130
            } else {
174
            } else {
131
                this->process_header(begin,end);
175
                ec = this->process_header(begin,end);
176
            }
177
            if (ec) {
178
                return 0;
132
            }
179
            }
133
        }
180
        }
134
181
182
        // if we got here it means there is another header line to read.
183
        // advance our cursor to the first character after the most recent
184
        // delimiter found.
135
        begin = end+(sizeof(header_delimiter) - 1);
185
        begin = end+(sizeof(header_delimiter) - 1);
136
    }
186
    }
137
}
187
}
138
188
139
inline size_t response::consume(std::istream & s) {
189
inline size_t response::consume(std::istream & s, lib::error_code & ec) {
140
    char buf[istream_buffer];
190
    char buf[istream_buffer];
141
    size_t bytes_read;
191
    size_t bytes_read;
142
    size_t bytes_processed;
192
    size_t bytes_processed;
Lines 147-158 inline size_t response::consume(std::ist Link Here
147
        bytes_read = static_cast<size_t>(s.gcount());
197
        bytes_read = static_cast<size_t>(s.gcount());
148
198
149
        if (s.fail() || s.eof()) {
199
        if (s.fail() || s.eof()) {
150
            bytes_processed = this->consume(buf,bytes_read);
200
            bytes_processed = this->consume(buf,bytes_read,ec);
151
            total += bytes_processed;
201
            total += bytes_processed;
152
202
203
            if (ec) { return total; }
204
153
            if (bytes_processed != bytes_read) {
205
            if (bytes_processed != bytes_read) {
154
                // problem
206
                // we read more data from the stream than we needed for the
155
                break;
207
                // HTTP response. This extra data gets thrown away now.
208
                // Returning it to the caller is complicated so we alert the
209
                // caller at least. This whole method has been deprecated
210
                // because this convenience method doesnt really add useful
211
                // functionality to the library, but makes it difficult to
212
                // recover from error cases.
213
                ec = error::make_error_code(error::istream_overread);
214
                return total;
156
            }
215
            }
157
        } else if (s.bad()) {
216
        } else if (s.bad()) {
158
            // problem
217
            // problem
Lines 162-173 inline size_t response::consume(std::ist Link Here
162
            // the newline that was discarded, since our raw consume function
221
            // the newline that was discarded, since our raw consume function
163
            // expects the newline to be be there.
222
            // expects the newline to be be there.
164
            buf[bytes_read-1] = '\n';
223
            buf[bytes_read-1] = '\n';
165
            bytes_processed = this->consume(buf,bytes_read);
224
            bytes_processed = this->consume(buf,bytes_read,ec);
166
            total += bytes_processed;
225
            total += bytes_processed;
167
226
227
            if (ec) { return total; }
228
168
            if (bytes_processed != bytes_read) {
229
            if (bytes_processed != bytes_read) {
169
                // problem
230
                // we read more data from the stream than we needed for the
170
                break;
231
                // HTTP response. This extra data gets thrown away now.
232
                // Returning it to the caller is complicated so we alert the
233
                // caller at least. This whole method has been deprecated
234
                // because this convenience method doesnt really add useful
235
                // functionality to the library, but makes it difficult to
236
                // recover from error cases.
237
                ec = error::make_error_code(error::istream_overread);
238
                return total;
171
            }
239
            }
172
        }
240
        }
173
    }
241
    }
Lines 188-215 inline std::string response::raw() const Link Here
188
    return ret.str();
256
    return ret.str();
189
}
257
}
190
258
191
inline void response::set_status(status_code::value code) {
259
inline lib::error_code response::set_status(status_code::value code) {
192
    // TODO: validation?
260
    // In theory the type of status_code::value should prevent setting any
261
    // invalid values. Messages are canned and looked up and known to be
262
    // valid.
263
    // TODO: Is there anything else that would need validation here?
193
    m_status_code = code;
264
    m_status_code = code;
194
    m_status_msg = get_string(code);
265
    m_status_msg = get_string(code);
266
    return lib::error_code();
195
}
267
}
196
268
197
inline void response::set_status(status_code::value code, std::string const &
269
inline lib::error_code response::set_status(status_code::value code,
198
    msg)
270
    std::string const & msg)
199
{
271
{
200
    // TODO: validation?
272
    // In theory the type of status_code::value should prevent setting any
273
    // invalid values.
274
    // TODO: Is there anything else that would need validation here?
275
    // length or content of message?
276
    // Per RFC2616
277
    // Reason-Phrase  = *<TEXT, excluding CR, LF>
278
    // TEXT = = <any OCTET except CTLs,but including LWS>
279
    // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
280
    // LWS = [CRLF] 1*( SP | HT )
201
    m_status_code = code;
281
    m_status_code = code;
202
    m_status_msg = msg;
282
    m_status_msg = msg;
283
    return lib::error_code();
203
}
284
}
204
285
205
inline void response::process(std::string::iterator begin,
286
inline lib::error_code response::process(std::string::iterator begin,
206
    std::string::iterator end)
287
    std::string::iterator end)
207
{
288
{
208
    std::string::iterator cursor_start = begin;
289
    std::string::iterator cursor_start = begin;
209
    std::string::iterator cursor_end = std::find(begin,end,' ');
290
    std::string::iterator cursor_end = std::find(begin,end,' ');
210
291
211
    if (cursor_end == end) {
292
    if (cursor_end == end) {
212
        throw exception("Invalid response line",status_code::bad_request);
293
        return error::make_error_code(error::incomplete_status_line);
213
    }
294
    }
214
295
215
    set_version(std::string(cursor_start,cursor_end));
296
    set_version(std::string(cursor_start,cursor_end));
Lines 218-224 inline void response::process(std::strin Link Here
218
    cursor_end = std::find(cursor_start,end,' ');
299
    cursor_end = std::find(cursor_start,end,' ');
219
300
220
    if (cursor_end == end) {
301
    if (cursor_end == end) {
221
        throw exception("Invalid request line",status_code::bad_request);
302
        return error::make_error_code(error::incomplete_status_line);
222
    }
303
    }
223
304
224
    int code;
305
    int code;
Lines 226-243 inline void response::process(std::strin Link Here
226
    std::istringstream ss(std::string(cursor_start,cursor_end));
307
    std::istringstream ss(std::string(cursor_start,cursor_end));
227
308
228
    if ((ss >> code).fail()) {
309
    if ((ss >> code).fail()) {
229
        throw exception("Unable to parse response code",status_code::bad_request);
310
        return error::make_error_code(error::incomplete_status_line);
230
    }
311
    }
231
312
232
    set_status(status_code::value(code),std::string(cursor_end+1,end));
313
    // todo: validation of status code? Technically there are limits on what
314
    // status codes can be. Right now we follow Postel's law and check only
315
    // that the valid is an integer and let the next layer decide what to do.
316
    // Is this reasonable or should we be more aggressive?
317
318
    // validation of the status message will pass through
319
    return set_status(status_code::value(code),std::string(cursor_end+1,end));
233
}
320
}
234
321
235
inline size_t response::process_body(char const * buf, size_t len) {
322
inline size_t response::process_body(char const * buf, size_t len, lib::error_code & ec) {
236
    // If no content length was set then we read forever and never set m_ready
323
    // If no content length was set then we read forever and never set m_ready
237
    if (m_read == 0) {
324
    if (m_read == 0) {
238
        //m_body.append(buf,len);
239
        //return len;
240
        m_state = DONE;
325
        m_state = DONE;
326
        ec = lib::error_code();
241
        return 0;
327
        return 0;
242
    }
328
    }
243
329
Lines 256-261 inline size_t response::process_body(cha Link Here
256
342
257
    m_body.append(buf,to_read);
343
    m_body.append(buf,to_read);
258
    m_read -= to_read;
344
    m_read -= to_read;
345
    ec = lib::error_code();
259
    return to_read;
346
    return to_read;
260
}
347
}
261
348
(-)websocketpp-zaphoyd/websocketpp/http/parser.hpp (-18 / +37 lines)
Lines 417-428 public: Link Here
417
     * @todo Does this method need any validation?
417
     * @todo Does this method need any validation?
418
     *
418
     *
419
     * @param [in] version The value to set the HTTP version to.
419
     * @param [in] version The value to set the HTTP version to.
420
     * @return A status code describing the outcome of the operation.
420
     */
421
     */
421
    void set_version(std::string const & version);
422
    lib::error_code set_version(std::string const & version);
422
423
423
    /// Get the value of an HTTP header
424
    /// Get the value of an HTTP header
424
    /**
425
    /**
425
     * @todo Make this method case insensitive.
426
     * Note: per HTTP specs header values are compared case insensitively.
426
     *
427
     *
427
     * @param [in] key The name/key of the header to get.
428
     * @param [in] key The name/key of the header to get.
428
     * @return The value associated with the given HTTP header key.
429
     * @return The value associated with the given HTTP header key.
Lines 457-472 public: Link Here
457
     * indicated value. If a header with the name `key` already exists, `val`
458
     * indicated value. If a header with the name `key` already exists, `val`
458
     * will be appended to the existing value.
459
     * will be appended to the existing value.
459
     *
460
     *
460
     * @todo Make this method case insensitive.
461
     * Note: per HTTP specs header values are compared case insensitively.
462
     * 
461
     * @todo Should there be any restrictions on which keys are allowed?
463
     * @todo Should there be any restrictions on which keys are allowed?
462
     * @todo Exception free varient
463
     *
464
     *
464
     * @see replace_header
465
     * @see replace_header
465
     *
466
     *
467
     * @since 0.9.0 (return value added, exceptions removed)
468
     * 
466
     * @param [in] key The name/key of the header to append to.
469
     * @param [in] key The name/key of the header to append to.
467
     * @param [in] val The value to append.
470
     * @param [in] val The value to append.
471
     * @return A status code describing the outcome of the operation.
468
     */
472
     */
469
    void append_header(std::string const & key, std::string const & val);
473
    lib::error_code append_header(std::string const & key, std::string const & val);
470
474
471
    /// Set a value for an HTTP header, replacing an existing value
475
    /// Set a value for an HTTP header, replacing an existing value
472
    /**
476
    /**
Lines 474-500 public: Link Here
474
     * indicated value. If a header with the name `key` already exists, `val`
478
     * indicated value. If a header with the name `key` already exists, `val`
475
     * will replace the existing value.
479
     * will replace the existing value.
476
     *
480
     *
477
     * @todo Make this method case insensitive.
481
     * Note: per HTTP specs header values are compared case insensitively.
478
     * @todo Should there be any restrictions on which keys are allowed?
479
     * @todo Exception free varient
480
     *
482
     *
481
     * @see append_header
483
     * @see append_header
482
     *
484
     *
485
     * @since 0.9.0 (return value added)
486
     * 
483
     * @param [in] key The name/key of the header to append to.
487
     * @param [in] key The name/key of the header to append to.
484
     * @param [in] val The value to append.
488
     * @param [in] val The value to append.
489
     * @return A status code describing the outcome of the operation.
485
     */
490
     */
486
    void replace_header(std::string const & key, std::string const & val);
491
    lib::error_code replace_header(std::string const & key, std::string const & val);
487
492
488
    /// Remove a header from the parser
493
    /// Remove a header from the parser
489
    /**
494
    /**
490
     * Removes the header entirely from the parser. This is different than
495
     * Removes the header entirely from the parser. This is different than
491
     * setting the value of the header to blank.
496
     * setting the value of the header to blank.
492
     *
497
     *
493
     * @todo Make this method case insensitive.
498
     * Note: per HTTP specs header values are compared case insensitively.
494
     *
499
     *
500
     * @since 0.9.0 (return value added)
501
     * 
495
     * @param [in] key The name/key of the header to remove.
502
     * @param [in] key The name/key of the header to remove.
503
     * @return A status code describing the outcome of the operation.
496
     */
504
     */
497
    void remove_header(std::string const & key);
505
    lib::error_code remove_header(std::string const & key);
506
507
    // todo exception varients for the above 3?
498
508
499
    /// Get HTTP body
509
    /// Get HTTP body
500
    /**
510
    /**
Lines 513-521 public: Link Here
513
     * value. If you want the Content-Length header to be something else, do so
523
     * value. If you want the Content-Length header to be something else, do so
514
     * via replace_header("Content-Length") after calling set_body()
524
     * via replace_header("Content-Length") after calling set_body()
515
     *
525
     *
526
     * @since 0.9.0 (return value added)
527
     * 
516
     * @param value String data to include as the body content.
528
     * @param value String data to include as the body content.
529
     * @return A status code describing the outcome of the operation.
517
     */
530
     */
518
    void set_body(std::string const & value);
531
    lib::error_code set_body(std::string const & value);
519
532
520
    /// Get body size limit
533
    /// Get body size limit
521
    /**
534
    /**
Lines 554-565 public: Link Here
554
protected:
567
protected:
555
    /// Process a header line
568
    /// Process a header line
556
    /**
569
    /**
557
     * @todo Update this method to be exception free.
570
     * @since 0.9.0 (return value added, exceptions removed)
558
     *
571
     * 
559
     * @param [in] begin An iterator to the beginning of the sequence.
572
     * @param [in] begin An iterator to the beginning of the sequence.
560
     * @param [in] end An iterator to the end of the sequence.
573
     * @param [in] end An iterator to the end of the sequence.
574
     * @return A status code describing the outcome of the operation.
561
     */
575
     */
562
    void process_header(std::string::iterator begin, std::string::iterator end);
576
    lib::error_code process_header(std::string::iterator begin,
577
        std::string::iterator end);
563
578
564
    /// Prepare the parser to begin parsing body data
579
    /// Prepare the parser to begin parsing body data
565
    /**
580
    /**
Lines 570-592 protected: Link Here
570
     *
585
     *
571
     * Must not be called until after all headers have been processed.
586
     * Must not be called until after all headers have been processed.
572
     *
587
     *
573
     * @since 0.5.0
588
     * @since 0.5.0 (no parameters)
589
     * @since 0.9.0 (ec parameter added, exceptions removed)
574
     *
590
     *
591
     * @param [out] ec A status code describing the outcome of the operation.
575
     * @return True if more bytes are needed to load the body, false otherwise.
592
     * @return True if more bytes are needed to load the body, false otherwise.
576
     */
593
     */
577
    bool prepare_body();
594
    bool prepare_body(lib::error_code & ec);
578
595
579
    /// Process body data
596
    /// Process body data
580
    /**
597
    /**
581
     * Parses body data.
598
     * Parses body data.
582
     *
599
     *
583
     * @since 0.5.0
600
     * @since 0.5.0
601
     * @since 0.9.0 (ec parameter added, exceptions removed)
584
     *
602
     *
585
     * @param [in] begin An iterator to the beginning of the sequence.
603
     * @param [in] begin An iterator to the beginning of the sequence.
586
     * @param [in] end An iterator to the end of the sequence.
604
     * @param [in] end An iterator to the end of the sequence.
605
     * @param [out] ec A status code describing the outcome of the operation.
587
     * @return The number of bytes processed
606
     * @return The number of bytes processed
588
     */
607
     */
589
    size_t process_body(char const * buf, size_t len);
608
    size_t process_body(char const * buf, size_t len, lib::error_code & ec);
590
609
591
    /// Check if the parser is done parsing the body
610
    /// Check if the parser is done parsing the body
592
    /**
611
    /**
(-)websocketpp-zaphoyd/websocketpp/http/request.hpp (-8 / +34 lines)
Lines 72-82 public: Link Here
72
     * error reasons include malformed requests, incomplete requests, and max
72
     * error reasons include malformed requests, incomplete requests, and max
73
     * header size being reached.
73
     * header size being reached.
74
     *
74
     *
75
     * @param buf Pointer to byte buffer
75
     * @since 0.9.0 Added ec parameter
76
     * @param len Size of byte buffer
76
     * 
77
     * @param [in] buf Pointer to byte buffer
78
     * @param [in] len Size of byte buffer
79
     * @param [out] ec A status code describing the outcome of the operation.
77
     * @return Number of bytes processed.
80
     * @return Number of bytes processed.
78
     */
81
     */
79
    size_t consume(char const * buf, size_t len);
82
    size_t consume(char const * buf, size_t len, lib::error_code & ec);
80
83
81
    /// Returns whether or not the request is ready for reading.
84
    /// Returns whether or not the request is ready for reading.
82
    bool ready() const {
85
    bool ready() const {
Lines 89-104 public: Link Here
89
    /// Returns the raw request headers only (similar to an HTTP HEAD request)
92
    /// Returns the raw request headers only (similar to an HTTP HEAD request)
90
    std::string raw_head() const;
93
    std::string raw_head() const;
91
94
92
    /// Set the HTTP method. Must be a valid HTTP token
95
    /// Set the HTTP method.
93
    void set_method(std::string const & method);
96
    /**
97
     * Must be a valid HTTP token
98
     *
99
     * @since 0.9.0 added return value and removed exception
100
     * 
101
     * @param [in] method The value to set the method to.
102
     * @return A status code describing the outcome of the operation.
103
     */
104
    lib::error_code set_method(std::string const & method);
94
105
95
    /// Return the request method
106
    /// Return the request method
96
    std::string const & get_method() const {
107
    std::string const & get_method() const {
97
        return m_method;
108
        return m_method;
98
    }
109
    }
99
110
100
    /// Set the HTTP uri. Must be a valid HTTP uri
111
    /// Set the HTTP uri.
101
    void set_uri(std::string const & uri);
112
    /**
113
     * Must be a valid HTTP uri
114
     * 
115
     * @since 0.9.0 Return value added
116
     * 
117
     * @param uri The URI to set
118
     * @return A status code describing the outcome of the operation.
119
     */
120
    lib::error_code set_uri(std::string const & uri);
102
121
103
    /// Return the requested URI
122
    /// Return the requested URI
104
    std::string const & get_uri() const {
123
    std::string const & get_uri() const {
Lines 107-113 public: Link Here
107
126
108
private:
127
private:
109
    /// Helper function for message::consume. Process request line
128
    /// Helper function for message::consume. Process request line
110
    void process(std::string::iterator begin, std::string::iterator end);
129
    /**
130
     * @since 0.9.0 (ec parameter added, exceptions removed)
131
     *
132
     * @param [in] begin An iterator to the beginning of the sequence.
133
     * @param [in] end An iterator to the end of the sequence.
134
     * @return A status code describing the outcome of the operation.
135
     */
136
    lib::error_code process(std::string::iterator begin, std::string::iterator end);
111
137
112
    lib::shared_ptr<std::string>    m_buf;
138
    lib::shared_ptr<std::string>    m_buf;
113
    std::string                     m_method;
139
    std::string                     m_method;
(-)websocketpp-zaphoyd/websocketpp/http/response.hpp (-20 / +53 lines)
Lines 77-97 public: Link Here
77
     * the ready flag will be set. Further calls to consume once ready will be
77
     * the ready flag will be set. Further calls to consume once ready will be
78
     * ignored.
78
     * ignored.
79
     *
79
     *
80
     * Consume will throw an http::exception in the case of an error. Typical
80
     * As of 0.9.0, consume will return a status code describing the output of 
81
     * error reasons include malformed responses, incomplete responses, and max
81
     * the operation. Earlier versions threw an `http::exception`. The status
82
     * header size being reached.
82
     * code will be zero/default constructed on success and non-zero on error.
83
     *
83
     * Typical error reasons include malformed responses, incomplete responses,
84
     * @param buf Pointer to byte buffer
84
     * and max header size being reached.
85
     * @param len Size of byte buffer
85
     *
86
     * @since 0.9.0 Added ec parameter
87
     *
88
     * @param [in] buf Pointer to byte buffer
89
     * @param [in] len Size of byte buffer
90
     * @param [out] ec A status code describing the outcome of the operation.
86
     * @return Number of bytes processed.
91
     * @return Number of bytes processed.
87
     */
92
     */
88
    size_t consume(char const * buf, size_t len);
93
    size_t consume(char const * buf, size_t len, lib::error_code & ec);
89
94
90
    /// Process bytes in the input buffer (istream version)
95
    /// Process bytes in the input buffer (istream version)
91
    /**
96
    /**
92
     * Process bytes from istream s. Returns the number of bytes processed. 
97
     * Process bytes from istream s. Returns the number of bytes processed. 
93
     * Bytes left unprocessed means bytes left over after the final header
94
     * delimiters.
95
     *
98
     *
96
     * Consume is a streaming processor. It may be called multiple times on one
99
     * Consume is a streaming processor. It may be called multiple times on one
97
     * response and the full headers need not be available before processing can
100
     * response and the full headers need not be available before processing can
Lines 99-113 public: Link Here
99
     * the ready flag will be set. Further calls to consume once ready will be
102
     * the ready flag will be set. Further calls to consume once ready will be
100
     * ignored.
103
     * ignored.
101
     *
104
     *
102
     * Consume will throw an http::exception in the case of an error. Typical
105
     * As of 0.9.0, consume will return a status code describing the output of 
103
     * error reasons include malformed responses, incomplete responses, and max
106
     * the operation. Earlier versions threw an `http::exception`. The status
104
     * header size being reached.
107
     * code will be zero/default constructed on success and non-zero on error.
108
     * Typical error reasons include malformed responses, incomplete responses,
109
     * and max header size being reached.
110
     *
111
     * **WARNING:** If not all the bytes were needed to complete the HTTP
112
     * request those bytes will still be removed from the istream and discarded.
113
     * If this happens an error `istream_overread` will be returned. This means
114
     * that the response read was successful but that some unrelated data was
115
     * lost. If you don't care about these bytes you can ignore the error.
116
     *
117
     * If there is an HTTP processing error and an istream overread in the same
118
     * call only the HTTP processing error will be returned. 
119
     *
120
     * If you might need bytes after the header in the istream you should NOT
121
     * use this wrapper and instead read data out of the istream directly and
122
     * pass it to consume(char const *, size_t, lib::error_code). This method
123
     * allows you to retain overread data.
124
     * 
125
     * @deprecated 0.9.0 This overload is dangerous in that it can overread the
126
     * stream and there isn't a good way to recover bytes lost this way. As of
127
     * 0.9.0 an error is raised when this situation happens, but generally, it
128
     * would be better for the calling application to read the stream itself and
129
     * call consume(char const *, size_t, lib::error_code) instead which provides
130
     * a better method of identifying and recovering from overreads.
131
     *
132
     * @since 0.9.0 Added ec parameter
105
     *
133
     *
106
     * @param buf Pointer to byte buffer
134
     * @param s pointer to an istream to read from
107
     * @param len Size of byte buffer
135
     * @param [out] ec A status code describing the outcome of the operation.
108
     * @return Number of bytes processed.
136
     * @return Number of bytes processed.
109
     */
137
     */
110
    size_t consume(std::istream & s);
138
    size_t consume(std::istream & s, lib::error_code & ec);
111
139
112
    /// Returns true if the response is ready.
140
    /// Returns true if the response is ready.
113
    /**
141
    /**
Lines 132-141 public: Link Here
132
     * use set_status(status_code::value,std::string) overload to set both
160
     * use set_status(status_code::value,std::string) overload to set both
133
     * values explicitly.
161
     * values explicitly.
134
     *
162
     *
163
     * @since 0.9.0 Added return value
164
     *
135
     * @param code Code to set
165
     * @param code Code to set
136
     * @param msg Message to set
166
     * @return A status code describing the outcome of the operation.
137
     */
167
     */
138
    void set_status(status_code::value code);
168
    lib::error_code set_status(status_code::value code);
139
169
140
    /// Set response status code and message
170
    /// Set response status code and message
141
    /**
171
    /**
Lines 143-152 public: Link Here
143
     * use set_status(status_code::value) to set the code and have the standard
173
     * use set_status(status_code::value) to set the code and have the standard
144
     * message be automatically set.
174
     * message be automatically set.
145
     *
175
     *
176
     * @since 0.9.0 Added return value
177
     *
146
     * @param code Code to set
178
     * @param code Code to set
147
     * @param msg Message to set
179
     * @param msg Message to set
180
     * @return A status code describing the outcome of the operation.
148
     */
181
     */
149
    void set_status(status_code::value code, std::string const & msg);
182
    lib::error_code set_status(status_code::value code, std::string const & msg);
150
183
151
    /// Return the response status code
184
    /// Return the response status code
152
    status_code::value get_status_code() const {
185
    status_code::value get_status_code() const {
Lines 159-168 public: Link Here
159
    }
192
    }
160
private:
193
private:
161
    /// Helper function for consume. Process response line
194
    /// Helper function for consume. Process response line
162
    void process(std::string::iterator begin, std::string::iterator end);
195
    lib::error_code process(std::string::iterator begin, std::string::iterator end);
163
196
164
    /// Helper function for processing body bytes
197
    /// Helper function for processing body bytes
165
    size_t process_body(char const * buf, size_t len);
198
    size_t process_body(char const * buf, size_t len, lib::error_code & ec);
166
199
167
    enum state {
200
    enum state {
168
        RESPONSE_LINE = 0,
201
        RESPONSE_LINE = 0,
(-)websocketpp-zaphoyd/websocketpp/impl/connection_impl.hpp (-51 / +197 lines)
Lines 220-225 void connection<config>::ping(std::strin Link Here
220
    ec = lib::error_code();
220
    ec = lib::error_code();
221
}
221
}
222
222
223
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
223
template<typename config>
224
template<typename config>
224
void connection<config>::ping(std::string const & payload) {
225
void connection<config>::ping(std::string const & payload) {
225
    lib::error_code ec;
226
    lib::error_code ec;
Lines 228-233 void connection<config>::ping(std::strin Link Here
228
        throw exception(ec);
229
        throw exception(ec);
229
    }
230
    }
230
}
231
}
232
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
231
233
232
template<typename config>
234
template<typename config>
233
void connection<config>::handle_pong_timeout(std::string payload,
235
void connection<config>::handle_pong_timeout(std::string payload,
Lines 291-296 void connection<config>::pong(std::strin Link Here
291
    ec = lib::error_code();
293
    ec = lib::error_code();
292
}
294
}
293
295
296
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
294
template<typename config>
297
template<typename config>
295
void connection<config>::pong(std::string const & payload) {
298
void connection<config>::pong(std::string const & payload) {
296
    lib::error_code ec;
299
    lib::error_code ec;
Lines 299-304 void connection<config>::pong(std::strin Link Here
299
        throw exception(ec);
302
        throw exception(ec);
300
    }
303
    }
301
}
304
}
305
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
302
306
303
template <typename config>
307
template <typename config>
304
void connection<config>::close(close::status::value const code,
308
void connection<config>::close(close::status::value const code,
Lines 322-327 void connection<config>::close(close::st Link Here
322
    ec = this->send_close_frame(code,tr,false,close::status::terminal(code));
326
    ec = this->send_close_frame(code,tr,false,close::status::terminal(code));
323
}
327
}
324
328
329
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
325
template<typename config>
330
template<typename config>
326
void connection<config>::close(close::status::value const code,
331
void connection<config>::close(close::status::value const code,
327
    std::string const & reason)
332
    std::string const & reason)
Lines 332-337 void connection<config>::close(close::st Link Here
332
        throw exception(ec);
337
        throw exception(ec);
333
    }
338
    }
334
}
339
}
340
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
335
341
336
/// Trigger the on_interrupt handler
342
/// Trigger the on_interrupt handler
337
/**
343
/**
Lines 474-479 void connection<config>::add_subprotocol Link Here
474
    m_requested_subprotocols.push_back(value);
480
    m_requested_subprotocols.push_back(value);
475
}
481
}
476
482
483
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
477
template <typename config>
484
template <typename config>
478
void connection<config>::add_subprotocol(std::string const & value) {
485
void connection<config>::add_subprotocol(std::string const & value) {
479
    lib::error_code ec;
486
    lib::error_code ec;
Lines 482-487 void connection<config>::add_subprotocol Link Here
482
        throw exception(ec);
489
        throw exception(ec);
483
    }
490
    }
484
}
491
}
492
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
485
493
486
494
487
template <typename config>
495
template <typename config>
Lines 510-517 void connection<config>::select_subproto Link Here
510
    }
518
    }
511
519
512
    m_subprotocol = value;
520
    m_subprotocol = value;
521
    ec = lib::error_code();
513
}
522
}
514
523
524
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
515
template <typename config>
525
template <typename config>
516
void connection<config>::select_subprotocol(std::string const & value) {
526
void connection<config>::select_subprotocol(std::string const & value) {
517
    lib::error_code ec;
527
    lib::error_code ec;
Lines 520-525 void connection<config>::select_subproto Link Here
520
        throw exception(ec);
530
        throw exception(ec);
521
    }
531
    }
522
}
532
}
533
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
523
534
524
535
525
template <typename config>
536
template <typename config>
Lines 540-651 connection<config>::get_response_header( Link Here
540
    return m_response.get_header(key);
551
    return m_response.get_header(key);
541
}
552
}
542
553
543
// TODO: EXCEPTION_FREE
554
template <typename config>
555
void connection<config>::set_status(http::status_code::value code,
556
    lib::error_code & ec)
557
{
558
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
559
        ec = error::make_error_code(error::invalid_state);
560
        return;
561
    }
562
    ec = m_response.set_status(code);
563
}
564
565
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
544
template <typename config>
566
template <typename config>
545
void connection<config>::set_status(http::status_code::value code)
567
void connection<config>::set_status(http::status_code::value code)
546
{
568
{
569
    lib::error_code ec;
570
    this->set_status(code, ec);
571
    if (ec) {
572
        throw exception("Call to set_status from invalid state", ec);
573
    }
574
}
575
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
576
577
template <typename config>
578
void connection<config>::set_status(http::status_code::value code,
579
    std::string const & msg, lib::error_code & ec)
580
{
547
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
581
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
548
        throw exception("Call to set_status from invalid state",
582
        ec = error::make_error_code(error::invalid_state);
549
                      error::make_error_code(error::invalid_state));
583
        return;
550
    }
584
    }
551
    m_response.set_status(code);
585
586
    ec = m_response.set_status(code,msg);
552
}
587
}
553
588
554
// TODO: EXCEPTION_FREE
589
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
555
template <typename config>
590
template <typename config>
556
void connection<config>::set_status(http::status_code::value code,
591
void connection<config>::set_status(http::status_code::value code,
557
    std::string const & msg)
592
    std::string const & msg)
558
{
593
{
594
    lib::error_code ec;
595
    this->set_status(code, msg);
596
    if (ec) {
597
        throw exception("Call to set_status from invalid state", ec);
598
    }
599
}
600
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
601
602
template <typename config>
603
void connection<config>::set_body(std::string const & value,
604
    lib::error_code & ec)
605
{
559
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
606
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
560
        throw exception("Call to set_status from invalid state",
607
        ec = error::make_error_code(error::invalid_state);
561
                      error::make_error_code(error::invalid_state));
608
        return;
562
    }
609
    }
563
610
564
    m_response.set_status(code,msg);
611
    ec = m_response.set_body(value);
565
}
612
}
566
613
567
// TODO: EXCEPTION_FREE
614
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
568
template <typename config>
615
template <typename config>
569
void connection<config>::set_body(std::string const & value) {
616
void connection<config>::set_body(std::string const & value) {
617
    lib::error_code ec;
618
    this->set_body(value, ec);
619
    if (ec) {
620
        throw exception("Call to set_body from invalid state", ec);
621
    }
622
}
623
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
624
625
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
626
template <typename config>
627
void connection<config>::set_body(std::string && value,
628
    lib::error_code & ec)
629
{
570
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
630
    if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
571
        throw exception("Call to set_status from invalid state",
631
        ec = error::make_error_code(error::invalid_state);
572
                      error::make_error_code(error::invalid_state));
632
        return;
573
    }
633
    }
574
634
575
    m_response.set_body(value);
635
    ec = m_response.set_body(std::move(value));
576
}
636
}
577
637
578
// TODO: EXCEPTION_FREE
638
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
639
template <typename config>
640
void connection<config>::set_body(std::string && value) {
641
    lib::error_code ec;
642
    this->set_body(std::move(value), ec);
643
    if (ec) {
644
        throw exception("Call to set_body from invalid state", ec);
645
    }
646
}
647
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
648
#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
649
579
template <typename config>
650
template <typename config>
580
void connection<config>::append_header(std::string const & key,
651
void connection<config>::append_header(std::string const & key,
581
    std::string const & val)
652
    std::string const & val, lib::error_code & ec)
582
{
653
{
583
    if (m_is_server) {
654
    if (m_is_server) {
584
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
655
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
585
            // we are setting response headers for an incoming server connection
656
            // we are setting response headers for an incoming server connection
586
            m_response.append_header(key,val);
657
            ec = m_response.append_header(key, val);
587
        } else {
658
        } else {
588
            throw exception("Call to append_header from invalid state",
659
            ec = error::make_error_code(error::invalid_state);
589
                      error::make_error_code(error::invalid_state));
590
        }
660
        }
591
    } else {
661
    } else {
592
        if (m_internal_state == istate::USER_INIT) {
662
        if (m_internal_state == istate::USER_INIT) {
593
            // we are setting initial headers for an outgoing client connection
663
            // we are setting initial headers for an outgoing client connection
594
            m_request.append_header(key,val);
664
            ec = m_request.append_header(key, val);
595
        } else {
665
        } else {
596
            throw exception("Call to append_header from invalid state",
666
            ec = error::make_error_code(error::invalid_state);
597
                      error::make_error_code(error::invalid_state));
598
        }
667
        }
599
    }
668
    }
600
}
669
}
601
670
602
// TODO: EXCEPTION_FREE
671
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
603
template <typename config>
672
template <typename config>
604
void connection<config>::replace_header(std::string const & key,
673
void connection<config>::append_header(std::string const & key,
605
    std::string const & val)
674
    std::string const & val)
606
{
675
{
676
    lib::error_code ec;
677
    this->append_header(key, val, ec);
678
    if (ec) {
679
        throw exception("Call to append_header from invalid state", ec);
680
    }
681
}
682
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
683
684
template <typename config>
685
void connection<config>::replace_header(std::string const & key,
686
    std::string const & val, lib::error_code & ec)
687
{
607
    if (m_is_server) {
688
    if (m_is_server) {
608
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
689
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
609
            // we are setting response headers for an incoming server connection
690
            // we are setting response headers for an incoming server connection
610
            m_response.replace_header(key,val);
691
            ec = m_response.replace_header(key, val);
611
        } else {
692
        } else {
612
            throw exception("Call to replace_header from invalid state",
693
            ec = error::make_error_code(error::invalid_state);
613
                        error::make_error_code(error::invalid_state));
614
        }
694
        }
615
    } else {
695
    } else {
616
        if (m_internal_state == istate::USER_INIT) {
696
        if (m_internal_state == istate::USER_INIT) {
617
            // we are setting initial headers for an outgoing client connection
697
            // we are setting initial headers for an outgoing client connection
618
            m_request.replace_header(key,val);
698
            ec = m_request.replace_header(key, val);
619
        } else {
699
        } else {
620
            throw exception("Call to replace_header from invalid state",
700
            ec = error::make_error_code(error::invalid_state);
621
                        error::make_error_code(error::invalid_state));
622
        }
701
        }
623
    }
702
    }
624
}
703
}
625
704
626
// TODO: EXCEPTION_FREE
705
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
627
template <typename config>
706
template <typename config>
628
void connection<config>::remove_header(std::string const & key)
707
void connection<config>::replace_header(std::string const & key,
708
    std::string const & val)
709
{
710
    lib::error_code ec;
711
    this->replace_header(key, val, ec);
712
    if (ec) {
713
        throw exception("Call to replace_header from invalid state", ec);
714
    }
715
}
716
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
717
718
template <typename config>
719
void connection<config>::remove_header(std::string const & key,
720
    lib::error_code & ec)
629
{
721
{
630
    if (m_is_server) {
722
    if (m_is_server) {
631
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
723
        if (m_internal_state == istate::PROCESS_HTTP_REQUEST) {
632
            // we are setting response headers for an incoming server connection
724
            // we are setting response headers for an incoming server connection
633
            m_response.remove_header(key);
725
            ec = m_response.remove_header(key);
634
        } else {
726
        } else {
635
            throw exception("Call to remove_header from invalid state",
727
            ec = error::make_error_code(error::invalid_state);
636
                        error::make_error_code(error::invalid_state));
637
        }
728
        }
638
    } else {
729
    } else {
639
        if (m_internal_state == istate::USER_INIT) {
730
        if (m_internal_state == istate::USER_INIT) {
640
            // we are setting initial headers for an outgoing client connection
731
            // we are setting initial headers for an outgoing client connection
641
            m_request.remove_header(key);
732
            ec = m_request.remove_header(key);
642
        } else {
733
        } else {
643
            throw exception("Call to remove_header from invalid state",
734
            ec = error::make_error_code(error::invalid_state);
644
                        error::make_error_code(error::invalid_state));
645
        }
735
        }
646
    }
736
    }
647
}
737
}
648
738
739
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
740
template <typename config>
741
void connection<config>::remove_header(std::string const & key)
742
{
743
    lib::error_code ec;
744
    this->remove_header(key, ec);
745
    if (ec) {
746
        throw exception("Call to remove_header from invalid state", ec);
747
    }
748
}
749
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
750
649
/// Defer HTTP Response until later
751
/// Defer HTTP Response until later
650
/**
752
/**
651
 * Used in the http handler to defer the HTTP response for this connection
753
 * Used in the http handler to defer the HTTP response for this connection
Lines 698-703 void connection<config>::send_http_respo Link Here
698
    ec = lib::error_code();
800
    ec = lib::error_code();
699
}
801
}
700
802
803
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
701
template <typename config>
804
template <typename config>
702
void connection<config>::send_http_response() {
805
void connection<config>::send_http_response() {
703
    lib::error_code ec;
806
    lib::error_code ec;
Lines 706-711 void connection<config>::send_http_respo Link Here
706
        throw exception(ec);
809
        throw exception(ec);
707
    }
810
    }
708
}
811
}
812
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
709
813
710
814
711
815
Lines 848-859 void connection<config>::handle_read_han Link Here
848
    }
952
    }
849
953
850
    size_t bytes_processed = 0;
954
    size_t bytes_processed = 0;
851
    try {
955
    lib::error_code consume_ec;
852
        bytes_processed = m_request.consume(m_buf,bytes_transferred);
956
853
    } catch (http::exception &e) {
957
    bytes_processed = m_request.consume(m_buf, bytes_transferred, consume_ec);
854
        // All HTTP exceptions will result in this request failing and an error
958
    if (consume_ec) {
959
        // All HTTP errors will result in this request failing and an error
855
        // response being returned. No more bytes will be read in this con.
960
        // response being returned. No more bytes will be read in this con.
856
        m_response.set_status(e.m_error_code,e.m_error_msg);
961
        m_response.set_status(http::error::get_status_code(http::error::value(consume_ec.value())));
962
        log_err(log::elevel::fatal,"Fatal error reading request: ",consume_ec);
857
        this->write_http_response_error(error::make_error_code(error::http_parse_error));
963
        this->write_http_response_error(error::make_error_code(error::http_parse_error));
858
        return;
964
        return;
859
    }
965
    }
Lines 925-930 void connection<config>::handle_read_han Link Here
925
            this->write_http_response(handshake_ec);
1031
            this->write_http_response(handshake_ec);
926
        }
1032
        }
927
    } else {
1033
    } else {
1034
        // The HTTP parser reported that it was not ready and wants more data.
1035
        // Assert that it actually consumed all the data present before overwriting
1036
        // the buffer. This should always be the case.
1037
        if (bytes_transferred != bytes_processed) {
1038
            m_elog->write(log::elevel::fatal,"Assertion Failed: HTTP request parser failed to consume all bytes from a read request.");
1039
            this->terminate(make_error_code(error::general));
1040
            return;
1041
        }
1042
928
        // read at least 1 more byte
1043
        // read at least 1 more byte
929
        transport_con_type::async_read_at_least(
1044
        transport_con_type::async_read_at_least(
930
            1,
1045
            1,
Lines 1197-1203 lib::error_code connection<config>::proc Link Here
1197
                return error::make_error_code(error::http_connection_ended);
1312
                return error::make_error_code(error::http_connection_ended);
1198
            }
1313
            }
1199
        } else {
1314
        } else {
1200
            set_status(http::status_code::upgrade_required);
1315
            m_response.set_status(http::status_code::upgrade_required);
1201
            return error::make_error_code(error::upgrade_required);
1316
            return error::make_error_code(error::upgrade_required);
1202
        }
1317
        }
1203
1318
Lines 1302-1307 void connection<config>::write_http_resp Link Here
1302
    }
1417
    }
1303
1418
1304
    if (m_response.get_status_code() == http::status_code::uninitialized) {
1419
    if (m_response.get_status_code() == http::status_code::uninitialized) {
1420
        lib::error_code status_ec;
1305
        m_response.set_status(http::status_code::internal_server_error);
1421
        m_response.set_status(http::status_code::internal_server_error);
1306
        m_ec = error::make_error_code(error::general);
1422
        m_ec = error::make_error_code(error::general);
1307
    } else {
1423
    } else {
Lines 1583-1594 void connection<config>::handle_read_htt Link Here
1583
    }
1699
    }
1584
    
1700
    
1585
    size_t bytes_processed = 0;
1701
    size_t bytes_processed = 0;
1586
    // TODO: refactor this to use error codes rather than exceptions
1702
1587
    try {
1703
    lib::error_code consume_ec;
1588
        bytes_processed = m_response.consume(m_buf,bytes_transferred);
1704
1589
    } catch (http::exception & e) {
1705
    bytes_processed = m_response.consume(m_buf, bytes_transferred, consume_ec);
1590
        m_elog->write(log::elevel::rerror,
1706
    if (consume_ec) {
1591
            std::string("error in handle_read_http_response: ")+e.what());
1707
        // An HTTP error while reading a response doesn't give us many options other than log
1708
        // and terminate.
1709
        m_response.set_status(http::error::get_status_code(http::error::value(consume_ec.value())));
1710
        log_err(log::elevel::rerror,"error in handle_read_http_response: ",consume_ec);
1592
        this->terminate(make_error_code(error::general));
1711
        this->terminate(make_error_code(error::general));
1593
        return;
1712
        return;
1594
    }
1713
    }
Lines 1648-1653 void connection<config>::handle_read_htt Link Here
1648
1767
1649
        this->handle_read_frame(lib::error_code(), m_buf_cursor);
1768
        this->handle_read_frame(lib::error_code(), m_buf_cursor);
1650
    } else {
1769
    } else {
1770
        // The HTTP parser reported that it was not ready and wants more data.
1771
        // Assert that it actually consumed all the data present before overwriting
1772
        // the buffer. This should always be the case.
1773
        if (bytes_transferred != bytes_processed) {
1774
            m_elog->write(log::elevel::fatal,"Assertion Failed: HTTP response parser failed to consume all bytes from a read request.");
1775
            this->terminate(make_error_code(error::general));
1776
            return;
1777
        }
1778
1651
        transport_con_type::async_read_at_least(
1779
        transport_con_type::async_read_at_least(
1652
            1,
1780
            1,
1653
            m_buf,
1781
            m_buf,
Lines 1706-1711 void connection<config>::terminate(lib:: Link Here
1706
        m_handshake_timer.reset();
1834
        m_handshake_timer.reset();
1707
    }
1835
    }
1708
1836
1837
    // Cancel ping timer
1838
    if (m_ping_timer) {
1839
        m_ping_timer->cancel();
1840
        m_handshake_timer.reset();
1841
    }
1842
1709
    terminate_status tstat = unknown;
1843
    terminate_status tstat = unknown;
1710
    if (ec) {
1844
    if (ec) {
1711
        m_ec = ec;
1845
        m_ec = ec;
Lines 1779-1791 void connection<config>::handle_terminat Link Here
1779
    // call the termination handler if it exists
1913
    // call the termination handler if it exists
1780
    // if it exists it might (but shouldn't) refer to a bad memory location.
1914
    // if it exists it might (but shouldn't) refer to a bad memory location.
1781
    // If it does, we don't care and should catch and ignore it.
1915
    // If it does, we don't care and should catch and ignore it.
1916
    // todo: there has to be a better way to do this.
1782
    if (m_termination_handler) {
1917
    if (m_termination_handler) {
1918
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
1783
        try {
1919
        try {
1784
            m_termination_handler(type::get_shared());
1920
            m_termination_handler(type::get_shared());
1785
        } catch (std::exception const & e) {
1921
        } catch (std::exception const & e) {
1786
            m_elog->write(log::elevel::warn,
1922
            m_elog->write(log::elevel::warn,
1787
                std::string("termination_handler call failed. Reason was: ")+e.what());
1923
                std::string("termination_handler call failed. Reason was: ")+e.what());
1788
        }
1924
        }
1925
#else
1926
        m_termination_handler(type::get_shared());
1927
#endif
1789
    }
1928
    }
1790
}
1929
}
1791
1930
Lines 1968-1979 void connection<config>::process_control Link Here
1968
            }
2107
            }
1969
        }
2108
        }
1970
    } else if (op == frame::opcode::PONG) {
2109
    } else if (op == frame::opcode::PONG) {
1971
        if (m_pong_handler) {
1972
            m_pong_handler(m_connection_hdl, msg->get_payload());
1973
        }
1974
        if (m_ping_timer) {
2110
        if (m_ping_timer) {
1975
            m_ping_timer->cancel();
2111
            m_ping_timer->cancel();
1976
        }
2112
        }
2113
        if (m_pong_handler) {
2114
            m_pong_handler(m_connection_hdl, msg->get_payload());
2115
        }
1977
    } else if (op == frame::opcode::CLOSE) {
2116
    } else if (op == frame::opcode::CLOSE) {
1978
        m_alog->write(log::alevel::devel,"got close frame");
2117
        m_alog->write(log::alevel::devel,"got close frame");
1979
        // record close code and reason somewhere
2118
        // record close code and reason somewhere
Lines 2123-2128 lib::error_code connection<config>::send Link Here
2123
2262
2124
    m_state = session::state::closing;
2263
    m_state = session::state::closing;
2125
2264
2265
    // Cancel any outstanding ping timers. Once we are in state closing the
2266
    // library no longer processes non-close frames, so any pongs will be
2267
    // dropped.
2268
    if (m_ping_timer) {
2269
        m_ping_timer->cancel();
2270
    }
2271
2126
    if (ack) {
2272
    if (ack) {
2127
        m_was_clean = true;
2273
        m_was_clean = true;
2128
    }
2274
    }
(-)websocketpp-zaphoyd/websocketpp/impl/endpoint_impl.hpp (-69 / +71 lines)
Lines 34-40 namespace websocketpp { Link Here
34
34
35
template <typename connection, typename config>
35
template <typename connection, typename config>
36
typename endpoint<connection,config>::connection_ptr
36
typename endpoint<connection,config>::connection_ptr
37
endpoint<connection,config>::create_connection() {
37
endpoint<connection,config>::create_connection(lib::error_code & ec) {
38
    m_alog->write(log::alevel::devel,"create_connection");
38
    m_alog->write(log::alevel::devel,"create_connection");
39
    //scoped_lock_type lock(m_state_lock);
39
    //scoped_lock_type lock(m_state_lock);
40
40
Lines 81-88 endpoint<connection,config>::create_conn Link Here
81
    }
81
    }
82
    con->set_max_http_body_size(m_max_http_body_size);
82
    con->set_max_http_body_size(m_max_http_body_size);
83
83
84
    lib::error_code ec;
85
86
    ec = transport_type::init(con);
84
    ec = transport_type::init(con);
87
    if (ec) {
85
    if (ec) {
88
        m_elog->write(log::elevel::fatal,ec.message());
86
        m_elog->write(log::elevel::fatal,ec.message());
Lines 104-116 void endpoint<connection,config>::interr Link Here
104
}
102
}
105
103
106
template <typename connection, typename config>
104
template <typename connection, typename config>
107
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
108
    lib::error_code ec;
109
    interrupt(hdl,ec);
110
    if (ec) { throw exception(ec); }
111
}
112
113
template <typename connection, typename config>
114
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
105
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
115
{
106
{
116
    connection_ptr con = get_con_from_hdl(hdl,ec);
107
    connection_ptr con = get_con_from_hdl(hdl,ec);
Lines 120-132 void endpoint<connection,config>::pause_ Link Here
120
}
111
}
121
112
122
template <typename connection, typename config>
113
template <typename connection, typename config>
123
void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
124
    lib::error_code ec;
125
    pause_reading(hdl,ec);
126
    if (ec) { throw exception(ec); }
127
}
128
129
template <typename connection, typename config>
130
void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
114
void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
131
{
115
{
132
    connection_ptr con = get_con_from_hdl(hdl,ec);
116
    connection_ptr con = get_con_from_hdl(hdl,ec);
Lines 136-148 void endpoint<connection,config>::resume Link Here
136
}
120
}
137
121
138
template <typename connection, typename config>
122
template <typename connection, typename config>
139
void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
140
    lib::error_code ec;
141
    resume_reading(hdl,ec);
142
    if (ec) { throw exception(ec); }
143
}
144
145
template <typename connection, typename config>
146
void endpoint<connection,config>::send_http_response(connection_hdl hdl,
123
void endpoint<connection,config>::send_http_response(connection_hdl hdl,
147
    lib::error_code & ec)
124
    lib::error_code & ec)
148
{
125
{
Lines 152-164 void endpoint<connection,config>::send_h Link Here
152
}
129
}
153
130
154
template <typename connection, typename config>
131
template <typename connection, typename config>
155
void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
156
    lib::error_code ec;
157
    send_http_response(hdl,ec);
158
    if (ec) { throw exception(ec); }
159
}
160
161
template <typename connection, typename config>
162
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
132
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
163
    frame::opcode::value op, lib::error_code & ec)
133
    frame::opcode::value op, lib::error_code & ec)
164
{
134
{
Lines 169-183 void endpoint<connection,config>::send(c Link Here
169
}
139
}
170
140
171
template <typename connection, typename config>
141
template <typename connection, typename config>
172
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
173
    frame::opcode::value op)
174
{
175
    lib::error_code ec;
176
    send(hdl,payload,op,ec);
177
    if (ec) { throw exception(ec); }
178
}
179
180
template <typename connection, typename config>
181
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
142
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
182
    size_t len, frame::opcode::value op, lib::error_code & ec)
143
    size_t len, frame::opcode::value op, lib::error_code & ec)
183
{
144
{
Lines 187-259 void endpoint<connection,config>::send(c Link Here
187
}
148
}
188
149
189
template <typename connection, typename config>
150
template <typename connection, typename config>
190
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
151
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
191
    size_t len, frame::opcode::value op)
152
    lib::error_code & ec)
192
{
153
{
193
    lib::error_code ec;
154
    connection_ptr con = get_con_from_hdl(hdl,ec);
194
    send(hdl,payload,len,op,ec);
155
    if (ec) {return;}
195
    if (ec) { throw exception(ec); }
156
    ec = con->send(msg);
196
}
157
}
197
158
198
template <typename connection, typename config>
159
template <typename connection, typename config>
199
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg,
160
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
161
    const code, std::string const & reason,
200
    lib::error_code & ec)
162
    lib::error_code & ec)
201
{
163
{
202
    connection_ptr con = get_con_from_hdl(hdl,ec);
164
    connection_ptr con = get_con_from_hdl(hdl,ec);
203
    if (ec) {return;}
165
    if (ec) {return;}
204
    ec = con->send(msg);
166
    con->close(code,reason,ec);
205
}
167
}
206
168
207
template <typename connection, typename config>
169
template <typename connection, typename config>
208
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
170
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
209
    lib::error_code ec;
171
    payload, lib::error_code & ec)
210
    send(hdl,msg,ec);
172
{
211
    if (ec) { throw exception(ec); }
173
    connection_ptr con = get_con_from_hdl(hdl,ec);
174
    if (ec) {return;}
175
    con->ping(payload,ec);
212
}
176
}
213
177
214
template <typename connection, typename config>
178
template <typename connection, typename config>
215
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
179
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
216
    const code, std::string const & reason,
217
    lib::error_code & ec)
180
    lib::error_code & ec)
218
{
181
{
219
    connection_ptr con = get_con_from_hdl(hdl,ec);
182
    connection_ptr con = get_con_from_hdl(hdl,ec);
220
    if (ec) {return;}
183
    if (ec) {return;}
221
    con->close(code,reason,ec);
184
    con->pong(payload,ec);
222
}
185
}
223
186
187
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
188
// If exceptions are enabled, define wrapper methods that throw exceptions
189
224
template <typename connection, typename config>
190
template <typename connection, typename config>
225
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
191
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
226
    const code, std::string const & reason)
192
    lib::error_code ec;
193
    interrupt(hdl,ec);
194
    if (ec) { throw exception(ec); }
195
}
196
197
template <typename connection, typename config>
198
void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
199
    lib::error_code ec;
200
    pause_reading(hdl,ec);
201
    if (ec) { throw exception(ec); }
202
}
203
204
template <typename connection, typename config>
205
void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
206
    lib::error_code ec;
207
    resume_reading(hdl,ec);
208
    if (ec) { throw exception(ec); }
209
}
210
211
template <typename connection, typename config>
212
void endpoint<connection,config>::send_http_response(connection_hdl hdl) {
213
    lib::error_code ec;
214
    send_http_response(hdl,ec);
215
    if (ec) { throw exception(ec); }
216
}
217
218
template <typename connection, typename config>
219
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
220
    frame::opcode::value op)
227
{
221
{
228
    lib::error_code ec;
222
    lib::error_code ec;
229
    close(hdl,code,reason,ec);
223
    send(hdl,payload,op,ec);
230
    if (ec) { throw exception(ec); }
224
    if (ec) { throw exception(ec); }
231
}
225
}
232
226
233
template <typename connection, typename config>
227
template <typename connection, typename config>
234
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
228
void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
235
    payload, lib::error_code & ec)
229
    size_t len, frame::opcode::value op)
236
{
230
{
237
    connection_ptr con = get_con_from_hdl(hdl,ec);
231
    lib::error_code ec;
238
    if (ec) {return;}
232
    send(hdl,payload,len,op,ec);
239
    con->ping(payload,ec);
233
    if (ec) { throw exception(ec); }
240
}
234
}
241
235
242
template <typename connection, typename config>
236
template <typename connection, typename config>
243
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
237
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
238
    lib::error_code ec;
239
    send(hdl,msg,ec);
240
    if (ec) { throw exception(ec); }
241
}
242
243
template <typename connection, typename config>
244
void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
245
    const code, std::string const & reason)
244
{
246
{
245
    lib::error_code ec;
247
    lib::error_code ec;
246
    ping(hdl,payload,ec);
248
    close(hdl,code,reason,ec);
247
    if (ec) { throw exception(ec); }
249
    if (ec) { throw exception(ec); }
248
}
250
}
249
251
250
template <typename connection, typename config>
252
template <typename connection, typename config>
251
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
253
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
252
    lib::error_code & ec)
253
{
254
{
254
    connection_ptr con = get_con_from_hdl(hdl,ec);
255
    lib::error_code ec;
255
    if (ec) {return;}
256
    ping(hdl,payload,ec);
256
    con->pong(payload,ec);
257
    if (ec) { throw exception(ec); }
257
}
258
}
258
259
259
template <typename connection, typename config>
260
template <typename connection, typename config>
Lines 263-268 void endpoint<connection,config>::pong(c Link Here
263
    pong(hdl,payload,ec);
264
    pong(hdl,payload,ec);
264
    if (ec) { throw exception(ec); }
265
    if (ec) { throw exception(ec); }
265
}
266
}
267
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
266
268
267
} // namespace websocketpp
269
} // namespace websocketpp
268
270
(-)websocketpp-zaphoyd/websocketpp/impl/utilities_impl.hpp (-18 / +4 lines)
Lines 34-66 Link Here
34
namespace websocketpp {
34
namespace websocketpp {
35
namespace utility {
35
namespace utility {
36
36
37
inline std::string to_lower(std::string const & in) {
38
    std::string out = in;
39
    std::transform(out.begin(),out.end(),out.begin(),::tolower);
40
    return out;
41
}
42
43
inline std::string to_hex(std::string const & input) {
37
inline std::string to_hex(std::string const & input) {
44
    std::string output;
38
    return to_hex(input.c_str(), input.size());
45
    std::string hex = "0123456789ABCDEF";
46
47
    for (size_t i = 0; i < input.size(); i++) {
48
        output += hex[(input[i] & 0xF0) >> 4];
49
        output += hex[input[i] & 0x0F];
50
        output += " ";
51
    }
52
53
    return output;
54
}
39
}
55
40
56
inline std::string to_hex(uint8_t const * input, size_t length) {
41
inline std::string to_hex(uint8_t const * input, size_t length) {
57
    std::string output;
42
    std::string output;
58
    std::string hex = "0123456789ABCDEF";
43
    output.reserve(length * 3);
44
    char const * hex = "0123456789ABCDEF";
59
45
60
    for (size_t i = 0; i < length; i++) {
46
    for (size_t i = 0; i < length; i++) {
61
        output += hex[(input[i] & 0xF0) >> 4];
47
        output += hex[(input[i] & 0xF0) >> 4];
62
        output += hex[input[i] & 0x0F];
48
        output += hex[input[i] & 0x0F];
63
        output += " ";
49
        output += ' ';
64
    }
50
    }
65
51
66
    return output;
52
    return output;
(-)websocketpp-zaphoyd/websocketpp/logger/basic.hpp (-7 / +7 lines)
Lines 58-90 namespace log { Link Here
58
template <typename concurrency, typename names>
58
template <typename concurrency, typename names>
59
class basic {
59
class basic {
60
public:
60
public:
61
    basic<concurrency,names>(channel_type_hint::value h =
61
    basic(channel_type_hint::value h =
62
        channel_type_hint::access)
62
        channel_type_hint::access)
63
      : m_static_channels(0xffffffff)
63
      : m_static_channels(0xffffffff)
64
      , m_dynamic_channels(0)
64
      , m_dynamic_channels(0)
65
      , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
65
      , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
66
66
67
    basic<concurrency,names>(std::ostream * out)
67
    basic(std::ostream * out)
68
      : m_static_channels(0xffffffff)
68
      : m_static_channels(0xffffffff)
69
      , m_dynamic_channels(0)
69
      , m_dynamic_channels(0)
70
      , m_out(out) {}
70
      , m_out(out) {}
71
71
72
    basic<concurrency,names>(level c, channel_type_hint::value h =
72
    basic(level c, channel_type_hint::value h =
73
        channel_type_hint::access)
73
        channel_type_hint::access)
74
      : m_static_channels(c)
74
      : m_static_channels(c)
75
      , m_dynamic_channels(0)
75
      , m_dynamic_channels(0)
76
      , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
76
      , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
77
77
78
    basic<concurrency,names>(level c, std::ostream * out)
78
    basic(level c, std::ostream * out)
79
      : m_static_channels(c)
79
      : m_static_channels(c)
80
      , m_dynamic_channels(0)
80
      , m_dynamic_channels(0)
81
      , m_out(out) {}
81
      , m_out(out) {}
82
82
83
    /// Destructor
83
    /// Destructor
84
    ~basic<concurrency,names>() {}
84
    ~basic() {}
85
85
86
    /// Copy constructor
86
    /// Copy constructor
87
    basic<concurrency,names>(basic<concurrency,names> const & other)
87
    basic(basic<concurrency,names> const & other)
88
     : m_static_channels(other.m_static_channels)
88
     : m_static_channels(other.m_static_channels)
89
     , m_dynamic_channels(other.m_dynamic_channels)
89
     , m_dynamic_channels(other.m_dynamic_channels)
90
     , m_out(other.m_out)
90
     , m_out(other.m_out)
Lines 97-103 public: Link Here
97
97
98
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
98
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
99
    /// Move constructor
99
    /// Move constructor
100
    basic<concurrency,names>(basic<concurrency,names> && other)
100
    basic(basic<concurrency,names> && other)
101
     : m_static_channels(other.m_static_channels)
101
     : m_static_channels(other.m_static_channels)
102
     , m_dynamic_channels(other.m_dynamic_channels)
102
     , m_dynamic_channels(other.m_dynamic_channels)
103
     , m_out(other.m_out)
103
     , m_out(other.m_out)
(-)websocketpp-zaphoyd/websocketpp/processors/hybi00.hpp (-1 / +1 lines)
Lines 435-441 private: Link Here
435
                      reinterpret_cast<char*>(&num)+4,
435
                      reinterpret_cast<char*>(&num)+4,
436
                      result);
436
                      result);
437
        } else {
437
        } else {
438
            std::fill(result,result+4,0);
438
            std::fill(result,result+4,static_cast<char>(0));
439
        }
439
        }
440
    }
440
    }
441
441
(-)websocketpp-zaphoyd/websocketpp/processors/hybi13.hpp (-1 / +1 lines)
Lines 555-561 public: Link Here
555
        std::fill_n(
555
        std::fill_n(
556
            m_extended_header.bytes,
556
            m_extended_header.bytes,
557
            frame::MAX_EXTENDED_HEADER_LENGTH,
557
            frame::MAX_EXTENDED_HEADER_LENGTH,
558
            0x00
558
            static_cast<uint8_t>(0x00)
559
        );
559
        );
560
    }
560
    }
561
561
(-)websocketpp-zaphoyd/websocketpp/roles/client_endpoint.hpp (-2 / +6 lines)
Lines 92-101 public: Link Here
92
            return connection_ptr();
92
            return connection_ptr();
93
        }
93
        }
94
94
95
        connection_ptr con = endpoint_type::create_connection();
95
        connection_ptr con = endpoint_type::create_connection(ec);
96
96
97
        if (!con) {
97
        if (!con) {
98
            ec = error::make_error_code(error::con_creation_failed);
98
            // if the transport doesn't have a more specific error, set
99
            // a generic one.
100
            if (!ec) {
101
                ec = error::make_error_code(error::con_creation_failed);
102
            }
99
            return con;
103
            return con;
100
        }
104
        }
101
105
(-)websocketpp-zaphoyd/websocketpp/roles/server_endpoint.hpp (-16 / +166 lines)
Lines 64-69 public: Link Here
64
    /// Type of the endpoint component of this server
64
    /// Type of the endpoint component of this server
65
    typedef endpoint<connection_type,config> endpoint_type;
65
    typedef endpoint<connection_type,config> endpoint_type;
66
66
67
    /// The type and signature of the callback passed to the start_accept method
68
    typedef lib::function<void(lib::error_code const &, lib::error_code const &)> accept_loop_handler;
69
67
    friend class connection<config>;
70
    friend class connection<config>;
68
71
69
    explicit server() : endpoint_type(true)
72
    explicit server() : endpoint_type(true)
Lines 72-82 public: Link Here
72
    }
75
    }
73
76
74
    /// Destructor
77
    /// Destructor
75
    ~server<config>() {}
78
    ~server() {}
76
79
77
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
80
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
78
    // no copy constructor because endpoints are not copyable
81
    // no copy constructor because endpoints are not copyable
79
    server<config>(server<config> &) = delete;
82
    server(server<config> &) = delete;
80
83
81
    // no copy assignment operator because endpoints are not copyable
84
    // no copy assignment operator because endpoints are not copyable
82
    server<config> & operator=(server<config> const &) = delete;
85
    server<config> & operator=(server<config> const &) = delete;
Lines 84-90 public: Link Here
84
87
85
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
88
#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
86
    /// Move constructor
89
    /// Move constructor
87
    server<config>(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {}
90
    server(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {}
88
91
89
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
92
#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
90
    // no move assignment operator because of const member variables
93
    // no move assignment operator because of const member variables
Lines 101-121 public: Link Here
101
     * Note: The connection must either be started or terminated using
104
     * Note: The connection must either be started or terminated using
102
     * connection::terminate in order to avoid memory leaks.
105
     * connection::terminate in order to avoid memory leaks.
103
     *
106
     *
107
     * @deprecated 0.9.0 use `get_connection(lib::error_code &)` instead.
108
     * 
109
     * @see `get_connection(lib::error_code &)` for an alternative that
110
     * returns a detailed error code on failure.
111
     * 
104
     * @return A pointer to the new connection.
112
     * @return A pointer to the new connection.
105
     */
113
     */
106
    connection_ptr get_connection() {
114
    connection_ptr get_connection() {
107
        return endpoint_type::create_connection();
115
        lib::error_code ec;
116
        return endpoint_type::create_connection(ec);
117
    }
118
119
    /// Create and initialize a new connection
120
    /**
121
     * The connection will be initialized and ready to begin. Call its start()
122
     * method to begin the processing loop.
123
     *
124
     * Note: The connection must either be started or terminated using
125
     * connection::terminate in order to avoid memory leaks.
126
     *
127
     * @since 0.9.0
128
     * 
129
     * @param [out] ec A status code that indicates why the failure occurred
130
     *        if the returned pointer is blank.
131
     * @return A pointer to the new connection.
132
     */
133
    connection_ptr get_connection(lib::error_code & ec) {
134
        return endpoint_type::create_connection(ec);
108
    }
135
    }
109
136
110
    /// Starts the server's async connection acceptance loop (exception free)
137
    /// Starts the server's async connection acceptance loop (exception free)
111
    /**
138
    /**
112
     * Initiates the server connection acceptance loop. Must be called after
139
     * Initiates the server connection acceptance loop. Must be called after
113
     * listen. This method will have no effect until the underlying io_service
140
     * listen. This method will have no effect until the underlying io_context
114
     * starts running. It may be called after the io_service is already running.
141
     * starts running. It may be called after the io_context is already running.
115
     *
142
     *
116
     * Refer to documentation for the transport policy you are using for
143
     * Refer to documentation for the transport policy you are using for
117
     * instructions on how to stop this acceptance loop.
144
     * instructions on how to stop this acceptance loop.
145
     * 
146
     * Error handling:
147
     * start_accept will return an error via the `ec` parameter if there is a 
148
     * problem starting the accept loop. Once successfully started the loop will
149
     * continue to renew itself after each connection. This method has no way of
150
     * delivering that happen after the loop is started. Use 
151
     * `start_accept(accept_loop_handler)` instead to get full error information
152
     * no matter when the async loop ends.
118
     *
153
     *
154
     * @deprecated use `start_accept(accept_loop_handler) instead
155
     * 
119
     * @param [out] ec A status code indicating an error, if any.
156
     * @param [out] ec A status code indicating an error, if any.
120
     */
157
     */
121
    void start_accept(lib::error_code & ec) {
158
    void start_accept(lib::error_code & ec) {
Lines 125-131 public: Link Here
125
        }
162
        }
126
        
163
        
127
        ec = lib::error_code();
164
        ec = lib::error_code();
128
        connection_ptr con = get_connection();
165
        connection_ptr con = get_connection(ec);
129
166
130
        if (!con) {
167
        if (!con) {
131
          ec = error::make_error_code(error::con_creation_failed);
168
          ec = error::make_error_code(error::con_creation_failed);
Lines 134-140 public: Link Here
134
171
135
        transport_type::async_accept(
172
        transport_type::async_accept(
136
            lib::static_pointer_cast<transport_con_type>(con),
173
            lib::static_pointer_cast<transport_con_type>(con),
137
            lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
174
            lib::bind(&type::handle_accept_legacy,this,con,lib::placeholders::_1),
138
            ec
175
            ec
139
        );
176
        );
140
177
Lines 145-158 public: Link Here
145
        }
182
        }
146
    }
183
    }
147
184
148
    /// Starts the server's async connection acceptance loop
185
    /// Starts the server's async connection acceptance loop (exception free)
149
    /**
186
    /**
150
     * Initiates the server connection acceptance loop. Must be called after
187
     * Initiates the server connection acceptance loop. Requires a transport
151
     * listen. This method will have no effect until the underlying io_service
188
     * policy that supports an asyncronous listen+accept loop. Must be called
152
     * starts running. It may be called after the io_service is already running.
189
     * while the endpoint is listening (or start_accept will return immediately
190
     * with an error that the server is not listening).
191
     * 
192
     * Consult the documentation for the underlying transport for information
193
     * about exactly when this code will start running, when in the transport
194
     * event loop it makes sense to call it, and for instructions on how to
195
     * stop this acceptance loop.
153
     *
196
     *
154
     * Refer to documentation for the transport policy you are using for
197
     * Error handling:
155
     * instructions on how to stop this acceptance loop.
198
     * start_accept will attempt to start an asyncronous acceptance loop that
199
     * accepts a connection and then re-issues a new accept command. If this loop
200
     * ends or fails for any reason (including immediately) the `completion_handler`
201
     * will be called with two status codes. The first is the library level status
202
     * code the second is the underlying transport status code (if any).
203
     * 
204
     * @since 0.9.0
205
     * 
206
     * @param completion_handler A handler function to be called when the async
207
     *        accept loop ends.
208
     */
209
    void start_accept(accept_loop_handler completion_handler) {
210
        // This check will happen again in async_accept but if we do it here we can
211
        // avoid setting up and tearing down a connection if we know that we can't
212
        // actually accept a connection.
213
        if (!transport_type::is_listening()) {
214
            completion_handler(error::make_error_code(error::transport_error),
215
                               error::make_error_code(error::async_accept_not_listening));
216
            return;
217
        }
218
        
219
        lib::error_code tec;
220
        connection_ptr con = get_connection(tec);
221
222
        if (!con) {
223
          completion_handler(error::make_error_code(error::con_creation_failed),tec);
224
          return;
225
        }
226
227
        transport_type::async_accept(
228
            lib::static_pointer_cast<transport_con_type>(con),
229
            lib::bind(&type::handle_accept,this,
230
                      con,
231
                      completion_handler,
232
                      lib::placeholders::_1),
233
            tec
234
        );
235
236
        if (tec) {
237
            if (con) {
238
                // If the connection was constructed but the accept failed,
239
                // terminate the connection to prevent memory leaks.
240
                con->terminate(lib::error_code());
241
            }
242
243
            endpoint_type::m_elog->write(log::elevel::rerror,
244
                "Async_accept failed: "+tec.message());
245
246
            // let the end user know about the error
247
            completion_handler(error::make_error_code(error::transport_error),tec);
248
        }
249
    }
250
251
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
252
    /// Starts the server's async connection acceptance loop (exception)
253
    /**
254
     * Initiates the server connection acceptance loop. Requires a transport
255
     * policy that supports an asyncronous listen+accept loop. Must be called
256
     * while the endpoint is listening (or start_accept will return immediately
257
     * with an error that the server is not listening).
258
     * 
259
     * Consult the documentation for the underlying transport for information
260
     * about exactly when this code will start running, when in the transport
261
     * event loop it makes sense to call it, and for instructions on how to
262
     * stop this acceptance loop.
263
     *
264
     * Error handling:
265
     * start_accept will throw an exception if there is a problem starting the
266
     * accept loop. Once successfully started the loop will continue to renew
267
     * itself after each connection. This method has no way of delivering that
268
     * happen after the loop is started. Use `start_accept(accept_loop_handler)`
269
     * instead to get full error information no matter when the async loop ends.
270
     * 
271
     * @deprecated use `start_accept(accept_loop_handler)` instead
272
     * 
273
     * @exception websocketpp::exception If the accept loop fails to be set up.
156
     */
274
     */
157
    void start_accept() {
275
    void start_accept() {
158
        lib::error_code ec;
276
        lib::error_code ec;
Lines 161-169 public: Link Here
161
            throw exception(ec);
279
            throw exception(ec);
162
        }
280
        }
163
    }
281
    }
282
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
164
283
165
    /// Handler callback for start_accept
284
    /// Handler callback for start_accept (deprecated)
166
    void handle_accept(connection_ptr con, lib::error_code const & ec) {
285
    void handle_accept_legacy(connection_ptr con, lib::error_code const & ec) {
167
        if (ec) {
286
        if (ec) {
168
            con->terminate(ec);
287
            con->terminate(ec);
169
288
Lines 188-193 public: Link Here
188
                "Restarting async_accept loop failed: "+ec.message());
307
                "Restarting async_accept loop failed: "+ec.message());
189
        }
308
        }
190
    }
309
    }
310
311
    /// Handler callback for start_accept
312
    void handle_accept(connection_ptr con, 
313
                       accept_loop_handler completion_handler,
314
                       lib::error_code const & tec)
315
    {
316
        // deal with the newly accepted connection
317
        if (tec) {
318
            // terminate the connection and pass the transport error
319
            // code along
320
            con->terminate(tec);
321
322
            // log the transport error before restarting the loop
323
            if (tec == error::operation_canceled) {
324
                endpoint_type::m_elog->write(log::elevel::info,
325
                    "handle_accept error: "+tec.message());
326
            } else {
327
                endpoint_type::m_elog->write(log::elevel::rerror,
328
                    "handle_accept error: "+tec.message());
329
            }
330
        } else {
331
            con->start();
332
        }
333
334
        // todo: are there any `tec` codes that should prompt us to end
335
        // without restarting the loop?
336
337
        // attempt to restart the async accept loop for the next connection
338
        // this method will deliver any errors via the completion_handler
339
        start_accept(completion_handler);
340
    }
191
};
341
};
192
342
193
} // namespace websocketpp
343
} // namespace websocketpp
(-)websocketpp-zaphoyd/websocketpp/sha1/sha1.hpp (-1 / +3 lines)
Lines 36-41 under the same license as the original, Link Here
36
#ifndef SHA1_DEFINED
36
#ifndef SHA1_DEFINED
37
#define SHA1_DEFINED
37
#define SHA1_DEFINED
38
38
39
#include <cstddef>
40
39
namespace websocketpp {
41
namespace websocketpp {
40
namespace sha1 {
42
namespace sha1 {
41
43
Lines 173-179 inline void calc(void const * src, size_ Link Here
173
        innerHash(result, w);
175
        innerHash(result, w);
174
        clearWBuffert(w);
176
        clearWBuffert(w);
175
    }
177
    }
176
    w[15] = bytelength << 3;
178
    w[15] = static_cast<unsigned int>(bytelength << 3);
177
    innerHash(result, w);
179
    innerHash(result, w);
178
180
179
    // Store hash in result pointer, and make sure we get in in the correct
181
    // Store hash in result pointer, and make sure we get in in the correct
(-)websocketpp-zaphoyd/websocketpp/transport/asio/base.hpp (-1 / +1 lines)
Lines 40-46 namespace websocketpp { Link Here
40
namespace transport {
40
namespace transport {
41
/// Transport policy that uses asio
41
/// Transport policy that uses asio
42
/**
42
/**
43
 * This policy uses a single asio io_service to provide transport
43
 * This policy uses a single asio io_context to provide transport
44
 * services to a WebSocket++ endpoint.
44
 * services to a WebSocket++ endpoint.
45
 */
45
 */
46
namespace asio {
46
namespace asio {
(-)websocketpp-zaphoyd/websocketpp/transport/asio/connection.hpp (-30 / +48 lines)
Lines 85-94 public: Link Here
85
    typedef typename config::response_type response_type;
85
    typedef typename config::response_type response_type;
86
    typedef typename response_type::ptr response_ptr;
86
    typedef typename response_type::ptr response_ptr;
87
87
88
    /// Type of a pointer to the Asio io_service being used
88
    /// Type of a pointer to the Asio io_context being used
89
    typedef lib::asio::io_service * io_service_ptr;
89
    typedef lib::asio::io_context * io_context_ptr;
90
    /// Type of a pointer to the Asio io_service::strand being used
90
    /// Type of a pointer to the Asio io_context::strand being used
91
    typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr;
91
    typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr;
92
    /// Type of a pointer to the Asio timer class
92
    /// Type of a pointer to the Asio timer class
93
    typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;
93
    typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;
94
94
Lines 97-103 public: Link Here
97
    // to the public api.
97
    // to the public api.
98
    friend class endpoint<config>;
98
    friend class endpoint<config>;
99
99
100
    // generate and manage our own io_service
100
    // generate and manage our own io_context
101
    explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & elog)
101
    explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & elog)
102
      : m_is_server(is_server)
102
      : m_is_server(is_server)
103
      , m_alog(alog)
103
      , m_alog(alog)
Lines 194-205 public: Link Here
194
        ec = lib::error_code();
194
        ec = lib::error_code();
195
    }
195
    }
196
196
197
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
197
    /// Set the proxy to connect through (exception)
198
    /// Set the proxy to connect through (exception)
198
    void set_proxy(std::string const & uri) {
199
    void set_proxy(std::string const & uri) {
199
        lib::error_code ec;
200
        lib::error_code ec;
200
        set_proxy(uri,ec);
201
        set_proxy(uri,ec);
201
        if (ec) { throw exception(ec); }
202
        if (ec) { throw exception(ec); }
202
    }
203
    }
204
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
203
205
204
    /// Set the basic auth credentials to use (exception free)
206
    /// Set the basic auth credentials to use (exception free)
205
    /**
207
    /**
Lines 228-233 public: Link Here
228
        ec = lib::error_code();
230
        ec = lib::error_code();
229
    }
231
    }
230
232
233
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
231
    /// Set the basic auth credentials to use (exception)
234
    /// Set the basic auth credentials to use (exception)
232
    void set_proxy_basic_auth(std::string const & username, std::string const &
235
    void set_proxy_basic_auth(std::string const & username, std::string const &
233
        password)
236
        password)
Lines 236-241 public: Link Here
236
        set_proxy_basic_auth(username,password,ec);
239
        set_proxy_basic_auth(username,password,ec);
237
        if (ec) { throw exception(ec); }
240
        if (ec) { throw exception(ec); }
238
    }
241
    }
242
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
239
243
240
    /// Set the proxy timeout duration (exception free)
244
    /// Set the proxy timeout duration (exception free)
241
    /**
245
    /**
Lines 257-268 public: Link Here
257
        ec = lib::error_code();
261
        ec = lib::error_code();
258
    }
262
    }
259
263
264
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
260
    /// Set the proxy timeout duration (exception)
265
    /// Set the proxy timeout duration (exception)
261
    void set_proxy_timeout(long duration) {
266
    void set_proxy_timeout(long duration) {
262
        lib::error_code ec;
267
        lib::error_code ec;
263
        set_proxy_timeout(duration,ec);
268
        set_proxy_timeout(duration,ec);
264
        if (ec) { throw exception(ec); }
269
        if (ec) { throw exception(ec); }
265
    }
270
    }
271
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
266
272
267
    std::string const & get_proxy() const {
273
    std::string const & get_proxy() const {
268
        return m_proxy;
274
        return m_proxy;
Lines 313-324 public: Link Here
313
    timer_ptr set_timer(long duration, timer_handler callback) {
319
    timer_ptr set_timer(long duration, timer_handler callback) {
314
        timer_ptr new_timer(
320
        timer_ptr new_timer(
315
            new lib::asio::steady_timer(
321
            new lib::asio::steady_timer(
316
                *m_io_service,
322
                *m_io_context,
317
                lib::asio::milliseconds(duration))
323
                lib::asio::milliseconds(duration))
318
        );
324
        );
319
325
320
        if (config::enable_multithreading) {
326
        if (config::enable_multithreading) {
321
            new_timer->async_wait(m_strand->wrap(lib::bind(
327
            new_timer->async_wait(lib::asio::bind_executor(*m_strand, lib::bind(
322
                &type::handle_timer, get_shared(),
328
                &type::handle_timer, get_shared(),
323
                new_timer,
329
                new_timer,
324
                callback,
330
                callback,
Lines 393-399 public: Link Here
393
    /// Initialize transport for reading
399
    /// Initialize transport for reading
394
    /**
400
    /**
395
     * init_asio is called once immediately after construction to initialize
401
     * init_asio is called once immediately after construction to initialize
396
     * Asio components to the io_service
402
     * Asio components to the io_context
397
     *
403
     *
398
     * The transport initialization sequence consists of the following steps:
404
     * The transport initialization sequence consists of the following steps:
399
     * - Pre-init: the underlying socket is initialized to the point where
405
     * - Pre-init: the underlying socket is initialized to the point where
Lines 451-471 protected: Link Here
451
    /// Finish constructing the transport
457
    /// Finish constructing the transport
452
    /**
458
    /**
453
     * init_asio is called once immediately after construction to initialize
459
     * init_asio is called once immediately after construction to initialize
454
     * Asio components to the io_service.
460
     * Asio components to the io_context.
455
     *
461
     *
456
     * @param io_service A pointer to the io_service to register with this
462
     * @param io_context A pointer to the io_context to register with this
457
     * connection
463
     * connection
458
     *
464
     *
459
     * @return Status code for the success or failure of the initialization
465
     * @return Status code for the success or failure of the initialization
460
     */
466
     */
461
    lib::error_code init_asio (io_service_ptr io_service) {
467
    lib::error_code init_asio (io_context_ptr io_context) {
462
        m_io_service = io_service;
468
        m_io_context = io_context;
463
469
464
        if (config::enable_multithreading) {
470
        if (config::enable_multithreading) {
465
            m_strand.reset(new lib::asio::io_service::strand(*io_service));
471
            m_strand.reset(new lib::asio::io_context::strand(*io_context));
466
        }
472
        }
467
473
468
        lib::error_code ec = socket_con_type::init_asio(io_service, m_strand,
474
        lib::error_code ec = socket_con_type::init_asio(io_context, m_strand,
469
            m_is_server);
475
            m_is_server);
470
476
471
        return ec;
477
        return ec;
Lines 573-579 protected: Link Here
573
        lib::error_code const & ec)
579
        lib::error_code const & ec)
574
    {
580
    {
575
        if (ec == transport::error::operation_aborted ||
581
        if (ec == transport::error::operation_aborted ||
576
            (post_timer && lib::asio::is_neg(post_timer->expires_from_now())))
582
            (post_timer && lib::asio::is_neg(post_timer->expiry() - timer_ptr::element_type::clock_type::now())))
577
        {
583
        {
578
            m_alog->write(log::alevel::devel,"post_init cancelled");
584
            m_alog->write(log::alevel::devel,"post_init cancelled");
579
            return;
585
            return;
Lines 629-635 protected: Link Here
629
            lib::asio::async_write(
635
            lib::asio::async_write(
630
                socket_con_type::get_next_layer(),
636
                socket_con_type::get_next_layer(),
631
                m_bufs,
637
                m_bufs,
632
                m_strand->wrap(lib::bind(
638
                lib::asio::bind_executor(*m_strand, lib::bind(
633
                    &type::handle_proxy_write, get_shared(),
639
                    &type::handle_proxy_write, get_shared(),
634
                    callback,
640
                    callback,
635
                    lib::placeholders::_1
641
                    lib::placeholders::_1
Lines 679-685 protected: Link Here
679
        // Whatever aborted it will be issuing the callback so we are safe to
685
        // Whatever aborted it will be issuing the callback so we are safe to
680
        // return
686
        // return
681
        if (ec == lib::asio::error::operation_aborted ||
687
        if (ec == lib::asio::error::operation_aborted ||
682
            lib::asio::is_neg(m_proxy_data->timer->expires_from_now()))
688
            lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now()))
683
        {
689
        {
684
            m_elog->write(log::elevel::devel,"write operation aborted");
690
            m_elog->write(log::elevel::devel,"write operation aborted");
685
            return;
691
            return;
Lines 703-709 protected: Link Here
703
        if (!m_proxy_data) {
709
        if (!m_proxy_data) {
704
            m_elog->write(log::elevel::library,
710
            m_elog->write(log::elevel::library,
705
                "assertion failed: !m_proxy_data in asio::connection::proxy_read");
711
                "assertion failed: !m_proxy_data in asio::connection::proxy_read");
706
            m_proxy_data->timer->cancel();
707
            callback(make_error_code(error::general));
712
            callback(make_error_code(error::general));
708
            return;
713
            return;
709
        }
714
        }
Lines 713-719 protected: Link Here
713
                socket_con_type::get_next_layer(),
718
                socket_con_type::get_next_layer(),
714
                m_proxy_data->read_buf,
719
                m_proxy_data->read_buf,
715
                "\r\n\r\n",
720
                "\r\n\r\n",
716
                m_strand->wrap(lib::bind(
721
                lib::asio::bind_executor(*m_strand, lib::bind(
717
                    &type::handle_proxy_read, get_shared(),
722
                    &type::handle_proxy_read, get_shared(),
718
                    callback,
723
                    callback,
719
                    lib::placeholders::_1, lib::placeholders::_2
724
                    lib::placeholders::_1, lib::placeholders::_2
Lines 751-757 protected: Link Here
751
        // Whatever aborted it will be issuing the callback so we are safe to
756
        // Whatever aborted it will be issuing the callback so we are safe to
752
        // return
757
        // return
753
        if (ec == lib::asio::error::operation_aborted ||
758
        if (ec == lib::asio::error::operation_aborted ||
754
            lib::asio::is_neg(m_proxy_data->timer->expires_from_now()))
759
            lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now()))
755
        {
760
        {
756
            m_elog->write(log::elevel::devel,"read operation aborted");
761
            m_elog->write(log::elevel::devel,"read operation aborted");
757
            return;
762
            return;
Lines 772-780 protected: Link Here
772
                return;
777
                return;
773
            }
778
            }
774
779
780
            // todo: switch this to using non-istream based consume
775
            std::istream input(&m_proxy_data->read_buf);
781
            std::istream input(&m_proxy_data->read_buf);
776
782
777
            m_proxy_data->res.consume(input);
783
            lib::error_code istream_ec;
784
            m_proxy_data->res.consume(input, istream_ec);
785
            if (istream_ec) {
786
                // there was an error while reading from the proxy
787
                m_elog->write(log::elevel::info,
788
                    "An HTTP handling error occurred while reading a response from the proxy server: "+istream_ec.message());
789
                // todo: do we need to translate this error?
790
                callback(istream_ec);
791
                return;
792
            }
778
793
779
            if (!m_proxy_data->res.headers_ready()) {
794
            if (!m_proxy_data->res.headers_ready()) {
780
                // we read until the headers were done in theory but apparently
795
                // we read until the headers were done in theory but apparently
Lines 841-847 protected: Link Here
841
                socket_con_type::get_socket(),
856
                socket_con_type::get_socket(),
842
                lib::asio::buffer(buf,len),
857
                lib::asio::buffer(buf,len),
843
                lib::asio::transfer_at_least(num_bytes),
858
                lib::asio::transfer_at_least(num_bytes),
844
                m_strand->wrap(make_custom_alloc_handler(
859
                lib::asio::bind_executor(*m_strand, make_custom_alloc_handler(
845
                    m_read_handler_allocator,
860
                    m_read_handler_allocator,
846
                    lib::bind(
861
                    lib::bind(
847
                        &type::handle_async_read, get_shared(),
862
                        &type::handle_async_read, get_shared(),
Lines 910-916 protected: Link Here
910
            lib::asio::async_write(
925
            lib::asio::async_write(
911
                socket_con_type::get_socket(),
926
                socket_con_type::get_socket(),
912
                m_bufs,
927
                m_bufs,
913
                m_strand->wrap(make_custom_alloc_handler(
928
                lib::asio::bind_executor(*m_strand, make_custom_alloc_handler(
914
                    m_write_handler_allocator,
929
                    m_write_handler_allocator,
915
                    lib::bind(
930
                    lib::bind(
916
                        &type::handle_async_write, get_shared(),
931
                        &type::handle_async_write, get_shared(),
Lines 939-944 protected: Link Here
939
    void async_write(std::vector<buffer> const & bufs, write_handler handler) {
954
    void async_write(std::vector<buffer> const & bufs, write_handler handler) {
940
        std::vector<buffer>::const_iterator it;
955
        std::vector<buffer>::const_iterator it;
941
956
957
        // todo: check if this underlying socket supports efficient scatter/gather io
958
        // if not, coalesce buffers before we send to the underlying transport.
959
942
        for (it = bufs.begin(); it != bufs.end(); ++it) {
960
        for (it = bufs.begin(); it != bufs.end(); ++it) {
943
            m_bufs.push_back(lib::asio::buffer((*it).buf,(*it).len));
961
            m_bufs.push_back(lib::asio::buffer((*it).buf,(*it).len));
944
        }
962
        }
Lines 947-953 protected: Link Here
947
            lib::asio::async_write(
965
            lib::asio::async_write(
948
                socket_con_type::get_socket(),
966
                socket_con_type::get_socket(),
949
                m_bufs,
967
                m_bufs,
950
                m_strand->wrap(make_custom_alloc_handler(
968
                lib::asio::bind_executor(*m_strand, make_custom_alloc_handler(
951
                    m_write_handler_allocator,
969
                    m_write_handler_allocator,
952
                    lib::bind(
970
                    lib::bind(
953
                        &type::handle_async_write, get_shared(),
971
                        &type::handle_async_write, get_shared(),
Lines 1012-1029 protected: Link Here
1012
     */
1030
     */
1013
    lib::error_code interrupt(interrupt_handler handler) {
1031
    lib::error_code interrupt(interrupt_handler handler) {
1014
        if (config::enable_multithreading) {
1032
        if (config::enable_multithreading) {
1015
            m_io_service->post(m_strand->wrap(handler));
1033
            lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler));
1016
        } else {
1034
        } else {
1017
            m_io_service->post(handler);
1035
            lib::asio::post(m_io_context->get_executor(), handler);
1018
        }
1036
        }
1019
        return lib::error_code();
1037
        return lib::error_code();
1020
    }
1038
    }
1021
1039
1022
    lib::error_code dispatch(dispatch_handler handler) {
1040
    lib::error_code dispatch(dispatch_handler handler) {
1023
        if (config::enable_multithreading) {
1041
        if (config::enable_multithreading) {
1024
            m_io_service->post(m_strand->wrap(handler));
1042
            lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler));
1025
        } else {
1043
        } else {
1026
            m_io_service->post(handler);
1044
            lib::asio::post(m_io_context->get_executor(), handler);
1027
        }
1045
        }
1028
        return lib::error_code();
1046
        return lib::error_code();
1029
    }
1047
    }
Lines 1095-1101 protected: Link Here
1095
        callback, lib::asio::error_code const & ec)
1113
        callback, lib::asio::error_code const & ec)
1096
    {
1114
    {
1097
        if (ec == lib::asio::error::operation_aborted ||
1115
        if (ec == lib::asio::error::operation_aborted ||
1098
            lib::asio::is_neg(shutdown_timer->expires_from_now()))
1116
            lib::asio::is_neg(shutdown_timer->expiry() - timer_ptr::element_type::clock_type::now()))
1099
        {
1117
        {
1100
            m_alog->write(log::alevel::devel,"async_shutdown cancelled");
1118
            m_alog->write(log::alevel::devel,"async_shutdown cancelled");
1101
            return;
1119
            return;
Lines 1172-1178 private: Link Here
1172
    lib::shared_ptr<proxy_data> m_proxy_data;
1190
    lib::shared_ptr<proxy_data> m_proxy_data;
1173
1191
1174
    // transport resources
1192
    // transport resources
1175
    io_service_ptr  m_io_service;
1193
    io_context_ptr  m_io_context;
1176
    strand_ptr      m_strand;
1194
    strand_ptr      m_strand;
1177
    connection_hdl  m_connection_hdl;
1195
    connection_hdl  m_connection_hdl;
1178
1196
(-)websocketpp-zaphoyd/websocketpp/transport/asio/endpoint.hpp (-174 / +199 lines)
Lines 77-101 public: Link Here
77
    /// associated with this endpoint transport component
77
    /// associated with this endpoint transport component
78
    typedef typename transport_con_type::ptr transport_con_ptr;
78
    typedef typename transport_con_type::ptr transport_con_ptr;
79
79
80
    /// Type of a pointer to the ASIO io_service being used
80
    /// Type of a pointer to the ASIO io_context being used
81
    typedef lib::asio::io_service * io_service_ptr;
81
    typedef lib::asio::io_context * io_context_ptr;
82
    /// Type of a shared pointer to the acceptor being used
82
    /// Type of a shared pointer to the acceptor being used
83
    typedef lib::shared_ptr<lib::asio::ip::tcp::acceptor> acceptor_ptr;
83
    typedef lib::shared_ptr<lib::asio::ip::tcp::acceptor> acceptor_ptr;
84
    /// Type of a shared pointer to the resolver being used
84
    /// Type of a shared pointer to the resolver being used
85
    typedef lib::shared_ptr<lib::asio::ip::tcp::resolver> resolver_ptr;
85
    typedef lib::shared_ptr<lib::asio::ip::tcp::resolver> resolver_ptr;
86
    /// Type of timer handle
86
    /// Type of timer handle
87
    typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;
87
    typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;
88
    /// Type of a shared pointer to an io_service work object
88
    /// Type of a shared pointer to an io_context work object
89
    typedef lib::shared_ptr<lib::asio::io_service::work> work_ptr;
89
    typedef lib::shared_ptr<lib::asio::executor_work_guard<lib::asio::io_context::executor_type>> work_guard_ptr;
90
90
91
    /// Type of socket pre-bind handler
91
    /// Type of socket pre-bind handler
92
    typedef lib::function<lib::error_code(acceptor_ptr)> tcp_pre_bind_handler;
92
    typedef lib::function<lib::error_code(acceptor_ptr)> tcp_pre_bind_handler;
93
93
94
    // generate and manage our own io_service
94
    // generate and manage our own io_context
95
    explicit endpoint()
95
    explicit endpoint()
96
      : m_io_service(NULL)
96
      : m_io_context(NULL)
97
      , m_external_io_service(false)
97
      , m_external_io_context(false)
98
      , m_listen_backlog(lib::asio::socket_base::max_connections)
98
      , m_listen_backlog(lib::asio::socket_base::max_listen_connections)
99
      , m_reuse_addr(false)
99
      , m_reuse_addr(false)
100
      , m_state(UNINITIALIZED)
100
      , m_state(UNINITIALIZED)
101
    {
101
    {
Lines 103-116 public: Link Here
103
    }
103
    }
104
104
105
    ~endpoint() {
105
    ~endpoint() {
106
        // clean up our io_service if we were initialized with an internal one.
106
        // clean up our io_context if we were initialized with an internal one.
107
107
108
        // Explicitly destroy local objects
108
        // Explicitly destroy local objects
109
        m_acceptor.reset();
109
        m_acceptor.reset();
110
        m_resolver.reset();
110
        m_resolver.reset();
111
        m_work.reset();
111
        m_work_guard.reset();
112
        if (m_state != UNINITIALIZED && !m_external_io_service) {
112
        if (m_state != UNINITIALIZED && !m_external_io_context) {
113
            delete m_io_service;
113
            delete m_io_context;
114
        }
114
        }
115
    }
115
    }
116
116
Lines 132-165 public: Link Here
132
      : config::socket_type(std::move(src))
132
      : config::socket_type(std::move(src))
133
      , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler)
133
      , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler)
134
      , m_tcp_post_init_handler(src.m_tcp_post_init_handler)
134
      , m_tcp_post_init_handler(src.m_tcp_post_init_handler)
135
      , m_io_service(src.m_io_service)
135
      , m_io_context(src.m_io_context)
136
      , m_external_io_service(src.m_external_io_service)
136
      , m_external_io_context(src.m_external_io_context)
137
      , m_acceptor(src.m_acceptor)
137
      , m_acceptor(src.m_acceptor)
138
      , m_listen_backlog(lib::asio::socket_base::max_connections)
138
      , m_listen_backlog(lib::asio::socket_base::max_listen_connections)
139
      , m_reuse_addr(src.m_reuse_addr)
139
      , m_reuse_addr(src.m_reuse_addr)
140
      , m_elog(src.m_elog)
140
      , m_elog(src.m_elog)
141
      , m_alog(src.m_alog)
141
      , m_alog(src.m_alog)
142
      , m_state(src.m_state)
142
      , m_state(src.m_state)
143
    {
143
    {
144
        src.m_io_service = NULL;
144
        src.m_io_context = NULL;
145
        src.m_external_io_service = false;
145
        src.m_external_io_context = false;
146
        src.m_acceptor = NULL;
146
        src.m_acceptor = NULL;
147
        src.m_state = UNINITIALIZED;
147
        src.m_state = UNINITIALIZED;
148
    }
148
    }
149
149
150
    /*endpoint & operator= (const endpoint && rhs) {
150
    /*endpoint & operator= (const endpoint && rhs) {
151
        if (this != &rhs) {
151
        if (this != &rhs) {
152
            m_io_service = rhs.m_io_service;
152
            m_io_context = rhs.m_io_context;
153
            m_external_io_service = rhs.m_external_io_service;
153
            m_external_io_context = rhs.m_external_io_context;
154
            m_acceptor = rhs.m_acceptor;
154
            m_acceptor = rhs.m_acceptor;
155
            m_listen_backlog = rhs.m_listen_backlog;
155
            m_listen_backlog = rhs.m_listen_backlog;
156
            m_reuse_addr = rhs.m_reuse_addr;
156
            m_reuse_addr = rhs.m_reuse_addr;
157
            m_state = rhs.m_state;
157
            m_state = rhs.m_state;
158
158
159
            rhs.m_io_service = NULL;
159
            rhs.m_io_context = NULL;
160
            rhs.m_external_io_service = false;
160
            rhs.m_external_io_context = false;
161
            rhs.m_acceptor = NULL;
161
            rhs.m_acceptor = NULL;
162
            rhs.m_listen_backlog = lib::asio::socket_base::max_connections;
162
            rhs.m_listen_backlog = lib::asio::socket_base::max_listen_connections;
163
            rhs.m_state = UNINITIALIZED;
163
            rhs.m_state = UNINITIALIZED;
164
            
164
            
165
            // TODO: this needs to be updated
165
            // TODO: this needs to be updated
Lines 173-188 public: Link Here
173
        return socket_type::is_secure();
173
        return socket_type::is_secure();
174
    }
174
    }
175
175
176
    /// initialize asio transport with external io_service (exception free)
176
    /// initialize asio transport with external io_context (exception free)
177
    /**
177
    /**
178
     * Initialize the ASIO transport policy for this endpoint using the provided
178
     * Initialize the ASIO transport policy for this endpoint using the provided
179
     * io_service object. asio_init must be called exactly once on any endpoint
179
     * io_context object. asio_init must be called exactly once on any endpoint
180
     * that uses transport::asio before it can be used.
180
     * that uses transport::asio before it can be used.
181
     *
181
     *
182
     * @param ptr A pointer to the io_service to use for asio events
182
     * @param ptr A pointer to the io_context to use for asio events
183
     * @param ec Set to indicate what error occurred, if any.
183
     * @param ec Set to indicate what error occurred, if any.
184
     */
184
     */
185
    void init_asio(io_service_ptr ptr, lib::error_code & ec) {
185
    void init_asio(io_context_ptr ptr, lib::error_code & ec) {
186
        if (m_state != UNINITIALIZED) {
186
        if (m_state != UNINITIALIZED) {
187
            m_elog->write(log::elevel::library,
187
            m_elog->write(log::elevel::library,
188
                "asio::init_asio called from the wrong state");
188
                "asio::init_asio called from the wrong state");
Lines 193-226 public: Link Here
193
193
194
        m_alog->write(log::alevel::devel,"asio::init_asio");
194
        m_alog->write(log::alevel::devel,"asio::init_asio");
195
195
196
        m_io_service = ptr;
196
        m_io_context = ptr;
197
        m_external_io_service = true;
197
        m_external_io_context = true;
198
        m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service));
198
        m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_context));
199
199
200
        m_state = READY;
200
        m_state = READY;
201
        ec = lib::error_code();
201
        ec = lib::error_code();
202
    }
202
    }
203
203
204
    /// initialize asio transport with external io_service
204
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
205
    /// initialize asio transport with external io_context
205
    /**
206
    /**
206
     * Initialize the ASIO transport policy for this endpoint using the provided
207
     * Initialize the ASIO transport policy for this endpoint using the provided
207
     * io_service object. asio_init must be called exactly once on any endpoint
208
     * io_context object. asio_init must be called exactly once on any endpoint
208
     * that uses transport::asio before it can be used.
209
     * that uses transport::asio before it can be used.
209
     *
210
     *
210
     * @param ptr A pointer to the io_service to use for asio events
211
     * @param ptr A pointer to the io_context to use for asio events
211
     */
212
     */
212
    void init_asio(io_service_ptr ptr) {
213
    void init_asio(io_context_ptr ptr) {
213
        lib::error_code ec;
214
        lib::error_code ec;
214
        init_asio(ptr,ec);
215
        init_asio(ptr,ec);
215
        if (ec) { throw exception(ec); }
216
        if (ec) { throw exception(ec); }
216
    }
217
    }
218
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
217
219
218
    /// Initialize asio transport with internal io_service (exception free)
220
    /// Initialize asio transport with internal io_context (exception free)
219
    /**
221
    /**
220
     * This method of initialization will allocate and use an internally managed
222
     * This method of initialization will allocate and use an internally managed
221
     * io_service.
223
     * io_context.
222
     *
224
     *
223
     * @see init_asio(io_service_ptr ptr)
225
     * @see init_asio(io_context_ptr ptr)
224
     *
226
     *
225
     * @param ec Set to indicate what error occurred, if any.
227
     * @param ec Set to indicate what error occurred, if any.
226
     */
228
     */
Lines 230-250 public: Link Here
230
        // TODO: remove the use of auto_ptr when C++98/03 support is no longer
232
        // TODO: remove the use of auto_ptr when C++98/03 support is no longer
231
        //       necessary.
233
        //       necessary.
232
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
234
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
233
        lib::unique_ptr<lib::asio::io_service> service(new lib::asio::io_service());
235
        lib::unique_ptr<lib::asio::io_context> context(new lib::asio::io_context());
234
#else
236
#else
235
        lib::auto_ptr<lib::asio::io_service> service(new lib::asio::io_service());
237
        lib::auto_ptr<lib::asio::io_context> context(new lib::asio::io_context());
236
#endif
238
#endif
237
        init_asio(service.get(), ec);
239
        init_asio(context.get(), ec);
238
        if( !ec ) service.release(); // Call was successful, transfer ownership
240
        if( !ec ) context.release(); // Call was successful, transfer ownership
239
        m_external_io_service = false;
241
        m_external_io_context = false;
240
    }
242
    }
241
243
242
    /// Initialize asio transport with internal io_service
244
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
245
    /// Initialize asio transport with internal io_context
243
    /**
246
    /**
244
     * This method of initialization will allocate and use an internally managed
247
     * This method of initialization will allocate and use an internally managed
245
     * io_service.
248
     * io_context.
246
     *
249
     *
247
     * @see init_asio(io_service_ptr ptr)
250
     * @see init_asio(io_context_ptr ptr)
248
     */
251
     */
249
    void init_asio() {
252
    void init_asio() {
250
        // Use a smart pointer until the call is successful and ownership has 
253
        // Use a smart pointer until the call is successful and ownership has 
Lines 252-266 public: Link Here
252
        // TODO: remove the use of auto_ptr when C++98/03 support is no longer
255
        // TODO: remove the use of auto_ptr when C++98/03 support is no longer
253
        //       necessary.
256
        //       necessary.
254
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
257
#ifdef _WEBSOCKETPP_CPP11_MEMORY_
255
        lib::unique_ptr<lib::asio::io_service> service(new lib::asio::io_service());
258
        lib::unique_ptr<lib::asio::io_context> context(new lib::asio::io_context());
256
#else
259
#else
257
        lib::auto_ptr<lib::asio::io_service> service(new lib::asio::io_service());
260
        lib::auto_ptr<lib::asio::io_context> context(new lib::asio::io_context());
258
#endif
261
#endif
259
        init_asio( service.get() );
262
        init_asio( context.get() );
260
        // If control got this far without an exception, then ownership has successfully been taken
263
        // If control got this far without an exception, then ownership has successfully been taken
261
        service.release();
264
        context.release();
262
        m_external_io_service = false;
265
        m_external_io_context = false;
263
    }
266
    }
267
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
264
268
265
    /// Sets the tcp pre bind handler
269
    /// Sets the tcp pre bind handler
266
    /**
270
    /**
Lines 330-336 public: Link Here
330
     *
334
     *
331
     * New values affect future calls to listen only.
335
     * New values affect future calls to listen only.
332
     *
336
     *
333
     * The default value is specified as *::asio::socket_base::max_connections
337
     * The default value is specified as *::asio::socket_base::max_listen_connections
334
     * which uses the operating system defined maximum queue length. Your OS
338
     * which uses the operating system defined maximum queue length. Your OS
335
     * may restrict or silently lower this value. A value of zero may cause
339
     * may restrict or silently lower this value. A value of zero may cause
336
     * all connections to be rejected.
340
     * all connections to be rejected.
Lines 364-382 public: Link Here
364
        m_reuse_addr = value;
368
        m_reuse_addr = value;
365
    }
369
    }
366
370
367
    /// Retrieve a reference to the endpoint's io_service
371
    /// Retrieve a reference to the endpoint's io_context
368
    /**
372
    /**
369
     * The io_service may be an internal or external one. This may be used to
373
     * The io_context may be an internal or external one. This may be used to
370
     * call methods of the io_service that are not explicitly wrapped by the
374
     * call methods of the io_context that are not explicitly wrapped by the
371
     * endpoint.
375
     * endpoint.
372
     *
376
     *
373
     * This method is only valid after the endpoint has been initialized with
377
     * This method is only valid after the endpoint has been initialized with
374
     * `init_asio`. No error will be returned if it isn't.
378
     * `init_asio`. No error will be returned if it isn't.
375
     *
379
     *
376
     * @return A reference to the endpoint's io_service
380
     * @return A reference to the endpoint's io_context
377
     */
381
     */
378
    lib::asio::io_service & get_io_service() {
382
    lib::asio::io_context & get_io_context() {
379
        return *m_io_service;
383
        return *m_io_context;
380
    }
384
    }
381
    
385
    
382
    /// Get local TCP endpoint
386
    /// Get local TCP endpoint
Lines 449-468 public: Link Here
449
        ec = lib::error_code();
453
        ec = lib::error_code();
450
    }
454
    }
451
455
452
453
454
    /// Set up endpoint for listening manually
455
    /**
456
     * Bind the internal acceptor using the settings specified by the endpoint e
457
     *
458
     * @param ep An endpoint to read settings from
459
     */
460
    void listen(lib::asio::ip::tcp::endpoint const & ep) {
461
        lib::error_code ec;
462
        listen(ep,ec);
463
        if (ec) { throw exception(ec); }
464
    }
465
466
    /// Set up endpoint for listening with protocol and port (exception free)
456
    /// Set up endpoint for listening with protocol and port (exception free)
467
    /**
457
    /**
468
     * Bind the internal acceptor using the given internet protocol and port.
458
     * Bind the internal acceptor using the given internet protocol and port.
Lines 485-510 public: Link Here
485
        listen(ep,ec);
475
        listen(ep,ec);
486
    }
476
    }
487
477
488
    /// Set up endpoint for listening with protocol and port
489
    /**
490
     * Bind the internal acceptor using the given internet protocol and port.
491
     * The endpoint must have been initialized by calling init_asio before
492
     * listening.
493
     *
494
     * Common options include:
495
     * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6()
496
     * - IPv4 only: lib::asio::ip::tcp::v4()
497
     *
498
     * @param internet_protocol The internet protocol to use.
499
     * @param port The port to listen on.
500
     */
501
    template <typename InternetProtocol>
502
    void listen(InternetProtocol const & internet_protocol, uint16_t port)
503
    {
504
        lib::asio::ip::tcp::endpoint ep(internet_protocol, port);
505
        listen(ep);
506
    }
507
508
    /// Set up endpoint for listening on a port (exception free)
478
    /// Set up endpoint for listening on a port (exception free)
509
    /**
479
    /**
510
     * Bind the internal acceptor using the given port. The IPv6 protocol with
480
     * Bind the internal acceptor using the given port. The IPv6 protocol with
Lines 521-552 public: Link Here
521
        listen(lib::asio::ip::tcp::v6(), port, ec);
491
        listen(lib::asio::ip::tcp::v6(), port, ec);
522
    }
492
    }
523
493
524
    /// Set up endpoint for listening on a port
525
    /**
526
     * Bind the internal acceptor using the given port. The IPv6 protocol with
527
     * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use
528
     * the overload that allows specifying the protocol explicitly.
529
     *
530
     * The endpoint must have been initialized by calling init_asio before
531
     * listening.
532
     *
533
     * @param port The port to listen on.
534
     * @param ec Set to indicate what error occurred, if any.
535
     */
536
    void listen(uint16_t port) {
537
        listen(lib::asio::ip::tcp::v6(), port);
538
    }
539
540
    /// Set up endpoint for listening on a host and service (exception free)
494
    /// Set up endpoint for listening on a host and service (exception free)
541
    /**
495
    /**
542
     * Bind the internal acceptor using the given host and service. More details
496
     * Bind the internal acceptor using the given host and service. More details
543
     * about what host and service can be are available in the Asio
497
     * about what host and service can be are available in the Asio
544
     * documentation for ip::basic_resolver_query::basic_resolver_query's
498
     * documentation for the ip::basic_resolver::resolve function.
545
     * constructors.
546
     *
499
     *
547
     * The endpoint must have been initialized by calling init_asio before
500
     * The endpoint must have been initialized by calling init_asio before
548
     * listening.
501
     * listening.
549
     *
502
     *
503
     * Once listening the underlying io_context will be kept open indefinitely.
504
     * Calling endpoint::stop_listening will stop the endpoint from accepting
505
     * new connections. See the documentation for stop listening for more details
506
     * about shutting down Asio Transport based endpoints.
507
     *
508
     * @see stop_listening(lib::error_code &)
509
     *
550
     * @param host A string identifying a location. May be a descriptive name or
510
     * @param host A string identifying a location. May be a descriptive name or
551
     * a numeric address string.
511
     * a numeric address string.
552
     * @param service A string identifying the requested service. This may be a
512
     * @param service A string identifying the requested service. This may be a
Lines 557-602 public: Link Here
557
        lib::error_code & ec)
517
        lib::error_code & ec)
558
    {
518
    {
559
        using lib::asio::ip::tcp;
519
        using lib::asio::ip::tcp;
560
        tcp::resolver r(*m_io_service);
520
        tcp::resolver r(*m_io_context);
561
        tcp::resolver::query query(host, service);
521
        tcp::resolver::results_type results = r.resolve(host, service);
562
        tcp::resolver::iterator endpoint_iterator = r.resolve(query);
522
        if (results.empty()) {
563
        tcp::resolver::iterator end;
564
        if (endpoint_iterator == end) {
565
            m_elog->write(log::elevel::library,
523
            m_elog->write(log::elevel::library,
566
                "asio::listen could not resolve the supplied host or service");
524
                "asio::listen could not resolve the supplied host or service");
567
            ec = make_error_code(error::invalid_host_service);
525
            ec = make_error_code(error::invalid_host_service);
568
            return;
526
            return;
569
        }
527
        }
570
        listen(*endpoint_iterator,ec);
528
        listen(*(results.begin()),ec);
571
    }
529
    }
572
530
573
    /// Set up endpoint for listening on a host and service
531
    /// Stop listening (exception free)
574
    /**
532
    /**
575
     * Bind the internal acceptor using the given host and service. More details
533
     * Stop listening and accepting new connections.
576
     * about what host and service can be are available in the Asio
577
     * documentation for ip::basic_resolver_query::basic_resolver_query's
578
     * constructors.
579
     *
534
     *
580
     * The endpoint must have been initialized by calling init_asio before
535
     * If the endpoint needs to shut down fully (i.e. close all connections)
581
     * listening.
536
     * this member function is necessary but not sufficient. In addition to
537
     * stopping listening, individual connections will need to be ended via 
538
     * their respective connection::close.
582
     *
539
     *
583
     * @param host A string identifying a location. May be a descriptive name or
540
     * For more details on clean closing, please refer to @ref clean_close
584
     * a numeric address string.
541
     * "Cleanly closing Asio Transport based endpoints"
585
     * @param service A string identifying the requested service. This may be a
586
     * descriptive name or a numeric string corresponding to a port number.
587
     * @param ec Set to indicate what error occurred, if any.
588
     */
589
    void listen(std::string const & host, std::string const & service)
590
    {
591
        lib::error_code ec;
592
        listen(host,service,ec);
593
        if (ec) { throw exception(ec); }
594
    }
595
596
    /// Stop listening (exception free)
597
    /**
598
     * Stop listening and accepting new connections. This will not end any
599
     * existing connections.
600
     *
542
     *
601
     * @since 0.3.0-alpha4
543
     * @since 0.3.0-alpha4
602
     * @param ec A status code indicating an error, if any.
544
     * @param ec A status code indicating an error, if any.
Lines 615-620 public: Link Here
615
        ec = lib::error_code();
557
        ec = lib::error_code();
616
    }
558
    }
617
559
560
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
561
    // if exceptions are avaliable, define listen overloads that use them
562
563
    /// Set up endpoint for listening manually
564
    /**
565
     * Bind the internal acceptor using the settings specified by the endpoint e
566
     *
567
     * @param ep An endpoint to read settings from
568
     */
569
    void listen(lib::asio::ip::tcp::endpoint const & ep) {
570
        lib::error_code ec;
571
        listen(ep,ec);
572
        if (ec) { throw exception(ec); }
573
    }
574
575
    /// Set up endpoint for listening with protocol and port
576
    /**
577
     * Bind the internal acceptor using the given internet protocol and port.
578
     * The endpoint must have been initialized by calling init_asio before
579
     * listening.
580
     *
581
     * Common options include:
582
     * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6()
583
     * - IPv4 only: lib::asio::ip::tcp::v4()
584
     *
585
     * @param internet_protocol The internet protocol to use.
586
     * @param port The port to listen on.
587
     */
588
    template <typename InternetProtocol>
589
    void listen(InternetProtocol const & internet_protocol, uint16_t port)
590
    {
591
        lib::asio::ip::tcp::endpoint ep(internet_protocol, port);
592
        listen(ep);
593
    }
594
595
    /// Set up endpoint for listening on a port
596
    /**
597
     * Bind the internal acceptor using the given port. The IPv6 protocol with
598
     * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use
599
     * the overload that allows specifying the protocol explicitly.
600
     *
601
     * The endpoint must have been initialized by calling init_asio before
602
     * listening.
603
     *
604
     * @param port The port to listen on.
605
     * @param ec Set to indicate what error occurred, if any.
606
     */
607
    void listen(uint16_t port) {
608
        listen(lib::asio::ip::tcp::v6(), port);
609
    }
610
611
    /// Set up endpoint for listening on a host and service
612
    /**
613
     * Bind the internal acceptor using the given host and service. More 
614
     * details about what host and service can be are available in the Asio
615
     * documentation for the ip::basic_resolver::resolve function.
616
     *
617
     * The endpoint must have been initialized by calling init_asio before
618
     * listening.
619
     *
620
     * Once listening the underlying io_context will be kept open indefinitely.
621
     * Calling endpoint::stop_listening will stop the endpoint from accepting
622
     * new connections. See the documentation for stop listening for more
623
     * details about shutting down Asio Transport based endpoints.
624
     *
625
     * @see stop_listening()
626
     *
627
     * @param host A string identifying a location. May be a descriptive name 
628
     * or a numeric address string.
629
     * @param service A string identifying the requested service. This may be a
630
     * descriptive name or a numeric string corresponding to a port number.
631
     * @param ec Set to indicate what error occurred, if any.
632
     */
633
    void listen(std::string const & host, std::string const & service)
634
    {
635
        lib::error_code ec;
636
        listen(host,service,ec);
637
        if (ec) { throw exception(ec); }
638
    }
639
618
    /// Stop listening
640
    /// Stop listening
619
    /**
641
    /**
620
     * Stop listening and accepting new connections. This will not end any
642
     * Stop listening and accepting new connections. This will not end any
Lines 627-632 public: Link Here
627
        stop_listening(ec);
649
        stop_listening(ec);
628
        if (ec) { throw exception(ec); }
650
        if (ec) { throw exception(ec); }
629
    }
651
    }
652
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
630
653
631
    /// Check if the endpoint is listening
654
    /// Check if the endpoint is listening
632
    /**
655
    /**
Lines 636-677 public: Link Here
636
        return (m_state == LISTENING);
659
        return (m_state == LISTENING);
637
    }
660
    }
638
661
639
    /// wraps the run method of the internal io_service object
662
    /// wraps the run method of the internal io_context object
640
    std::size_t run() {
663
    std::size_t run() {
641
        return m_io_service->run();
664
        return m_io_context->run();
642
    }
665
    }
643
666
644
    /// wraps the run_one method of the internal io_service object
667
    /// wraps the run_one method of the internal io_context object
645
    /**
668
    /**
646
     * @since 0.3.0-alpha4
669
     * @since 0.3.0-alpha4
647
     */
670
     */
648
    std::size_t run_one() {
671
    std::size_t run_one() {
649
        return m_io_service->run_one();
672
        return m_io_context->run_one();
650
    }
673
    }
651
674
652
    /// wraps the stop method of the internal io_service object
675
    /// wraps the stop method of the internal io_context object
653
    void stop() {
676
    void stop() {
654
        m_io_service->stop();
677
        m_io_context->stop();
655
    }
678
    }
656
679
657
    /// wraps the poll method of the internal io_service object
680
    /// wraps the poll method of the internal io_context object
658
    std::size_t poll() {
681
    std::size_t poll() {
659
        return m_io_service->poll();
682
        return m_io_context->poll();
660
    }
683
    }
661
684
662
    /// wraps the poll_one method of the internal io_service object
685
    /// wraps the poll_one method of the internal io_context object
663
    std::size_t poll_one() {
686
    std::size_t poll_one() {
664
        return m_io_service->poll_one();
687
        return m_io_context->poll_one();
665
    }
688
    }
666
689
667
    /// wraps the reset method of the internal io_service object
690
    /// wraps the restart method of the internal io_context object
668
    void reset() {
691
    void reset() {
669
        m_io_service->reset();
692
        m_io_context->restart();
670
    }
693
    }
671
694
672
    /// wraps the stopped method of the internal io_service object
695
    /// wraps the stopped method of the internal io_context object
673
    bool stopped() const {
696
    bool stopped() const {
674
        return m_io_service->stopped();
697
        return m_io_context->stopped();
675
    }
698
    }
676
699
677
    /// Marks the endpoint as perpetual, stopping it from exiting when empty
700
    /// Marks the endpoint as perpetual, stopping it from exiting when empty
Lines 687-693 public: Link Here
687
     * @since 0.3.0
710
     * @since 0.3.0
688
     */
711
     */
689
    void start_perpetual() {
712
    void start_perpetual() {
690
        m_work.reset(new lib::asio::io_service::work(*m_io_service));
713
        m_work_guard.reset(new lib::asio::executor_work_guard<lib::asio::io_context::executor_type>(m_io_context->get_executor()));
691
    }
714
    }
692
715
693
    /// Clears the endpoint's perpetual flag, allowing it to exit when empty
716
    /// Clears the endpoint's perpetual flag, allowing it to exit when empty
Lines 699-705 public: Link Here
699
     * @since 0.3.0
722
     * @since 0.3.0
700
     */
723
     */
701
    void stop_perpetual() {
724
    void stop_perpetual() {
702
        m_work.reset();
725
        m_work_guard.reset();
703
    }
726
    }
704
727
705
    /// Call back a function after a period of time.
728
    /// Call back a function after a period of time.
Lines 716-722 public: Link Here
716
     */
739
     */
717
    timer_ptr set_timer(long duration, timer_handler callback) {
740
    timer_ptr set_timer(long duration, timer_handler callback) {
718
        timer_ptr new_timer = lib::make_shared<lib::asio::steady_timer>(
741
        timer_ptr new_timer = lib::make_shared<lib::asio::steady_timer>(
719
            *m_io_service,
742
            *m_io_context,
720
             lib::asio::milliseconds(duration)
743
             lib::asio::milliseconds(duration)
721
        );
744
        );
722
745
Lines 779-785 public: Link Here
779
        if (config::enable_multithreading) {
802
        if (config::enable_multithreading) {
780
            m_acceptor->async_accept(
803
            m_acceptor->async_accept(
781
                tcon->get_raw_socket(),
804
                tcon->get_raw_socket(),
782
                tcon->get_strand()->wrap(lib::bind(
805
                lib::asio::bind_executor(*tcon->get_strand(), lib::bind(
783
                    &type::handle_accept,
806
                    &type::handle_accept,
784
                    this,
807
                    this,
785
                    callback,
808
                    callback,
Lines 799-804 public: Link Here
799
        }
822
        }
800
    }
823
    }
801
824
825
#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_
802
    /// Accept the next connection attempt and assign it to con.
826
    /// Accept the next connection attempt and assign it to con.
803
    /**
827
    /**
804
     * @param tcon The connection to accept into.
828
     * @param tcon The connection to accept into.
Lines 809-814 public: Link Here
809
        async_accept(tcon,callback,ec);
833
        async_accept(tcon,callback,ec);
810
        if (ec) { throw exception(ec); }
834
        if (ec) { throw exception(ec); }
811
    }
835
    }
836
#endif // _WEBSOCKETPP_NO_EXCEPTIONS_
812
protected:
837
protected:
813
    /// Initialize logging
838
    /// Initialize logging
814
    /**
839
    /**
Lines 851-857 protected: Link Here
851
876
852
        // Create a resolver
877
        // Create a resolver
853
        if (!m_resolver) {
878
        if (!m_resolver) {
854
            m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service));
879
            m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_context));
855
        }
880
        }
856
881
857
        tcon->set_uri(u);
882
        tcon->set_uri(u);
Lines 883-890 protected: Link Here
883
            port = pu->get_port_str();
908
            port = pu->get_port_str();
884
        }
909
        }
885
910
886
        tcp::resolver::query query(host,port);
887
888
        if (m_alog->static_test(log::alevel::devel)) {
911
        if (m_alog->static_test(log::alevel::devel)) {
889
            m_alog->write(log::alevel::devel,
912
            m_alog->write(log::alevel::devel,
890
                "starting async DNS resolve for "+host+":"+port);
913
                "starting async DNS resolve for "+host+":"+port);
Lines 905-912 protected: Link Here
905
928
906
        if (config::enable_multithreading) {
929
        if (config::enable_multithreading) {
907
            m_resolver->async_resolve(
930
            m_resolver->async_resolve(
908
                query,
931
                host,
909
                tcon->get_strand()->wrap(lib::bind(
932
                port,
933
                lib::asio::bind_executor(*tcon->get_strand(), lib::bind(
910
                    &type::handle_resolve,
934
                    &type::handle_resolve,
911
                    this,
935
                    this,
912
                    tcon,
936
                    tcon,
Lines 918-924 protected: Link Here
918
            );
942
            );
919
        } else {
943
        } else {
920
            m_resolver->async_resolve(
944
            m_resolver->async_resolve(
921
                query,
945
                host,
946
                port,
922
                lib::bind(
947
                lib::bind(
923
                    &type::handle_resolve,
948
                    &type::handle_resolve,
924
                    this,
949
                    this,
Lines 966-975 protected: Link Here
966
991
967
    void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer,
992
    void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer,
968
        connect_handler callback, lib::asio::error_code const & ec,
993
        connect_handler callback, lib::asio::error_code const & ec,
969
        lib::asio::ip::tcp::resolver::iterator iterator)
994
        lib::asio::ip::tcp::resolver::results_type results)
970
    {
995
    {
971
        if (ec == lib::asio::error::operation_aborted ||
996
        if (ec == lib::asio::error::operation_aborted ||
972
            lib::asio::is_neg(dns_timer->expires_from_now()))
997
            lib::asio::is_neg(dns_timer->expiry() - timer_ptr::element_type::clock_type::now()))
973
        {
998
        {
974
            m_alog->write(log::alevel::devel,"async_resolve cancelled");
999
            m_alog->write(log::alevel::devel,"async_resolve cancelled");
975
            return;
1000
            return;
Lines 987-994 protected: Link Here
987
            std::stringstream s;
1012
            std::stringstream s;
988
            s << "Async DNS resolve successful. Results: ";
1013
            s << "Async DNS resolve successful. Results: ";
989
1014
990
            lib::asio::ip::tcp::resolver::iterator it, end;
1015
            lib::asio::ip::tcp::resolver::results_type::iterator it;
991
            for (it = iterator; it != end; ++it) {
1016
            for (it = results.begin(); it != results.end(); ++it) {
992
                s << (*it).endpoint() << " ";
1017
                s << (*it).endpoint() << " ";
993
            }
1018
            }
994
1019
Lines 1014-1021 protected: Link Here
1014
        if (config::enable_multithreading) {
1039
        if (config::enable_multithreading) {
1015
            lib::asio::async_connect(
1040
            lib::asio::async_connect(
1016
                tcon->get_raw_socket(),
1041
                tcon->get_raw_socket(),
1017
                iterator,
1042
                results,
1018
                tcon->get_strand()->wrap(lib::bind(
1043
                lib::asio::bind_executor(*tcon->get_strand(), lib::bind(
1019
                    &type::handle_connect,
1044
                    &type::handle_connect,
1020
                    this,
1045
                    this,
1021
                    tcon,
1046
                    tcon,
Lines 1027-1033 protected: Link Here
1027
        } else {
1052
        } else {
1028
            lib::asio::async_connect(
1053
            lib::asio::async_connect(
1029
                tcon->get_raw_socket(),
1054
                tcon->get_raw_socket(),
1030
                iterator,
1055
                results,
1031
                lib::bind(
1056
                lib::bind(
1032
                    &type::handle_connect,
1057
                    &type::handle_connect,
1033
                    this,
1058
                    this,
Lines 1077-1083 protected: Link Here
1077
        connect_handler callback, lib::asio::error_code const & ec)
1102
        connect_handler callback, lib::asio::error_code const & ec)
1078
    {
1103
    {
1079
        if (ec == lib::asio::error::operation_aborted ||
1104
        if (ec == lib::asio::error::operation_aborted ||
1080
            lib::asio::is_neg(con_timer->expires_from_now()))
1105
            lib::asio::is_neg(con_timer->expiry() - timer_ptr::element_type::clock_type::now()))
1081
        {
1106
        {
1082
            m_alog->write(log::alevel::devel,"async_connect cancelled");
1107
            m_alog->write(log::alevel::devel,"async_connect cancelled");
1083
            return;
1108
            return;
Lines 1119-1125 protected: Link Here
1119
1144
1120
        lib::error_code ec;
1145
        lib::error_code ec;
1121
1146
1122
        ec = tcon->init_asio(m_io_service);
1147
        ec = tcon->init_asio(m_io_context);
1123
        if (ec) {return ec;}
1148
        if (ec) {return ec;}
1124
1149
1125
        tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler);
1150
        tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler);
Lines 1158-1168 private: Link Here
1158
    tcp_init_handler    m_tcp_post_init_handler;
1183
    tcp_init_handler    m_tcp_post_init_handler;
1159
1184
1160
    // Network Resources
1185
    // Network Resources
1161
    io_service_ptr      m_io_service;
1186
    io_context_ptr      m_io_context;
1162
    bool                m_external_io_service;
1187
    bool                m_external_io_context;
1163
    acceptor_ptr        m_acceptor;
1188
    acceptor_ptr        m_acceptor;
1164
    resolver_ptr        m_resolver;
1189
    resolver_ptr        m_resolver;
1165
    work_ptr            m_work;
1190
    work_guard_ptr      m_work_guard;
1166
1191
1167
    // Network constants
1192
    // Network constants
1168
    int                 m_listen_backlog;
1193
    int                 m_listen_backlog;
(-)websocketpp-zaphoyd/websocketpp/transport/asio/security/none.hpp (-13 / +14 lines)
Lines 62-71 public: Link Here
62
    /// Type of a shared pointer to this connection socket component
62
    /// Type of a shared pointer to this connection socket component
63
    typedef lib::shared_ptr<type> ptr;
63
    typedef lib::shared_ptr<type> ptr;
64
64
65
    /// Type of a pointer to the Asio io_service being used
65
    /// Type of a pointer to the Asio io_context being used
66
    typedef lib::asio::io_service* io_service_ptr;
66
    typedef lib::asio::io_context* io_context_ptr;
67
    /// Type of a pointer to the Asio io_service strand being used
67
    /// Type of a pointer to the Asio io_context strand being used
68
    typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr;
68
    typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr;
69
    /// Type of the ASIO socket being used
69
    /// Type of the ASIO socket being used
70
    typedef lib::asio::ip::tcp::socket socket_type;
70
    typedef lib::asio::ip::tcp::socket socket_type;
71
    /// Type of a shared pointer to the socket being used.
71
    /// Type of a shared pointer to the socket being used.
Lines 156-178 protected: Link Here
156
    /// Perform one time initializations
156
    /// Perform one time initializations
157
    /**
157
    /**
158
     * init_asio is called once immediately after construction to initialize
158
     * init_asio is called once immediately after construction to initialize
159
     * Asio components to the io_service
159
     * Asio components to the io_context. At this stage the connection is
160
     * speculative, the server may not have actually received a new connection.
160
     *
161
     *
161
     * @param service A pointer to the endpoint's io_service
162
     * @param context A pointer to the endpoint's io_context
162
     * @param strand A shared pointer to the connection's asio strand
163
     * @param strand A shared pointer to the connection's asio strand
163
     * @param is_server Whether or not the endpoint is a server or not.
164
     * @param is_server Whether or not the endpoint is a server or not.
164
     */
165
     */
165
    lib::error_code init_asio (io_service_ptr service, strand_ptr, bool)
166
    lib::error_code init_asio (io_context_ptr context, strand_ptr, bool)
166
    {
167
    {
167
        if (m_state != UNINITIALIZED) {
168
        if (m_state != UNINITIALIZED) {
168
            return socket::make_error_code(socket::error::invalid_state);
169
            return socket::make_error_code(socket::error::invalid_state);
169
        }
170
        }
170
171
171
        m_socket.reset(new lib::asio::ip::tcp::socket(*service));
172
        m_socket.reset(new lib::asio::ip::tcp::socket(*context));
172
173
        if (m_socket_init_handler) {
174
            m_socket_init_handler(m_hdl, *m_socket);
175
        }
176
173
177
        m_state = READY;
174
        m_state = READY;
178
175
Lines 194-200 protected: Link Here
194
191
195
    /// Pre-initialize security policy
192
    /// Pre-initialize security policy
196
    /**
193
    /**
197
     * Called by the transport after a new connection is created to initialize
194
     * Called by the transport after a new connection is accepted to initialize
198
     * the socket component of the connection. This method is not allowed to
195
     * the socket component of the connection. This method is not allowed to
199
     * write any bytes to the wire. This initialization happens before any
196
     * write any bytes to the wire. This initialization happens before any
200
     * proxies or other intermediate wrappers are negotiated.
197
     * proxies or other intermediate wrappers are negotiated.
Lines 207-212 protected: Link Here
207
            return;
204
            return;
208
        }
205
        }
209
206
207
        if (m_socket_init_handler) {
208
            m_socket_init_handler(m_hdl, *m_socket);
209
        }
210
210
        m_state = READING;
211
        m_state = READING;
211
212
212
        callback(lib::error_code());
213
        callback(lib::error_code());
(-)websocketpp-zaphoyd/websocketpp/transport/asio/security/tls.hpp (-21 / +32 lines)
Lines 71-80 public: Link Here
71
    typedef lib::asio::ssl::stream<lib::asio::ip::tcp::socket> socket_type;
71
    typedef lib::asio::ssl::stream<lib::asio::ip::tcp::socket> socket_type;
72
    /// Type of a shared pointer to the ASIO socket being used
72
    /// Type of a shared pointer to the ASIO socket being used
73
    typedef lib::shared_ptr<socket_type> socket_ptr;
73
    typedef lib::shared_ptr<socket_type> socket_ptr;
74
    /// Type of a pointer to the ASIO io_service being used
74
    /// Type of a pointer to the ASIO io_context being used
75
    typedef lib::asio::io_service * io_service_ptr;
75
    typedef lib::asio::io_context * io_context_ptr;
76
    /// Type of a pointer to the ASIO io_service strand being used
76
    /// Type of a pointer to the ASIO io_context strand being used
77
    typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr;
77
    typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr;
78
    /// Type of a shared pointer to the ASIO TLS context being used
78
    /// Type of a shared pointer to the ASIO TLS context being used
79
    typedef lib::shared_ptr<lib::asio::ssl::context> context_ptr;
79
    typedef lib::shared_ptr<lib::asio::ssl::context> context_ptr;
80
80
Lines 176-188 protected: Link Here
176
    /// Perform one time initializations
176
    /// Perform one time initializations
177
    /**
177
    /**
178
     * init_asio is called once immediately after construction to initialize
178
     * init_asio is called once immediately after construction to initialize
179
     * Asio components to the io_service
179
     * Asio components to the io_context
180
     *
180
     *
181
     * @param service A pointer to the endpoint's io_service
181
     * @param context A pointer to the endpoint's io_context
182
     * @param strand A pointer to the connection's strand
182
     * @param strand A pointer to the connection's strand
183
     * @param is_server Whether or not the endpoint is a server or not.
183
     * @param is_server Whether or not the endpoint is a server or not.
184
     */
184
     */
185
    lib::error_code init_asio (io_service_ptr service, strand_ptr strand,
185
    lib::error_code init_asio (io_context_ptr context, strand_ptr strand,
186
        bool is_server)
186
        bool is_server)
187
    {
187
    {
188
        if (!m_tls_init_handler) {
188
        if (!m_tls_init_handler) {
Lines 193-205 protected: Link Here
193
        if (!m_context) {
193
        if (!m_context) {
194
            return socket::make_error_code(socket::error::invalid_tls_context);
194
            return socket::make_error_code(socket::error::invalid_tls_context);
195
        }
195
        }
196
        m_socket.reset(new socket_type(*service, *m_context));
196
        m_socket.reset(new socket_type(*context, *m_context));
197
197
198
        if (m_socket_init_handler) {
198
        m_io_context = context;
199
            m_socket_init_handler(m_hdl, get_socket());
200
        }
201
202
        m_io_service = service;
203
        m_strand = strand;
199
        m_strand = strand;
204
        m_is_server = is_server;
200
        m_is_server = is_server;
205
201
Lines 234-252 protected: Link Here
234
    void pre_init(init_handler callback) {
230
    void pre_init(init_handler callback) {
235
        // TODO: is this the best way to check whether this function is 
231
        // TODO: is this the best way to check whether this function is 
236
        //       available in the version of OpenSSL being used?
232
        //       available in the version of OpenSSL being used?
237
        // TODO: consider case where host is an IP address
238
#if OPENSSL_VERSION_NUMBER >= 0x90812f
233
#if OPENSSL_VERSION_NUMBER >= 0x90812f
239
        if (!m_is_server) {
234
        if (!m_is_server) {
240
            // For clients on systems with a suitable OpenSSL version, set the
235
            // For clients on systems with a suitable OpenSSL version, set the
241
            // TLS SNI hostname header so connecting to TLS servers using SNI
236
            // TLS SNI hostname header so connecting to TLS servers using SNI
242
            // will work.
237
            // will work.
243
            long res = SSL_set_tlsext_host_name(
238
            std::string const & host = m_uri->get_host();
244
                get_socket().native_handle(), m_uri->get_host().c_str());
239
            lib::asio::error_code ec_addr;
245
            if (!(1 == res)) {
240
            
246
                callback(socket::make_error_code(socket::error::tls_failed_sni_hostname));
241
            // run the hostname through make_address to check if it is a valid IP literal
242
            lib::asio::ip::address addr = lib::asio::ip::make_address(host, ec_addr);
243
            (void)addr;
244
            
245
            // If the parsing as an IP literal fails, proceed to register the hostname
246
            // with the TLS handshake via SNI.
247
            // The SNI applies only to DNS host names, not for IP addresses
248
            // See RFC3546 Section 3.1
249
            if (ec_addr) {
250
                long res = SSL_set_tlsext_host_name(
251
                    get_socket().native_handle(), host.c_str());
252
                if (!(1 == res)) {
253
                    callback(socket::make_error_code(socket::error::tls_failed_sni_hostname));
254
                }
247
            }
255
            }
248
        }
256
        }
249
#endif
257
#endif
258
        if (m_socket_init_handler) {
259
            m_socket_init_handler(m_hdl, get_socket());
260
        }
250
261
251
        callback(lib::error_code());
262
        callback(lib::error_code());
252
    }
263
    }
Lines 266-272 protected: Link Here
266
        if (m_strand) {
277
        if (m_strand) {
267
            m_socket->async_handshake(
278
            m_socket->async_handshake(
268
                get_handshake_type(),
279
                get_handshake_type(),
269
                m_strand->wrap(lib::bind(
280
                lib::asio::bind_executor(*m_strand, lib::bind(
270
                    &type::handle_init, get_shared(),
281
                    &type::handle_init, get_shared(),
271
                    callback,
282
                    callback,
272
                    lib::placeholders::_1
283
                    lib::placeholders::_1
Lines 326-332 protected: Link Here
326
337
327
    void async_shutdown(socket::shutdown_handler callback) {
338
    void async_shutdown(socket::shutdown_handler callback) {
328
        if (m_strand) {
339
        if (m_strand) {
329
            m_socket->async_shutdown(m_strand->wrap(callback));
340
            m_socket->async_shutdown(lib::asio::bind_executor(*m_strand, callback));
330
        } else {
341
        } else {
331
            m_socket->async_shutdown(callback);
342
            m_socket->async_shutdown(callback);
332
        }
343
        }
Lines 381-387 private: Link Here
381
        }
392
        }
382
    }
393
    }
383
394
384
    io_service_ptr      m_io_service;
395
    io_context_ptr      m_io_context;
385
    strand_ptr          m_strand;
396
    strand_ptr          m_strand;
386
    context_ptr         m_context;
397
    context_ptr         m_context;
387
    socket_ptr          m_socket;
398
    socket_ptr          m_socket;
(-)websocketpp-zaphoyd/websocketpp/transport/base/endpoint.hpp (+11 lines)
Lines 57-67 namespace websocketpp { Link Here
57
 * is a pointer to the transport connection component of the connection. When
57
 * is a pointer to the transport connection component of the connection. When
58
 * complete, `handler` should be called with the the connection's
58
 * complete, `handler` should be called with the the connection's
59
 * `connection_hdl` and any error that occurred.
59
 * `connection_hdl` and any error that occurred.
60
 * note: optional, client transports only
60
 *
61
 *
62
 * **async_accept**\n
63
 * todo:
64
 * note: optional, server transports only
65
 * 
61
 * **init_logging**
66
 * **init_logging**
62
 * `void init_logging(const lib::shared_ptr<alog_type>& a, const lib::shared_ptr<elog_type>& e)`\n
67
 * `void init_logging(const lib::shared_ptr<alog_type>& a, const lib::shared_ptr<elog_type>& e)`\n
63
 * Called once after construction to provide pointers to the endpoint's access
68
 * Called once after construction to provide pointers to the endpoint's access
64
 * and error loggers. These may be stored and used to log messages or ignored.
69
 * and error loggers. These may be stored and used to log messages or ignored.
70
 * 
71
 * 
72
 * **is_listening**
73
 * `bool is_listening()`
74
 * Server roles only. Called to determine if the server is listening and that calls to
75
 * start_accept / async_accept are valid.
65
 */
76
 */
66
namespace transport {
77
namespace transport {
67
78
(-)websocketpp-zaphoyd/websocketpp/transport/debug/endpoint.hpp (-1 / +1 lines)
Lines 60-66 public: Link Here
60
    /// associated connection transport component
60
    /// associated connection transport component
61
    typedef typename transport_con_type::ptr transport_con_ptr;
61
    typedef typename transport_con_type::ptr transport_con_ptr;
62
62
63
    // generate and manage our own io_service
63
    // generate and manage our own io_context
64
    explicit endpoint()
64
    explicit endpoint()
65
    {
65
    {
66
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
66
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
(-)websocketpp-zaphoyd/websocketpp/transport/iostream/endpoint.hpp (-1 / +1 lines)
Lines 64-70 public: Link Here
64
    /// associated connection transport component
64
    /// associated connection transport component
65
    typedef typename transport_con_type::ptr transport_con_ptr;
65
    typedef typename transport_con_type::ptr transport_con_ptr;
66
66
67
    // generate and manage our own io_service
67
    // generate and manage our own io_context
68
    explicit endpoint() : m_output_stream(NULL), m_is_secure(false)
68
    explicit endpoint() : m_output_stream(NULL), m_is_secure(false)
69
    {
69
    {
70
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
70
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
(-)websocketpp-zaphoyd/websocketpp/transport/stub/endpoint.hpp (-2 / +18 lines)
Lines 60-66 public: Link Here
60
    /// associated connection transport component
60
    /// associated connection transport component
61
    typedef typename transport_con_type::ptr transport_con_ptr;
61
    typedef typename transport_con_type::ptr transport_con_ptr;
62
62
63
    // generate and manage our own io_service
63
    // generate and manage our own io_context
64
    explicit endpoint()
64
    explicit endpoint()
65
    {
65
    {
66
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
66
        //std::cout << "transport::iostream::endpoint constructor" << std::endl;
Lines 89-94 public: Link Here
89
    bool is_secure() const {
89
    bool is_secure() const {
90
        return false;
90
        return false;
91
    }
91
    }
92
93
    /// Tests whether or not the transport is currently listening for new connections
94
    /**
95
     * Server roles only 
96
     */
97
    bool is_listening() const {
98
        return false;
99
    }
92
protected:
100
protected:
93
    /// Initialize logging
101
    /// Initialize logging
94
    /**
102
    /**
Lines 103-109 protected: Link Here
103
     * @param a A pointer to the access logger to use.
111
     * @param a A pointer to the access logger to use.
104
     * @param e A pointer to the error logger to use.
112
     * @param e A pointer to the error logger to use.
105
     */
113
     */
106
    void init_logging(alog_type * a, elog_type * e) {}
114
    void init_logging(lib::shared_ptr<alog_type>, lib::shared_ptr<elog_type>) {}
107
115
108
    /// Initiate a new connection
116
    /// Initiate a new connection
109
    /**
117
    /**
Lines 116-121 protected: Link Here
116
        cb(make_error_code(error::not_implemented));
124
        cb(make_error_code(error::not_implemented));
117
    }
125
    }
118
126
127
    /// Accept a new connection
128
    /**
129
     * Server roles only
130
     */
131
    void async_accept(transport_con_ptr tcon, accept_handler cb, std::error_code & ec) {
132
        ec = make_error_code(error::not_implemented);
133
    }
134
119
    /// Initialize a connection
135
    /// Initialize a connection
120
    /**
136
    /**
121
     * Init is called by an endpoint once for each newly created connection.
137
     * Init is called by an endpoint once for each newly created connection.
(-)websocketpp-zaphoyd/websocketpp/uri.hpp (-29 / +468 lines)
Lines 46-54 static uint16_t const uri_default_port = Link Here
46
/// Default port for wss://
46
/// Default port for wss://
47
static uint16_t const uri_default_secure_port = 443;
47
static uint16_t const uri_default_secure_port = 443;
48
48
49
50
51
/// A group of helper methods for parsing and validating URIs against RFC 3986
52
namespace uri_helper {
53
54
/// RFC3986 unreserved character test
55
/**
56
 * @since 0.8.3
57
 *
58
 * @param c the char to test
59
 * @return True if the character is considered `unreserved`
60
 */
61
inline bool unreserved(char c) {
62
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
63
        return true;
64
    } else if (c >= '0' && c <= '9') {
65
        return true;
66
    } else if (c == '-' || c == '.' || c == '_' || c == '~') {
67
        return true;
68
    } else {
69
        return false;
70
    }
71
}
72
73
/// RFC3986 generic delimiter character test
74
/**
75
 * @param c the char to test
76
 * @return True if the character is considered a generic delimiter
77
 */
78
inline bool gen_delim(char c) {
79
    switch(c) {
80
        case ':':
81
        case '/':
82
        case '?':
83
        case '#':
84
        case '[':
85
        case ']':
86
        case '@':
87
            return true;
88
        default:
89
            return false;
90
    }
91
}
92
93
/// RFC3986 subcomponent delimiter character test
94
/**
95
 * @since 0.8.3
96
 *
97
 * @param c the char to test
98
 * @return True if the character is considered a subcomponent delimiter
99
 */
100
inline bool sub_delim(char c) {
101
    switch(c) {
102
        case '!':
103
        case '$':
104
        case '&':
105
        case '\'':
106
        case '(':
107
        case ')':
108
        case '*':
109
        case '+':
110
        case ',':
111
        case ';':
112
        case '=':
113
            return true;
114
        default:
115
            return false;
116
    }
117
}
118
119
/// RFC3986 hex digit character test
120
/**
121
 * Case insensitive
122
 *
123
 * @since 0.8.3
124
 *
125
 * @param c the char to test
126
 * @return True if the character is considered a hexadecimal digit
127
 */
128
inline bool hexdigit(char c) {
129
    switch(c) {
130
        case '0':
131
        case '1':
132
        case '2':
133
        case '3':
134
        case '4':
135
        case '5':
136
        case '6':
137
        case '7':
138
        case '8':
139
        case '9':
140
        case 'A':
141
        case 'B':
142
        case 'C':
143
        case 'D':
144
        case 'E':
145
        case 'F':
146
        case 'a':
147
        case 'b':
148
        case 'c':
149
        case 'd':
150
        case 'e':
151
        case 'f':
152
            return true;
153
        default:
154
            return false;
155
    }
156
}
157
158
/// RFC3986 scheme character test
159
/**
160
 * @since 0.8.3
161
 *
162
 * @param c the char to test
163
 * @return True if the character is considered a valid character for a uri scheme
164
 */
165
inline bool scheme(char c) {
166
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
167
        return true;
168
    } else if (c >= '0' && c <= '9') {
169
        return true;
170
    } else if (c == '+' || c == '-' || c == '.') {
171
        return true;
172
    } else {
173
        return false;
174
    }
175
}
176
177
/// RFC3986 digit character test
178
/**
179
 * @since 0.8.3
180
 *
181
 * @param c the char to test
182
 * @return True if the character is considered a digit (0-9)
183
 */
184
inline bool digit(char c) {
185
    return c >= '0' && c <= '9';
186
}
187
188
/// RFC3986 digit character test (iterator version)
189
/**
190
 * @since 0.8.3
191
 *
192
 * @param c the char to test
193
 * @return True if the character is considered a digit (0-9)
194
 */
195
inline bool digit(std::string::const_iterator it) {
196
    return digit(*it);
197
}
198
199
200
/// RFC3986 per cent encoded character test
201
/**
202
 * caller must range check (only caller knows the actual range)
203
 * caller must check for leading %
204
 *
205
 * @since 0.8.3
206
 *
207
 * @param it An iterator to the first character after the % sign
208
 * @return True if both the character pointed at by the iterator and
209
 *         the next one represent a valid RFC3986 percent encoding
210
 */
211
inline bool pct_encoded(std::string::const_iterator it) {
212
    return hexdigit(*it) && hexdigit(*(it + 1));
213
}
214
215
/// Tests a range for a valid IPv4 decimal octet
216
/**
217
 * @since 0.8.3
218
 *
219
 * @param start An iterator to the first character of the range to check (inclusive)
220
 * @param start An iterator to the last character of the range to check (exclusive)
221
 * @return True if the range represents a valid IPv4 decimal octet (0-255)
222
 */
223
inline bool dec_octet(std::string::const_iterator start, std::string::const_iterator end) {
224
    if (end-start == 1) {
225
        return digit(start);
226
    } else if (end-start == 2) {
227
        return ((*start >= '1' && *start <= '9') && digit(start+1));
228
    } else if (end-start == 3) {
229
        if (*start == '1') {
230
            return digit(start+1) && digit(start+2);
231
        } else if (*start == '2') {
232
            if (*(start+1) >= '0' && *(start+1) <= '4') {
233
                return digit(start+2);
234
            } else if (*(start+1) == '5') {
235
                return *(start+2) >= '0' && *(start+2) <= '5';
236
            }
237
        }
238
    }
239
    return false;
240
}
241
242
/// Tests a range for a valid IPv4 literal
243
/**
244
 * @since 0.8.3
245
 *
246
 * @param start An iterator to the first character of the range to check (inclusive)
247
 * @param start An iterator to the last character of the range to check (exclusive)
248
 * @return True if the range represents a valid IPv4 literal address
249
 */
250
inline bool ipv4_literal(std::string::const_iterator start, std::string::const_iterator end) {
251
    std::string::const_iterator cursor = start;
252
    size_t counter = 0;
253
    for (std::string::const_iterator it = start; it != end; ++it) {
254
        if (*it == '.') {
255
            if (dec_octet(cursor,it)) {
256
                cursor = it+1;
257
                counter++;
258
                if (counter > 3) {
259
                    return false;
260
                }
261
            } else {
262
                return false;
263
            }
264
        }
265
    }
266
    
267
    // check final octet
268
    return (counter == 3 && dec_octet(cursor,end));
269
}
270
271
/// Tests a range for a valid IPv6 hex quad
272
/**
273
 * @since 0.8.3
274
 *
275
 * @param start An iterator to the first character of the range to check (inclusive)
276
 * @param start An iterator to the last character of the range to check (exclusive)
277
 * @return True if the range represents a valid IPv6 hex quad
278
 */
279
inline bool hex4(std::string::const_iterator start, std::string::const_iterator end) {
280
    if (end-start == 0 || end-start >4) {
281
        return false;
282
    }
283
    for (std::string::const_iterator it = start; it != end; ++it) {
284
        if (!hexdigit(*it)) {
285
            return false;
286
        }
287
    }
288
    return true;
289
}
290
291
/// Tests a range for a valid IPv6 literal
292
/**
293
 * @since 0.8.3
294
 *
295
 * @param start An iterator to the first character of the range to check (inclusive)
296
 * @param start An iterator to the last character of the range to check (exclusive)
297
 * @return True if the range represents a valid IPv6 literal
298
 */
299
inline bool ipv6_literal(std::string::const_iterator start, std::string::const_iterator end) {
300
    // initial range check
301
    if (end-start > 45 && end-start >= 2) {
302
        return false;
303
    }
304
    
305
    // peal off and count hex4s until we run out of colons,
306
    // note the abbreviation marker if we see one.
307
    std::string::const_iterator cursor = start;
308
    std::string::const_iterator it = start;
309
    size_t count = 0;
310
    size_t abbr = 0;
311
    while (it != end) {
312
        if (*it == ':') {
313
            if (it == start) {
314
                // if a : happens at the beginning, don't check for a hex quad, just advance
315
                // the cursor. The abbreviation marker will be counted on the next pass
316
                cursor++;
317
            } else if (it-cursor == 0) {
318
                // this is a double colon abbreviation marker
319
                cursor++;
320
                abbr++;
321
            } else if (hex4(cursor,it)) {
322
                cursor = it+1;
323
                count++;
324
            } else {
325
                return false;
326
            }
327
        }
328
        it++;
329
    }
330
    
331
    // final bit either needs to be a hex4 or an IPv4 literal
332
    if (cursor == end) {
333
        // fine
334
    } else if (hex4(cursor,end)) {
335
        count++;
336
    } else if (ipv4_literal(cursor, end)) {
337
        count += 2;
338
    } else {
339
        return false;
340
    }
341
    
342
    if ((abbr == 0 && count != 8) || (abbr == 1 && count > 7) || abbr > 1) {
343
        return false;
344
    }
345
    
346
    return true;
347
}
348
349
/// Tests a character for validity for a registry name
350
/**
351
 * will fail on %, which is valid, but only when used as a part of a multiple
352
 * character escape sequence. Since this test checks a single character it
353
 * can't tell whether a % character is valid so it returns false. The caller
354
 * needs to catch and handle %s in another way.
355
 *
356
 * @since 0.8.3
357
 *
358
 * @param c The character to test
359
 * @return True if the range represents a valid IPv6 literal
360
 */
361
inline bool reg_name(char c) {
362
    return unreserved(c) || sub_delim(c);
363
}
364
365
/// Tests a range for validity for a registry name
366
/**
367
 * @since 0.8.3
368
 *
369
 * @param start An iterator to the first character of the range to check (inclusive)
370
 * @param start An iterator to the last character of the range to check (exclusive)
371
 * @return True if the range represents a valid registry name
372
 */
373
inline bool reg_name(std::string::const_iterator start, std::string::const_iterator end) {
374
    std::string::const_iterator it = start;
375
    while (it != end) {
376
        if (*it == '%') {
377
            // check for valid % encoded char
378
            if (it+2 < end && uri_helper::pct_encoded(it+1)) {
379
                it += 3;
380
                continue;
381
            } else {
382
                return false;
383
            }
384
        } else if (!uri_helper::reg_name(*it)) {
385
            return false;
386
        }
387
        ++it;
388
    }
389
    return true;
390
}
391
392
} // end namespace uri_helper
393
394
395
396
49
class uri {
397
class uri {
50
public:
398
public:
51
    explicit uri(std::string const & uri_string) : m_valid(false) {
399
    explicit uri(std::string const & uri_string) : m_valid(false), m_ipv6_literal(false) {
52
        std::string::const_iterator it;
400
        std::string::const_iterator it;
53
        std::string::const_iterator temp;
401
        std::string::const_iterator temp;
54
402
Lines 57-62 public: Link Here
57
        it = uri_string.begin();
405
        it = uri_string.begin();
58
        size_t uri_len = uri_string.length();
406
        size_t uri_len = uri_string.length();
59
407
408
        // extract scheme. We only consider Websocket and HTTP URI schemes as valid
60
        if (uri_len >= 7 && std::equal(it,it+6,"wss://")) {
409
        if (uri_len >= 7 && std::equal(it,it+6,"wss://")) {
61
            m_secure = true;
410
            m_secure = true;
62
            m_scheme = "wss";
411
            m_scheme = "wss";
Lines 101-117 public: Link Here
101
                return;
450
                return;
102
            } else {
451
            } else {
103
                // validate IPv6 literal parts
452
                // validate IPv6 literal parts
104
                // can contain numbers, a-f and A-F
453
                if (!uri_helper::ipv6_literal(it,temp)) {
454
                    return;
455
                } else {
456
                    m_ipv6_literal = true;
457
                }
105
                m_host.append(it,temp);
458
                m_host.append(it,temp);
106
            }
459
            }
107
            it = temp+1;
460
            it = temp+1;
108
            if (it == uri_string.end()) {
461
            if (it == uri_string.end()) {
109
                state = 2;
462
                state = 2;
110
            } else if (*it == '/') {
463
            } else if (*it == '/' || *it == '?' || *it == '#') {
464
                // todo: better path parsing
111
                state = 2;
465
                state = 2;
112
                ++it;
466
                
467
                // we don't increment the iterator here because we want the 
468
                // delimiter to be read again as a part of the path
113
            } else if (*it == ':') {
469
            } else if (*it == ':') {
114
                state = 1;
470
                state = 1;
471
472
                // start reading port after the delimiter
115
                ++it;
473
                ++it;
116
            } else {
474
            } else {
117
                // problem
475
                // problem
Lines 119-138 public: Link Here
119
            }
477
            }
120
        } else {
478
        } else {
121
            // IPv4 or hostname
479
            // IPv4 or hostname
122
            // extract until : or /
480
            // extract until : or first path component
123
            while (state == 0) {
481
            while (state == 0) {
124
                if (it == uri_string.end()) {
482
                if (it == uri_string.end()) {
125
                    state = 2;
483
                    state = 2;
126
                    break;
484
                    break;
127
                } else if (*it == '/') {
485
                } else if (*it == '%') {
128
                    state = 2;
486
                    // check for valid % encoded char
129
                } else if (*it == ':') {
487
                    if (it+2 < uri_string.end() && uri_helper::pct_encoded(it+1)) {
130
                    // end hostname start port
488
                        m_host.append(it,it+2);
131
                    state = 1;
489
                        it += 3;
490
                    }
491
                } else if (!uri_helper::reg_name(*it)) {
492
                    // we hit one of the general delimiters
493
                    if (*it == ':') {
494
                        // got host vs port delimiter
495
                        // end hostname start port
496
                        state = 1;
497
498
                        // start reading port after the delimiter
499
                        ++it;
500
                    } else if (*it == '/' || *it == '#' || *it == '?') {
501
                        // one of the normal authority vs path delimiters
502
                        // end hostname and start parsing path
503
                        state = 2;
504
505
                        // we don't increment the iterator here because we want the 
506
                        // delimiter to be read again as a part of the path
507
                    } else {
508
                        // either @, [, or ]
509
                        // @ = userinfo fragment
510
                        // [ and ] = illegal, basically
511
                        return;
512
                    }
132
                } else {
513
                } else {
133
                    m_host += *it;
514
                    m_host += *it;
515
                    ++it;
134
                }
516
                }
135
                ++it;
517
                
136
            }
518
            }
137
        }
519
        }
138
520
Lines 140-156 public: Link Here
140
        std::string port;
522
        std::string port;
141
        while (state == 1) {
523
        while (state == 1) {
142
            if (it == uri_string.end()) {
524
            if (it == uri_string.end()) {
143
                // state is not used after this point presently.
525
                // if we stop parsing the port and there wasn't actually a port
144
                // this should be re-enabled if it ever is needed in a future
526
                // we have an invalid URI
145
                // refactoring
527
                if (port.empty()) {
146
                //state = 3;
528
                    return;
147
                break;
529
                }
148
            } else if (*it == '/') {
149
                state = 3;
530
                state = 3;
150
            } else {
531
            } else if (uri_helper::digit(it)) {
151
                port += *it;
532
                port += *it;
533
                ++it;
534
            } else {
535
                // if we stop parsing the port and there wasn't actually a port
536
                // we have an invalid URI
537
                if (port.empty()) {
538
                    return;
539
                }
540
                state = 3;
541
542
                // we don't increment the iterator here because we want the 
543
                // delimiter to be read again as a part of the path
152
            }
544
            }
153
            ++it;
545
            
154
        }
546
        }
155
547
156
        lib::error_code ec;
548
        lib::error_code ec;
Lines 160-167 public: Link Here
160
            return;
552
            return;
161
        }
553
        }
162
554
163
        m_resource = "/";
555
        // step back one so the first char of the path delimiter doesn't get eaten
164
        m_resource.append(it,uri_string.end());
556
        m_resource.append(it,uri_string.end());
557
        
558
        if (m_resource.empty()) {
559
            m_resource = "/";
560
        }
561
562
        // todo: validate path component
165
563
166
564
167
        m_valid = true;
565
        m_valid = true;
Lines 174-180 public: Link Here
174
      , m_resource(resource.empty() ? "/" : resource)
572
      , m_resource(resource.empty() ? "/" : resource)
175
      , m_port(port)
573
      , m_port(port)
176
      , m_secure(secure)
574
      , m_secure(secure)
177
      , m_valid(true) {}
575
      {
576
          m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
577
          m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end());
578
      }
178
579
179
    uri(bool secure, std::string const & host, std::string const & resource)
580
    uri(bool secure, std::string const & host, std::string const & resource)
180
      : m_scheme(secure ? "wss" : "ws")
581
      : m_scheme(secure ? "wss" : "ws")
Lines 182-188 public: Link Here
182
      , m_resource(resource.empty() ? "/" : resource)
583
      , m_resource(resource.empty() ? "/" : resource)
183
      , m_port(secure ? uri_default_secure_port : uri_default_port)
584
      , m_port(secure ? uri_default_secure_port : uri_default_port)
184
      , m_secure(secure)
585
      , m_secure(secure)
185
      , m_valid(true) {}
586
      {
587
          m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
588
          m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end());
589
      }
186
590
187
    uri(bool secure, std::string const & host, std::string const & port,
591
    uri(bool secure, std::string const & host, std::string const & port,
188
        std::string const & resource)
592
        std::string const & resource)
Lines 193-199 public: Link Here
193
    {
597
    {
194
        lib::error_code ec;
598
        lib::error_code ec;
195
        m_port = get_port_from_string(port,ec);
599
        m_port = get_port_from_string(port,ec);
196
        m_valid = !ec;
600
        m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
601
602
        m_valid = !ec && (m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()));
197
    }
603
    }
198
604
199
    uri(std::string const & scheme, std::string const & host, uint16_t port,
605
    uri(std::string const & scheme, std::string const & host, uint16_t port,
Lines 203-209 public: Link Here
203
      , m_resource(resource.empty() ? "/" : resource)
609
      , m_resource(resource.empty() ? "/" : resource)
204
      , m_port(port)
610
      , m_port(port)
205
      , m_secure(scheme == "wss" || scheme == "https")
611
      , m_secure(scheme == "wss" || scheme == "https")
206
      , m_valid(true) {}
612
      {
613
          m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
614
          m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end());
615
      }
207
616
208
    uri(std::string scheme, std::string const & host, std::string const & resource)
617
    uri(std::string scheme, std::string const & host, std::string const & resource)
209
      : m_scheme(scheme)
618
      : m_scheme(scheme)
Lines 211-217 public: Link Here
211
      , m_resource(resource.empty() ? "/" : resource)
620
      , m_resource(resource.empty() ? "/" : resource)
212
      , m_port((scheme == "wss" || scheme == "https") ? uri_default_secure_port : uri_default_port)
621
      , m_port((scheme == "wss" || scheme == "https") ? uri_default_secure_port : uri_default_port)
213
      , m_secure(scheme == "wss" || scheme == "https")
622
      , m_secure(scheme == "wss" || scheme == "https")
214
      , m_valid(true) {}
623
      {
624
          m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
625
          m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end());
626
      }
215
627
216
    uri(std::string const & scheme, std::string const & host,
628
    uri(std::string const & scheme, std::string const & host,
217
        std::string const & port, std::string const & resource)
629
        std::string const & port, std::string const & resource)
Lines 222-234 public: Link Here
222
    {
634
    {
223
        lib::error_code ec;
635
        lib::error_code ec;
224
        m_port = get_port_from_string(port,ec);
636
        m_port = get_port_from_string(port,ec);
225
        m_valid = !ec;
637
        m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end());
638
639
        m_valid = !ec && (m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()));
226
    }
640
    }
227
641
228
    bool get_valid() const {
642
    bool get_valid() const {
229
        return m_valid;
643
        return m_valid;
230
    }
644
    }
231
645
646
    // Check whether the host of this URI is an IPv6 literal address
647
    /**
648
     * @since 0.8.3
649
     * @return True if the host of this URI is an IPv6 literal address
650
     */
651
    bool is_ipv6_literal() const {
652
        return m_ipv6_literal;
653
    }
654
232
    bool get_secure() const {
655
    bool get_secure() const {
233
        return m_secure;
656
        return m_secure;
234
    }
657
    }
Lines 243-259 public: Link Here
243
666
244
    std::string get_host_port() const {
667
    std::string get_host_port() const {
245
        if (m_port == (m_secure ? uri_default_secure_port : uri_default_port)) {
668
        if (m_port == (m_secure ? uri_default_secure_port : uri_default_port)) {
669
            // todo: should this have brackets for v6?
246
            return m_host;
670
            return m_host;
247
        } else {
671
        } else {
248
            std::stringstream p;
672
            std::stringstream p;
249
            p << m_host << ":" << m_port;
673
            if (m_ipv6_literal) {
674
                p << "[" << m_host << "]:" << m_port;
675
            } else {
676
                p << m_host << ":" << m_port;
677
            }
678
            
250
            return p.str();
679
            return p.str();
251
        }
680
        }
252
    }
681
    }
253
682
254
    std::string get_authority() const {
683
    std::string get_authority() const {
255
        std::stringstream p;
684
        std::stringstream p;
256
        p << m_host << ":" << m_port;
685
        if (m_ipv6_literal) {
686
            p << "[" << m_host << "]:" << m_port;
687
        } else {
688
            p << m_host << ":" << m_port;
689
        }
257
        return p.str();
690
        return p.str();
258
    }
691
    }
259
692
Lines 274-280 public: Link Here
274
    std::string str() const {
707
    std::string str() const {
275
        std::stringstream s;
708
        std::stringstream s;
276
709
277
        s << m_scheme << "://" << m_host;
710
        s << m_scheme << "://";
711
        if (m_ipv6_literal) {
712
            s << "[" << m_host << "]";
713
        } else {
714
            s << m_host;
715
        }
278
716
279
        if (m_port != (m_secure ? uri_default_secure_port : uri_default_port)) {
717
        if (m_port != (m_secure ? uri_default_secure_port : uri_default_port)) {
280
            s << ":" << m_port;
718
            s << ":" << m_port;
Lines 346-351 private: Link Here
346
    uint16_t    m_port;
784
    uint16_t    m_port;
347
    bool        m_secure;
785
    bool        m_secure;
348
    bool        m_valid;
786
    bool        m_valid;
787
    bool        m_ipv6_literal;
349
};
788
};
350
789
351
/// Pointer to a URI
790
/// Pointer to a URI
(-)websocketpp-zaphoyd/websocketpp/utilities.hpp (-7 lines)
Lines 128-140 typename T::const_iterator ci_find_subst Link Here
128
        needle, needle+size, my_equal<typename T::value_type>(loc) );
128
        needle, needle+size, my_equal<typename T::value_type>(loc) );
129
}
129
}
130
130
131
/// Convert a string to lowercase
132
/**
133
 * @param [in] in The string to convert
134
 * @return The converted string
135
 */
136
std::string to_lower(std::string const & in);
137
138
/// Replace all occurrances of a substring with another
131
/// Replace all occurrances of a substring with another
139
/**
132
/**
140
 * @param [in] subject The string to search in
133
 * @param [in] subject The string to search in

Return to bug 946365