Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 921340 Details for
Bug 946365
dev-cpp/websocketpp-0.8.2 fails to compile: none.hpp:66:24: error: io_service in namespace websocketpp::lib::asio does not name a type
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
hingobway.patch
hingobway.patch (text/plain), 405.55 KB, created by
Attila Tóth
on 2025-03-20 13:35:09 UTC
(
hide
)
Description:
hingobway.patch
Filename:
MIME Type:
Creator:
Attila Tóth
Created:
2025-03-20 13:35:09 UTC
Size:
405.55 KB
patch
obsolete
>diff '--color=auto' -urNp websocketpp-zaphoyd/changelog.md websocketpp-hingobway/changelog.md >--- websocketpp-zaphoyd/changelog.md 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/changelog.md 2025-03-10 21:33:06.000000000 +0100 >@@ -1,4 +1,83 @@ > HEAD >+- MINOR BREAKING BUNDLED LIBRARY CHANGE: The bundled mini-HTTP library has >+ been refactored to eliminate its use of exceptions. This does not affect any >+ of the core library APIs. If any users are calling into the underlying HTTP >+ libraries directly (classes in the namespace `websocketpp::http::*`) they >+ should review any error handling they do. >+- MINOR BREAKING BUNDLED LIBRARY CHANGE: The `websocketpp::utility::to_lower` >+ function, from the bundled utility library, has been removed. This vestigial >+ code was not used by the library at all and throwing warnings in MSVC. >+ Thank you fedor-strelkov and maksis for reporting and remediation ideas. #956 >+- Feature: WebSocket++ can now be compiled without exceptions by defining >+ `_WEBSOCKETPP_NO_EXCEPTIONS` in the C++ preprocessor. All internal use of >+ exceptions have been removed. External interfaces that throw exceptions are >+ still avaliable and supported (except in exception free mode) but now have >+ overloads that allow `error_code` based error handling. >+- Compatibility: Overhauled the URI authority parsing logic to be more >+ compliant with RFC3986. WebSocket++ is now able to detect invalid registry >+ hosts, invalid IPv4 and IPv6 literal addresses. Dozens of additional >+ uri tests added (thank you to the uriparser project for inspiration & test >+ cases). URI methods that produce URI strings will now produce RFC3986 >+ compliant URIs when IPv6 literals are involved. Thank you Jeff Davie, >+ thorsten-klein, mstaz, and barsnick for reporting, example patches, and >+ testing. #601 #879 >+- Improvement: The error handling system for the server role's async start >+ accept loop and connection generation has been significantly improved. >+ `endpoint::get_connection` now takes an output parameter ec that gives >+ a detailed error code if connection creation fails. `endpoint::start_accept` >+ now accepts a handler function as a parameter instead of an error code. >+ This handler function allows the client program to be alerted when the >+ async accept loop stops (for any reason, including explicit cancellation) >+ at any time. Previously, it was only possible to tell if the initial loop >+ start had failed, making it difficult to tell when/if the async accept loop >+ needed to be restarted. The loop handler returns two error codes, a higher >+ level library code and a second more specific transport level code. The >+ old `endpoint::get_connection` and `endpoint::start_accept` functions >+ remain for backwards compatibility but are deprecated. Thank you Oleh >+ Derevenko for reporting. #896 >+- Improvement: Cancel ping timer before calling blocking pong handler. >+ This should reduce any unnecessary expiration logic done to a timer >+ that is going to be cancelled regardless. Thank you Oleh Derevenko >+ for reporting. #901 >+- Improvement: Cancel ping timer on connection close. Once the close handeshake >+ begins, pong responses can no longer be delivered and any outstanding pings >+ can be assumed to have been preempted by the close. fixes #664 >+- Performance: Refactor to_hex utility method to reduce unecessary copying, >+ std::string construction, and duplicated code. Add tests. Thank you Dmitry >+ Matrokhin for reporting and the patch. #914 >+- Performance: Move based overload for connection::set_body for C++11 and >+ later compilers. Thank you Matus Kysel for the patch & tests. #792 >+- Reliability: Add a few defensive assertions to guard against corrupted >+ HTTP message reads. Thank you Oleh Derevenko for reporting. #899 >+- Compatibility: Remove use of simple template ids in constructors. This was >+ required to compile in C++20 mode and higher. Thank you yushb0602 for >+ reporting and jcelerier for a patch. >+- Fix Regression: Correct a regression introduced in 0.8.0 that broke >+ functionality for setting accepted socket options like TCP_NODELAY. >+ #530 #812 >+- Bug: Fix null pointer deference in proxy error handling code. Thank you >+ abitmore for reporting and stkaufer for a patch. #820 #825 >+- Documentation: Added language to explicitly clarify that the library >+ license is in fact the 3-Clause BSD license. #906 >+- Travis/CI: Updated Travis config to use newer version of ubuntu, and use >+ CMake based build & tests. >+- SCons: Fix typo in SConstruct that prevented clang from getting the right >+ value for CXXFLAGS. Thank you robinlinden for reporting and a patch. #878 >+- SCons: Improve compatibility with Python 3. Thank you Jochen Jägers and >+ Gianfranco Costamagna for reporting and the patches. #885 #857 #1024 >+- SCons: Correct copy/paste error in `scratch_client` SConstruct file. >+ Thank you kautsig for reporting and the patch. #893 >+- CMake: Fix typo in CMakeLists.txt that caused CXX_FLAGS to be improperly >+ quoted. Removed unnecessary hardcoded dependency on libc++ for clang. >+ Thank you kraj and leochan2009 for reporting and a patch. #614 #859 >+- CMake: Fix issue in CMakeLists.txt that caused boost dependencies to be >+ seen as a single library rather than multiple. Thank you Gianfranco >+ Costamagna for reporting and a patch. #855 >+- CMake: Adjust CMake config to use GNUInstallDirs to choose install >+ directories rather than hard coding. Thank you Khem Raj for reporting and >+ a patch. #854 >+- CMake: Improve support for building tests & examples on the Haiku platform >+ Thank you Schrijvers Luc for reporting and the patch. #849 > > 0.8.2 - 2020-04-19 > - Examples: Update print_client_tls example to remove use of deprecated >diff '--color=auto' -urNp websocketpp-zaphoyd/CMakeLists.txt websocketpp-hingobway/CMakeLists.txt >--- websocketpp-zaphoyd/CMakeLists.txt 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/CMakeLists.txt 2025-03-10 21:33:06.000000000 +0100 >@@ -39,6 +39,8 @@ endif() > > set_property(GLOBAL PROPERTY USE_FOLDERS ON) > >+include(GNUInstallDirs) >+ > get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS) > if ("${LIB64}" STREQUAL "TRUE") > set(LIBSUFFIX 64) >@@ -82,6 +84,7 @@ include (CMakeHelpers) > option (ENABLE_CPP11 "Build websocketpp with CPP11 features enabled." TRUE) > option (BUILD_EXAMPLES "Build websocketpp examples." FALSE) > option (BUILD_TESTS "Build websocketpp tests." FALSE) >+option (USE_ASIO_STANDALONE "Build websocketpp examples and tests using the standalone ASIO library." FALSE) > > if (BUILD_TESTS OR BUILD_EXAMPLES) > >@@ -130,11 +133,15 @@ if (BUILD_TESTS OR BUILD_EXAMPLES) > > # g++ > if (CMAKE_COMPILER_IS_GNUCXX) >- if (NOT APPLE) >+ if (NOT APPLE AND NOT HAIKU) > set (WEBSOCKETPP_PLATFORM_LIBS pthread rt) > else() >+ if (HAIKU) >+ set (WEBSOCKETPP_PLATFORM_LIBS pthread network) >+ else() > set (WEBSOCKETPP_PLATFORM_LIBS pthread) > endif() >+ endif() > set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto) > set (WEBSOCKETPP_BOOST_LIBS system thread) > set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") >@@ -152,10 +159,12 @@ if (BUILD_TESTS OR BUILD_EXAMPLES) > > # clang > if (CMAKE_COMPILER_IS_CLANGXX) >- if (NOT APPLE) >- set (WEBSOCKETPP_PLATFORM_LIBS pthread rt) >- else() >+ if (APPLE) > set (WEBSOCKETPP_PLATFORM_LIBS pthread) >+ elseif (HAIKU) >+ set (WEBSOCKETPP_PLATFORM_LIBS pthread network) >+ else() >+ set (WEBSOCKETPP_PLATFORM_LIBS pthread rt) > endif() > set (WEBSOCKETPP_PLATFORM_TLS_LIBS ssl crypto) > set (WEBSOCKETPP_BOOST_LIBS system thread) >@@ -253,6 +262,10 @@ endif() > > ############ Add projects > >+if (USE_ASIO_STANDALONE) >+ add_definitions("-DASIO_STANDALONE -DASIO_HAS_BOOST_DATE_TIME") >+endif () >+ > # Add main library > add_subdirectory (websocketpp) > >diff '--color=auto' -urNp websocketpp-zaphoyd/COPYING websocketpp-hingobway/COPYING >--- websocketpp-zaphoyd/COPYING 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/COPYING 2025-03-10 21:33:06.000000000 +0100 >@@ -1,5 +1,7 @@ > Main Library: > >+BSD 3-Clause License >+ > Copyright (c) 2014, Peter Thorson. All rights reserved. > > Redistribution and use in source and binary forms, with or without >@@ -64,6 +66,8 @@ use as a header only library. This conve > (webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed > under the same license as the original, which is listed below. > >+New BSD License / 3-Clause BSD License >+ > Copyright (c) 2011, Micael Hildenborg > All rights reserved. > >diff '--color=auto' -urNp websocketpp-zaphoyd/docs/config.dox websocketpp-hingobway/docs/config.dox >--- websocketpp-zaphoyd/docs/config.dox 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/docs/config.dox 2025-03-10 21:33:06.000000000 +0100 >@@ -1,6 +1,6 @@ > /** \page reference.config Config Reference > >-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. >+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. > > A custom config can be made standalone or can subclass one of the bundled configs and just override a few things. > >@@ -38,20 +38,21 @@ Core Config Options > > Policies are classes used to allow clean swapping of behavior without changing the core library > >-| Typedef Name | Effect | >-| ------------------------- | -------------------------------------- | >-| concurrency_type | Concurrency policy | >-| elog_type | Error logger type | >-| alog_type | Access logger type | >-| request_type | HTTP request type | >-| response_type | HTTP response type | >-| message_type | Type to deliver recieved messages | >-| con_msg_manager_type | Connection level message manager | >-| endpoint_msg_manager_type | Endpoint level message manager | >-| rng_type | Random Number Generation policy | >-| transport_type | Transport policy to use | >-| endpoint_base | User overridable Endpoint base class | >-| connection_base | User overridable Connection base class | >+| Typedef Name | Effect | Core policies | >+| ------------------------- | -------------------------------------- | ------------- | >+| concurrency_type | Provides concurrency primitives | **None** Stub to disable concurrency overhead & dependencies in single threaded environments | >+| ^ | ^ | **Basic** Primities provided by the C++11 STL or Boost.Atomic | >+| elog_type | Provides error logging functionality | | >+| alog_type | Provides access logging functionality | | >+| request_type | Stores and manipulates HTTP requests | | >+| response_type | Stores and manipulates HTTP responses | | >+| message_type | Stores and manipulates WebSocket Messages | | >+| con_msg_manager_type | Connection level message manager | | >+| endpoint_msg_manager_type | Endpoint level message manager | | >+| rng_type | Random Number Generation policy | | >+| transport_type | Provides network I/O and timers | | >+| endpoint_base | User overridable Endpoint base class | | >+| connection_base | User overridable Connection base class | | > > ### Timeouts Values > >@@ -91,7 +92,7 @@ If your application has a lot of connect > 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. > > #### Silent Close >-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. >+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. > > Note: this will suppress *all* close codes, including those explicitly sent by local applications. > >diff '--color=auto' -urNp websocketpp-zaphoyd/docs/faq.dox websocketpp-hingobway/docs/faq.dox >--- websocketpp-zaphoyd/docs/faq.dox 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/docs/faq.dox 2025-03-10 21:33:06.000000000 +0100 >@@ -29,19 +29,19 @@ Note: some browsers will allow the conne > > ### How do I cleanly exit an Asio transport based program > >-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: >+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: > > - For servers, call `websocketpp::transport::asio::endpoint::stop_listening` to initiate the closing of the server listening socket. > - For clients, if you have engaged perpetual mode with `websocketpp::transport::asio::endpoint::start_perpetual`, disable it with `websocketpp::transport::asio::endpoint::stop_perpetual`. > - 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 >-- 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. >+- 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. > >-__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. >+__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. > > __Special cases__: >-- 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. >-- 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. >-- 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. >+- 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. >+- 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. >+- 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. > > ### Is there a way to check the validity of a `connection_hdl`? > >diff '--color=auto' -urNp websocketpp-zaphoyd/docs/handlers.dox websocketpp-hingobway/docs/handlers.dox >--- websocketpp-zaphoyd/docs/handlers.dox 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/docs/handlers.dox 2025-03-10 21:33:06.000000000 +0100 >@@ -46,13 +46,22 @@ operations have been run. Common pre-han > > ### TCP Post-init Handler > >+| Event | Signature | Availability | >+| -------------------------------------------------- | ------------------------------- | -------------------- | >+| TCP established, pre-handshake operations complete | `tcp_post_init(connection_hdl)` | 0.3.0 Asio Transport | >+ >+This hook is triggered after all pre-WebSocket handshake operations have been run. Common pre-handshake >+operations include TLS handshakes and proxy connections. >+ >+### TLS Initialization Handler >+ > | Event | Signature | Availability | > | ----------------------- | ------------------------------------------ | ----------------------------- | > | Request for TLS context | `tls_context_ptr tls_init(connection_hdl)` | 0.3.0 Asio Transport with TLS | > >-This hook is triggered before the TLS handshake to request the TLS context to use. You must >-return a pointer to a configured TLS conext to continue. This provides the opportuinity to >-set up the TLS settings, certificates, etc. >+This hook is triggered before the TLS handshake to request the TLS context to use. The user program must >+return a pointer to a configured TLS context to continue. This provides the opportuinity to set up TLS >+settings, certificates, etc. > > ### Validate Handler > >@@ -96,10 +105,49 @@ that fail will never have a close handle > Close will be called exactly once for every connection that open was called for. > Close is not called for failed connections. > >+Endpoint Handlers >+----------------- >+ >+### TCP Listen Pre-bind handler >+ >+| Event | Signature | Availability | >+| -------------- | ----------------------------------------------------------------------------- | -------------------- | >+| Listen Prebind | `lib::error_code tcp_pre_bind(lib::shared_ptr<lib::asio::ip::tcp::acceptor>)` | 0.8.0 Asio Transport | >+ >+This hook is triggered during the call to `endpoint::listen` after the acceptor >+is initialized and open but before bind or listen are called. It provides an >+opportunity to make application specific configuation to the acceptor, most >+commonly setting socket options on the listening socket, such as SO_REUSEPORT >+or IPV6_ONLY. >+ >+The return value of the callback will be used to determine whether to proceed >+with listening. Return an empty/0 error code to proceed, or another error code >+to fail. In the fail case, the error code will be reported back to the caller >+of `endpoint::listen`. >+ >+### Acceptance Loop End Handler >+ >+| Event | Signature | Availability | >+| ------------------------------------- | --------------------------------------------------------------------- | ---------------------------- | >+| Async Accept Loop end (after opening) | `accept_loop(void(lib::error_code const &, lib::error_code const &))` | 0.9.0 Core, Server role only | >+ >+This handler is passed to the `endpoint::start_accept()` function, which initiates an >+asyncronous loop that accepts new connections, and is invoked when that loop ends. The >+handler will be called exactly once for each call of `start_accept` no matter when or >+how it exits (it might exit immediately). >+ >+The handler may be called inside the call to `start_accept` if that function has enough >+information to determine that accepting connections will be impossible. Otherwise, it >+may be invoked at a later time from a different asyncronous handler. >+ >+The handler returns two error codes. The first from the core library and the second a >+more detailed code passed through from the underlying transport. >+ > Message Handlers > ---------------- > >-These handers are called in response to incoming messages or message like events. They only will be called while the connection is in the open state. >+These handers are called in response to incoming messages or message like events. >+They only will be called while the connection is in the open state. > > ### Message Handler > >@@ -145,7 +193,7 @@ Triggered if there is no response to a p > | HTTP request recieved | `http(connection_hdl` | 0.3.0 Core, Server role only | > > Called when HTTP requests that are not WebSocket handshake upgrade requests are >-recieved. Allows responding to regular HTTP requests. If no handler is registered >+received. Allows responding to regular HTTP requests. If no handler is registered > a 426/Upgrade Required error is returned. > > ### Interrupt Handler >@@ -157,9 +205,7 @@ a 426/Upgrade Required error is returned > Interrupt events can be triggered by calling `endpoint::interrupt` or `connection::interrupt`. > Interrupt is similar to a timer event with duration zero but with lower overhead. It is useful > for single threaded programs to allow breaking up a very long handler into multiple parts and >-for multi threaded programs as a way for worker threads to signale to the main/network thread >+for multi threaded programs as a way for worker threads to signal to the main/network thread > that an event is ready. > >-todo: write low and high watermark handlers >- > */ >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/associative_storage/associative_storage.cpp websocketpp-hingobway/examples/associative_storage/associative_storage.cpp >--- websocketpp-zaphoyd/examples/associative_storage/associative_storage.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/associative_storage/associative_storage.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -10,6 +10,7 @@ using websocketpp::connection_hdl; > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > struct connection_data { > int sessionid; >@@ -44,6 +45,11 @@ public: > m_connections.erase(hdl); > } > >+ void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+ } >+ > void on_message(connection_hdl hdl, server::message_ptr msg) { > connection_data& data = get_data_from_hdl(hdl); > >@@ -71,7 +77,7 @@ public: > > void run(uint16_t port) { > m_server.listen(port); >- m_server.start_accept(); >+ m_server.start_accept(bind(&print_server::on_end_accept,this,::_1,::_2)); > m_server.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/broadcast_server/broadcast_server.cpp websocketpp-hingobway/examples/broadcast_server/broadcast_server.cpp >--- websocketpp-zaphoyd/examples/broadcast_server/broadcast_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/broadcast_server/broadcast_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -47,8 +47,12 @@ struct action { > class broadcast_server { > public: > broadcast_server() { >+ websocketpp::lib::error_code ec; > // Initialize Asio Transport >- m_server.init_asio(); >+ m_server.init_asio(ec); >+ if (!ec) { >+ return; >+ } > > // Register handler callbacks > m_server.set_open_handler(bind(&broadcast_server::on_open,this,::_1)); >@@ -57,18 +61,26 @@ public: > } > > void run(uint16_t port) { >+ websocketpp::lib::error_code ec; >+ > // listen on specified port >- m_server.listen(port); >+ m_server.listen(port,ec); >+ if (!ec) { >+ return; >+ } > > // Start the server accept loop >- m_server.start_accept(); >+ m_server.start_accept(ec); >+ if (!ec) { >+ return; >+ } > >- // Start the ASIO io_service run loop >- try { >+ // Start the ASIO io_context run loop >+ //try { > m_server.run(); >- } catch (const std::exception & e) { >- std::cout << e.what() << std::endl; >- } >+ //} catch (const std::exception & e) { >+ // std::cout << e.what() << std::endl; >+ //} > } > > void on_open(connection_hdl hdl) { >@@ -100,6 +112,7 @@ public: > } > > void process_messages() { >+ websocketpp::lib::error_code ec; > while(1) { > unique_lock<mutex> lock(m_action_lock); > >@@ -123,7 +136,10 @@ public: > > con_list::iterator it; > for (it = m_connections.begin(); it != m_connections.end(); ++it) { >- m_server.send(*it,a.msg); >+ m_server.send(*it,a.msg,ec); >+ if (ec) { >+ return; >+ } > } > } else { > // undefined. >@@ -143,7 +159,7 @@ private: > }; > > int main() { >- try { >+ //try { > broadcast_server server_instance; > > // Start a thread to run the processing loop >@@ -154,7 +170,7 @@ int main() { > > t.join(); > >- } catch (websocketpp::exception const & e) { >- std::cout << e.what() << std::endl; >- } >+ //} catch (websocketpp::exception const & e) { >+ // std::cout << e.what() << std::endl; >+ //} > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/broadcast_server/SConscript websocketpp-hingobway/examples/broadcast_server/SConscript >--- websocketpp-zaphoyd/examples/broadcast_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/broadcast_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('broadcast_server', ["broadcast_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/debug_client/debug_client.cpp websocketpp-hingobway/examples/debug_client/debug_client.cpp >--- websocketpp-zaphoyd/examples/debug_client/debug_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/debug_client/debug_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -30,13 +30,12 @@ > */ > > #include <websocketpp/config/asio_client.hpp> >- > #include <websocketpp/client.hpp> > > #include <iostream> > #include <chrono> > >-typedef websocketpp::client<websocketpp::config::asio_client> client; >+typedef websocketpp::client<websocketpp::config::asio_tls_client> client; > > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; >@@ -44,7 +43,7 @@ using websocketpp::lib::bind; > > // pull out the type of messages sent by our config > typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr; >-typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr; >+typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr; > typedef client::connection_ptr connection_ptr; > > >@@ -63,7 +62,7 @@ public: > > // Register our handlers > m_endpoint.set_socket_init_handler(bind(&type::on_socket_init,this,::_1)); >- //m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1)); >+ m_endpoint.set_tls_init_handler(bind(&type::on_tls_init,this,::_1)); > m_endpoint.set_message_handler(bind(&type::on_message,this,::_1,::_2)); > m_endpoint.set_open_handler(bind(&type::on_open,this,::_1)); > m_endpoint.set_close_handler(bind(&type::on_close,this,::_1)); >@@ -83,7 +82,7 @@ public: > > m_endpoint.connect(con); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > m_start = std::chrono::high_resolution_clock::now(); > m_endpoint.run(); > } >@@ -94,13 +93,13 @@ public: > > context_ptr on_tls_init(websocketpp::connection_hdl) { > m_tls_init = std::chrono::high_resolution_clock::now(); >- context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1); >+ context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(websocketpp::lib::asio::ssl::context::tlsv1); > > try { >- ctx->set_options(boost::asio::ssl::context::default_workarounds | >- boost::asio::ssl::context::no_sslv2 | >- boost::asio::ssl::context::no_sslv3 | >- boost::asio::ssl::context::single_dh_use); >+ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | >+ websocketpp::lib::asio::ssl::context::no_sslv2 | >+ websocketpp::lib::asio::ssl::context::no_sslv3 | >+ websocketpp::lib::asio::ssl::context::single_dh_use); > } catch (std::exception& e) { > std::cout << e.what() << std::endl; > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/debug_client/SConscript websocketpp-hingobway/examples/debug_client/SConscript >--- websocketpp-zaphoyd/examples/debug_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/debug_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,7 +14,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > prgs += env_cpp11.Program('debug_client', ["debug_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/debug_server/debug_server.cpp websocketpp-hingobway/examples/debug_server/debug_server.cpp >--- websocketpp-zaphoyd/examples/debug_server/debug_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/debug_server/debug_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -162,7 +162,7 @@ int main() { > // Start the server accept loop > echo_server.start_accept(); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > echo_server.run(); > } catch (websocketpp::exception const & e) { > std::cout << e.what() << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/debug_server/SConscript websocketpp-hingobway/examples/debug_server/SConscript >--- websocketpp-zaphoyd/examples/debug_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/debug_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('debug_server', ["debug_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/dev/SConscript websocketpp-hingobway/examples/dev/SConscript >--- websocketpp-zaphoyd/examples/dev/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/dev/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -11,7 +11,7 @@ env_cpp11 = env_cpp11.Clone () > > prgs = [] > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system','timer','chrono'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('main', ["main.cpp"], LIBS = BOOST_LIBS_CPP11) > >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_client/echo_client.cpp websocketpp-hingobway/examples/echo_client/echo_client.cpp >--- websocketpp-zaphoyd/examples/echo_client/echo_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_client/echo_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { > // exchanged until the event loop starts running in the next line. > c.connect(con); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > // this will cause a single connection to be made to the server. c.run() > // will exit when this connection is closed. > c.run(); >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_client/SConscript websocketpp-hingobway/examples/echo_client/SConscript >--- websocketpp-zaphoyd/examples/echo_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z'] > prgs += env_cpp11.Program('echo_client', ["echo_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server/echo_server.cpp websocketpp-hingobway/examples/echo_server/echo_server.cpp >--- websocketpp-zaphoyd/examples/echo_server/echo_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server/echo_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -9,6 +9,7 @@ typedef websocketpp::server<websocketpp: > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > // pull out the type of messages sent by our config > typedef server::message_ptr message_ptr; >@@ -34,6 +35,12 @@ void on_message(server* s, websocketpp:: > } > } > >+// Define a callback to handle failures accepting connections >+void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+} >+ > int main() { > // Create a server endpoint > server echo_server; >@@ -53,9 +60,9 @@ int main() { > echo_server.listen(9002); > > // Start the server accept loop >- echo_server.start_accept(); >+ echo_server.start_accept(&on_end_accept); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > echo_server.run(); > } catch (websocketpp::exception const & e) { > std::cout << e.what() << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server/SConscript websocketpp-hingobway/examples/echo_server/SConscript >--- websocketpp-zaphoyd/examples/echo_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('echo_server', ["echo_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server_both/echo_server_both.cpp websocketpp-hingobway/examples/echo_server_both/echo_server_both.cpp >--- websocketpp-zaphoyd/examples/echo_server_both/echo_server_both.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server_both/echo_server_both.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -12,9 +12,10 @@ typedef websocketpp::server<websocketpp: > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > // type of the ssl context pointer is long so alias it >-typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr; >+typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr; > > // The shared on_message handler takes a template parameter so the function can > // resolve any endpoint dependent types like message_ptr or connection_ptr >@@ -34,6 +35,12 @@ void on_message(EndpointType* s, websock > } > } > >+// Define a callback to handle failures accepting connections >+void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+} >+ > // No change to TLS init methods from echo_server_tls > std::string get_password() { > return "test"; >@@ -41,16 +48,16 @@ std::string get_password() { > > context_ptr on_tls_init(websocketpp::connection_hdl hdl) { > std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl; >- context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1)); >+ context_ptr ctx(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::tlsv1)); > > try { >- ctx->set_options(boost::asio::ssl::context::default_workarounds | >- boost::asio::ssl::context::no_sslv2 | >- boost::asio::ssl::context::no_sslv3 | >- boost::asio::ssl::context::single_dh_use); >+ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | >+ websocketpp::lib::asio::ssl::context::no_sslv2 | >+ websocketpp::lib::asio::ssl::context::no_sslv3 | >+ websocketpp::lib::asio::ssl::context::single_dh_use); > ctx->set_password_callback(bind(&get_password)); > ctx->use_certificate_chain_file("server.pem"); >- ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem); >+ ctx->use_private_key_file("server.pem", websocketpp::lib::asio::ssl::context::pem); > } catch (std::exception& e) { > std::cout << e.what() << std::endl; > } >@@ -58,30 +65,30 @@ context_ptr on_tls_init(websocketpp::con > } > > int main() { >- // set up an external io_service to run both endpoints on. This is not >+ // set up an external io_context to run both endpoints on. This is not > // strictly necessary, but simplifies thread management a bit. >- boost::asio::io_service ios; >+ websocketpp::lib::asio::io_context ctx; > > // set up plain endpoint > server_plain endpoint_plain; >- // initialize asio with our external io_service rather than an internal one >- endpoint_plain.init_asio(&ios); >+ // initialize asio with our external io_context rather than an internal one >+ endpoint_plain.init_asio(&ctx); > endpoint_plain.set_message_handler( > bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2)); > endpoint_plain.listen(80); >- endpoint_plain.start_accept(); >+ endpoint_plain.start_accept(&on_end_accept); > > // set up tls endpoint > server_tls endpoint_tls; >- endpoint_tls.init_asio(&ios); >+ endpoint_tls.init_asio(&ctx); > endpoint_tls.set_message_handler( > bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2)); > // TLS endpoint has an extra handler for the tls init > endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1)); > // tls endpoint listens on a different port > endpoint_tls.listen(443); >- endpoint_tls.start_accept(); >+ endpoint_tls.start_accept(&on_end_accept); > >- // Start the ASIO io_service run loop running both endpoints >- ios.run(); >+ // Start the ASIO io_context run loop running both endpoints >+ ctx.run(); > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server_both/SConscript websocketpp-hingobway/examples/echo_server_both/SConscript >--- websocketpp-zaphoyd/examples/echo_server_both/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server_both/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,7 +14,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > prgs += env_cpp11.Program('echo_server_both', ["echo_server_both.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server_tls/echo_server_tls.cpp websocketpp-hingobway/examples/echo_server_tls/echo_server_tls.cpp >--- websocketpp-zaphoyd/examples/echo_server_tls/echo_server_tls.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server_tls/echo_server_tls.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -45,6 +45,7 @@ typedef websocketpp::server<websocketpp: > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > // pull out the type of messages sent by our config > typedef websocketpp::config::asio::message_type::ptr message_ptr; >@@ -63,6 +64,12 @@ void on_message(server* s, websocketpp:: > } > } > >+// Define a callback to handle failures accepting connections >+void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+} >+ > void on_http(server* s, websocketpp::connection_hdl hdl) { > server::connection_ptr con = s->get_con_from_hdl(hdl); > >@@ -146,9 +153,9 @@ int main() { > echo_server.listen(9002); > > // Start the server accept loop >- echo_server.start_accept(); >+ echo_server.start_accept(&on_end_accept); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > echo_server.run(); > > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/echo_server_tls/SConscript websocketpp-hingobway/examples/echo_server_tls/SConscript >--- websocketpp-zaphoyd/examples/echo_server_tls/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/echo_server_tls/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,7 +14,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > prgs += env_cpp11.Program('echo_server_tls', ["echo_server_tls.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/enriched_storage/enriched_storage.cpp websocketpp-hingobway/examples/enriched_storage/enriched_storage.cpp >--- websocketpp-zaphoyd/examples/enriched_storage/enriched_storage.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/enriched_storage/enriched_storage.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -34,6 +34,7 @@ using websocketpp::connection_hdl; > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > class print_server { > public: >@@ -57,6 +58,11 @@ public: > std::cout << "Closing connection " << con->name > << " with sessionid " << con->sessionid << std::endl; > } >+ >+ void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+ } > > void on_message(connection_hdl hdl, server::message_ptr msg) { > connection_ptr con = m_server.get_con_from_hdl(hdl); >@@ -73,7 +79,7 @@ public: > > void run(uint16_t port) { > m_server.listen(port); >- m_server.start_accept(); >+ m_server.start_accept(bind(&print_server::on_end_accept,this,::_1,::_2)); > m_server.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_context/CMakeLists.txt websocketpp-hingobway/examples/external_io_context/CMakeLists.txt >--- websocketpp-zaphoyd/examples/external_io_context/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 >+++ websocketpp-hingobway/examples/external_io_context/CMakeLists.txt 2025-03-10 21:33:06.000000000 +0100 >@@ -0,0 +1,12 @@ >+ >+file (GLOB SOURCE_FILES *.cpp) >+file (GLOB HEADER_FILES *.hpp) >+ >+init_target (external_io_context) >+ >+build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES}) >+ >+link_boost () >+final_target () >+ >+set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples") >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_context/external_io_context.cpp websocketpp-hingobway/examples/external_io_context/external_io_context.cpp >--- websocketpp-zaphoyd/examples/external_io_context/external_io_context.cpp 1970-01-01 01:00:00.000000000 +0100 >+++ websocketpp-hingobway/examples/external_io_context/external_io_context.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (c) 2015, Peter Thorson. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions are met: >+ * * Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * * Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * * Neither the name of the WebSocket++ Project nor the >+ * names of its contributors may be used to endorse or promote products >+ * derived from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "tcp_echo_server.hpp" >+ >+#include <websocketpp/config/asio_no_tls.hpp> >+#include <websocketpp/server.hpp> >+ >+#include <iostream> >+ >+using websocketpp::lib::placeholders::_1; >+using websocketpp::lib::placeholders::_2; >+using websocketpp::lib::bind; >+using websocketpp::lib::error_code; >+ >+typedef websocketpp::server<websocketpp::config::asio> ws_echo_server; >+ >+// Define a callback to handle incoming messages >+void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_server::message_ptr msg) { >+ std::cout << "on_message called with hdl: " << hdl.lock().get() >+ << " and message: " << msg->get_payload() >+ << std::endl; >+ >+ // check for a special command to instruct the server to stop listening so >+ // it can be cleanly exited. >+ if (msg->get_payload() == "stop-listening") { >+ s->stop_listening(); >+ return; >+ } >+ >+ try { >+ s->send(hdl, msg->get_payload(), msg->get_opcode()); >+ } catch (websocketpp::exception const & e) { >+ std::cout << "Echo failed because: " >+ << "(" << e.what() << ")" << std::endl; >+ } >+} >+ >+// Define a callback to handle failures accepting connections >+void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+} >+ >+int main() { >+ websocketpp::lib::asio::io_context context; >+ >+ // Add a TCP echo server on port 9003 >+ tcp_echo_server custom_http_server(context, 9003); >+ >+ // Add a WebSocket echo server on port 9002 >+ ws_echo_server ws_server; >+ ws_server.set_access_channels(websocketpp::log::alevel::all); >+ ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload); >+ >+ // The only difference in this code between an internal and external >+ // io_context is the different constructor to init_asio >+ ws_server.init_asio(&context); >+ >+ // Register our message handler >+ ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2)); >+ ws_server.listen(9002); >+ ws_server.start_accept(&on_end_accept); >+ >+ // TODO: add a timer? >+ >+ // Start the Asio io_context run loop for all >+ context.run(); >+} >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_context/SConscript websocketpp-hingobway/examples/external_io_context/SConscript >--- websocketpp-zaphoyd/examples/external_io_context/SConscript 1970-01-01 01:00:00.000000000 +0100 >+++ websocketpp-hingobway/examples/external_io_context/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -0,0 +1,23 @@ >+## Main development example >+## >+ >+Import('env') >+Import('env_cpp11') >+Import('boostlibs') >+Import('platform_libs') >+Import('polyfill_libs') >+ >+env = env.Clone () >+env_cpp11 = env_cpp11.Clone () >+ >+prgs = [] >+ >+# if a C++11 environment is available build using that, otherwise use boost >+if 'WSPP_CPP11_ENABLED' in env_cpp11: >+ ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] >+ prgs += env_cpp11.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) >+else: >+ ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] >+ prgs += env.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) >+ >+Return('prgs') >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_context/tcp_echo_server.hpp websocketpp-hingobway/examples/external_io_context/tcp_echo_server.hpp >--- websocketpp-zaphoyd/examples/external_io_context/tcp_echo_server.hpp 1970-01-01 01:00:00.000000000 +0100 >+++ websocketpp-hingobway/examples/external_io_context/tcp_echo_server.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -0,0 +1,95 @@ >+/* >+ * Copyright (c) 2015, Peter Thorson. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions are met: >+ * * Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * * Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * * Neither the name of the WebSocket++ Project nor the >+ * names of its contributors may be used to endorse or promote products >+ * derived from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+/** >+ * TCP Echo Server >+ * >+ * This file defines a simple TCP Echo Server. It is adapted from the Asio >+ * example: cpp03/echo/async_tcp_echo_server.cpp >+ */ >+ >+#include <websocketpp/common/asio.hpp> >+#include <websocketpp/common/memory.hpp> >+#include <websocketpp/common/functional.hpp> >+ >+using websocketpp::lib::placeholders::_1; >+using websocketpp::lib::placeholders::_2; >+using websocketpp::lib::bind; >+ >+struct tcp_echo_session : websocketpp::lib::enable_shared_from_this<tcp_echo_session> { >+ typedef websocketpp::lib::shared_ptr<tcp_echo_session> ptr; >+ >+ tcp_echo_session(websocketpp::lib::asio::io_context & context) : m_socket(context) {} >+ >+ void start() { >+ m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)), >+ websocketpp::lib::bind( >+ &tcp_echo_session::handle_read, shared_from_this(), _1, _2)); >+ } >+ >+ void handle_read(const websocketpp::lib::asio::error_code & ec, size_t transferred) { >+ if (!ec) { >+ websocketpp::lib::asio::async_write(m_socket, >+ websocketpp::lib::asio::buffer(m_buffer, transferred), >+ bind(&tcp_echo_session::handle_write, shared_from_this(), _1)); >+ } >+ } >+ >+ void handle_write(const websocketpp::lib::asio::error_code & ec) { >+ if (!ec) { >+ m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)), >+ bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2)); >+ } >+ } >+ >+ websocketpp::lib::asio::ip::tcp::socket m_socket; >+ char m_buffer[1024]; >+}; >+ >+struct tcp_echo_server { >+ tcp_echo_server(websocketpp::lib::asio::io_context & context, short port) >+ : m_context(context) >+ , m_acceptor(context, websocketpp::lib::asio::ip::tcp::endpoint(websocketpp::lib::asio::ip::tcp::v6(), port)) >+ { >+ this->start_accept(); >+ } >+ >+ void start_accept() { >+ tcp_echo_session::ptr new_session(new tcp_echo_session(m_context)); >+ m_acceptor.async_accept(new_session->m_socket, >+ bind(&tcp_echo_server::handle_accept, this, new_session, _1)); >+ } >+ >+ void handle_accept(tcp_echo_session::ptr new_session, const websocketpp::lib::asio::error_code & ec) { >+ if (!ec) { >+ new_session->start(); >+ } >+ start_accept(); >+ } >+ >+ websocketpp::lib::asio::io_context & m_context; >+ websocketpp::lib::asio::ip::tcp::acceptor m_acceptor; >+}; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_service/CMakeLists.txt websocketpp-hingobway/examples/external_io_service/CMakeLists.txt >--- websocketpp-zaphoyd/examples/external_io_service/CMakeLists.txt 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/external_io_service/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 >@@ -1,12 +0,0 @@ >- >-file (GLOB SOURCE_FILES *.cpp) >-file (GLOB HEADER_FILES *.hpp) >- >-init_target (external_io_service) >- >-build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES}) >- >-link_boost () >-final_target () >- >-set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "examples") >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_service/external_io_service.cpp websocketpp-hingobway/examples/external_io_service/external_io_service.cpp >--- websocketpp-zaphoyd/examples/external_io_service/external_io_service.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/external_io_service/external_io_service.cpp 1970-01-01 01:00:00.000000000 +0100 >@@ -1,85 +0,0 @@ >-/* >- * Copyright (c) 2015, Peter Thorson. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions are met: >- * * Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * * Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * * Neither the name of the WebSocket++ Project nor the >- * names of its contributors may be used to endorse or promote products >- * derived from this software without specific prior written permission. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY >- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "tcp_echo_server.hpp" >- >-#include <websocketpp/config/asio_no_tls.hpp> >-#include <websocketpp/server.hpp> >- >-#include <iostream> >- >-using websocketpp::lib::placeholders::_1; >-using websocketpp::lib::placeholders::_2; >-using websocketpp::lib::bind; >- >-typedef websocketpp::server<websocketpp::config::asio> ws_echo_server; >- >-// Define a callback to handle incoming messages >-void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_server::message_ptr msg) { >- std::cout << "on_message called with hdl: " << hdl.lock().get() >- << " and message: " << msg->get_payload() >- << std::endl; >- >- // check for a special command to instruct the server to stop listening so >- // it can be cleanly exited. >- if (msg->get_payload() == "stop-listening") { >- s->stop_listening(); >- return; >- } >- >- try { >- s->send(hdl, msg->get_payload(), msg->get_opcode()); >- } catch (websocketpp::exception const & e) { >- std::cout << "Echo failed because: " >- << "(" << e.what() << ")" << std::endl; >- } >-} >- >-int main() { >- asio::io_service service; >- >- // Add a TCP echo server on port 9003 >- tcp_echo_server custom_http_server(service, 9003); >- >- // Add a WebSocket echo server on port 9002 >- ws_echo_server ws_server; >- ws_server.set_access_channels(websocketpp::log::alevel::all); >- ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload); >- >- // The only difference in this code between an internal and external >- // io_service is the different constructor to init_asio >- ws_server.init_asio(&service); >- >- // Register our message handler >- ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2)); >- ws_server.listen(9002); >- ws_server.start_accept(); >- >- // TODO: add a timer? >- >- // Start the Asio io_service run loop for all >- service.run(); >-} >\ Nincs új sor a fájl végén >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_service/SConscript websocketpp-hingobway/examples/external_io_service/SConscript >--- websocketpp-zaphoyd/examples/external_io_service/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/external_io_service/SConscript 1970-01-01 01:00:00.000000000 +0100 >@@ -1,23 +0,0 @@ >-## Main development example >-## >- >-Import('env') >-Import('env_cpp11') >-Import('boostlibs') >-Import('platform_libs') >-Import('polyfill_libs') >- >-env = env.Clone () >-env_cpp11 = env_cpp11.Clone () >- >-prgs = [] >- >-# if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >- ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] >- prgs += env_cpp11.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) >-else: >- ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] >- prgs += env.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) >- >-Return('prgs') >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/external_io_service/tcp_echo_server.hpp websocketpp-hingobway/examples/external_io_service/tcp_echo_server.hpp >--- websocketpp-zaphoyd/examples/external_io_service/tcp_echo_server.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/external_io_service/tcp_echo_server.hpp 1970-01-01 01:00:00.000000000 +0100 >@@ -1,97 +0,0 @@ >-/* >- * Copyright (c) 2015, Peter Thorson. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions are met: >- * * Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * * Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * * Neither the name of the WebSocket++ Project nor the >- * names of its contributors may be used to endorse or promote products >- * derived from this software without specific prior written permission. >- * >- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY >- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-/** >- * TCP Echo Server >- * >- * This file defines a simple TCP Echo Server. It is adapted from the Asio >- * example: cpp03/echo/async_tcp_echo_server.cpp >- */ >- >-#include <websocketpp/common/asio.hpp> >-#include <websocketpp/common/memory.hpp> >-#include <websocketpp/common/functional.hpp> >- >-using websocketpp::lib::placeholders::_1; >-using websocketpp::lib::placeholders::_2; >-using websocketpp::lib::bind; >- >-namespace asio = websocketpp::lib::asio; >- >-struct tcp_echo_session : websocketpp::lib::enable_shared_from_this<tcp_echo_session> { >- typedef websocketpp::lib::shared_ptr<tcp_echo_session> ptr; >- >- tcp_echo_session(asio::io_service & service) : m_socket(service) {} >- >- void start() { >- m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), >- websocketpp::lib::bind( >- &tcp_echo_session::handle_read, shared_from_this(), _1, _2)); >- } >- >- void handle_read(const asio::error_code & ec, size_t transferred) { >- if (!ec) { >- asio::async_write(m_socket, >- asio::buffer(m_buffer, transferred), >- bind(&tcp_echo_session::handle_write, shared_from_this(), _1)); >- } >- } >- >- void handle_write(const asio::error_code & ec) { >- if (!ec) { >- m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), >- bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2)); >- } >- } >- >- asio::ip::tcp::socket m_socket; >- char m_buffer[1024]; >-}; >- >-struct tcp_echo_server { >- tcp_echo_server(asio::io_service & service, short port) >- : m_service(service) >- , m_acceptor(service, asio::ip::tcp::endpoint(asio::ip::tcp::v6(), port)) >- { >- this->start_accept(); >- } >- >- void start_accept() { >- tcp_echo_session::ptr new_session(new tcp_echo_session(m_service)); >- m_acceptor.async_accept(new_session->m_socket, >- bind(&tcp_echo_server::handle_accept, this, new_session, _1)); >- } >- >- void handle_accept(tcp_echo_session::ptr new_session, const asio::error_code & ec) { >- if (!ec) { >- new_session->start(); >- } >- start_accept(); >- } >- >- asio::io_service & m_service; >- asio::ip::tcp::acceptor m_acceptor; >-}; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/handler_switch/handler_switch.cpp websocketpp-hingobway/examples/handler_switch/handler_switch.cpp >--- websocketpp-zaphoyd/examples/handler_switch/handler_switch.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/handler_switch/handler_switch.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -36,7 +36,7 @@ int main() { > > s.init_asio(); > s.listen(9002); >- s.start_accept(); >+ s.start_accept(NULL); // ignore errors to keep example code consise > > s.run(); > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/iostream_server/iostream_server.cpp websocketpp-hingobway/examples/iostream_server/iostream_server.cpp >--- websocketpp-zaphoyd/examples/iostream_server/iostream_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/iostream_server/iostream_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -10,6 +10,7 @@ typedef websocketpp::server<websocketpp: > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > // pull out the type of messages sent by our config > typedef server::message_ptr message_ptr; >@@ -55,7 +56,12 @@ int main() { > // Register our message handler > s.set_message_handler(bind(&on_message,&s,::_1,::_2)); > >- server::connection_ptr con = s.get_connection(); >+ error_code ec; >+ server::connection_ptr con = s.get_connection(ec); >+ if (ec) { >+ std::cout << "Failed to generate new connection because " << ec.message() << std::endl; >+ return 1; >+ } > > con->start(); > >@@ -69,7 +75,7 @@ int main() { > // messages being buffered forever. The non-buffered strategy below > // reads characters from stdin one at a time. This is inefficient and > // for more serious uses should be replaced with a platform specific >- // asyncronous i/o technique like select, poll, IOCP, etc >+ // asynchronous i/o technique like select, poll, IOCP, etc > bool buffered_io = false; > > if (buffered_io) { >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/iostream_server/SConscript websocketpp-hingobway/examples/iostream_server/SConscript >--- websocketpp-zaphoyd/examples/iostream_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/iostream_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('iostream_server', ["iostream_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_client/print_client.cpp websocketpp-hingobway/examples/print_client/print_client.cpp >--- websocketpp-zaphoyd/examples/print_client/print_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_client/print_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -68,7 +68,7 @@ int main(int argc, char* argv[]) { > // exchanged until the event loop starts running in the next line. > c.connect(con); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > // this will cause a single connection to be made to the server. c.run() > // will exit when this connection is closed. > c.run(); >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_client/SConscript websocketpp-hingobway/examples/print_client/SConscript >--- websocketpp-zaphoyd/examples/print_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('print_client', ["print_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_client_tls/print_client_tls.cpp websocketpp-hingobway/examples/print_client_tls/print_client_tls.cpp >--- websocketpp-zaphoyd/examples/print_client_tls/print_client_tls.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_client_tls/print_client_tls.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -112,7 +112,7 @@ bool verify_common_name(char const * hos > * and > * https://github.com/iSECPartners/ssl-conservatory > */ >-bool verify_certificate(const char * hostname, bool preverified, boost::asio::ssl::verify_context& ctx) { >+bool verify_certificate(const char * hostname, bool preverified, websocketpp::lib::asio::ssl::verify_context& ctx) { > // The verify callback can be used to check whether the certificate that is > // being presented is valid for the peer. For example, RFC 2818 describes > // the steps involved in doing this for HTTPS. Consult the OpenSSL >@@ -176,16 +176,16 @@ bool verify_certificate(const char * hos > * (websocketpp.org, for example). > */ > context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) { >- context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23); >+ context_ptr ctx = websocketpp::lib::make_shared<websocketpp::lib::asio::ssl::context>(websocketpp::lib::asio::ssl::context::sslv23); > > try { >- ctx->set_options(boost::asio::ssl::context::default_workarounds | >- boost::asio::ssl::context::no_sslv2 | >- boost::asio::ssl::context::no_sslv3 | >- boost::asio::ssl::context::single_dh_use); >+ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | >+ websocketpp::lib::asio::ssl::context::no_sslv2 | >+ websocketpp::lib::asio::ssl::context::no_sslv3 | >+ websocketpp::lib::asio::ssl::context::single_dh_use); > > >- ctx->set_verify_mode(boost::asio::ssl::verify_peer); >+ ctx->set_verify_mode(websocketpp::lib::asio::ssl::verify_peer); > ctx->set_verify_callback(bind(&verify_certificate, hostname, ::_1, ::_2)); > > // Here we load the CA certificates of all CA's that this client trusts. >@@ -239,7 +239,7 @@ int main(int argc, char* argv[]) { > > c.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > // this will cause a single connection to be made to the server. c.run() > // will exit when this connection is closed. > c.run(); >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_client_tls/SConscript websocketpp-hingobway/examples/print_client_tls/SConscript >--- websocketpp-zaphoyd/examples/print_client_tls/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_client_tls/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,7 +14,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > prgs += env_cpp11.Program('print_client_tls', ["print_client_tls.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_server/print_server.cpp websocketpp-hingobway/examples/print_server/print_server.cpp >--- websocketpp-zaphoyd/examples/print_server/print_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_server/print_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -18,7 +18,7 @@ int main() { > > print_server.init_asio(); > print_server.listen(9002); >- print_server.start_accept(); >+ print_server.start_accept(NULL); // omit error handling to keep example consise > > print_server.run(); > } >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/print_server/SConscript websocketpp-hingobway/examples/print_server/SConscript >--- websocketpp-zaphoyd/examples/print_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/print_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('print_server', ["print_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/scratch_client/SConscript websocketpp-hingobway/examples/scratch_client/SConscript >--- websocketpp-zaphoyd/examples/scratch_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/scratch_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,11 +14,11 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > prgs += env_cpp11.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS) > else: > ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] >- prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS) >+ prgs += env.Program('scratch_client', ["scratch_client.cpp"], LIBS = ALL_LIBS) > > Return('prgs') >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/scratch_server/SConscript websocketpp-hingobway/examples/scratch_server/SConscript >--- websocketpp-zaphoyd/examples/scratch_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/scratch_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -14,7 +14,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] + ['z'] > prgs += env_cpp11.Program('scratch_server', ["scratch_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/scratch_server/scratch_server.cpp websocketpp-hingobway/examples/scratch_server/scratch_server.cpp >--- websocketpp-zaphoyd/examples/scratch_server/scratch_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/scratch_server/scratch_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -94,7 +94,7 @@ int main(int argc, char * argv[]) { > // Start the server accept loop > echo_server.start_accept(); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > echo_server.run(); > } catch (websocketpp::exception const & e) { > std::cout << e.what() << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/simple_broadcast_server/simple_broadcast_server.cpp websocketpp-hingobway/examples/simple_broadcast_server/simple_broadcast_server.cpp >--- websocketpp-zaphoyd/examples/simple_broadcast_server/simple_broadcast_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/simple_broadcast_server/simple_broadcast_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -8,6 +8,7 @@ using websocketpp::connection_hdl; > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > class broadcast_server { > public: >@@ -27,6 +28,11 @@ public: > m_connections.erase(hdl); > } > >+ void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+ } >+ > void on_message(connection_hdl hdl, server::message_ptr msg) { > for (auto it : m_connections) { > m_server.send(it,msg); >@@ -35,7 +41,7 @@ public: > > void run(uint16_t port) { > m_server.listen(port); >- m_server.start_accept(); >+ m_server.start_accept(bind(&broadcast_server::on_end_accept,this,::_1,::_2)); > m_server.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/sip_client/SConscript websocketpp-hingobway/examples/sip_client/SConscript >--- websocketpp-zaphoyd/examples/sip_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/sip_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('sip_client', ["sip_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/sip_client/sip_client.cpp websocketpp-hingobway/examples/sip_client/sip_client.cpp >--- websocketpp-zaphoyd/examples/sip_client/sip_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/sip_client/sip_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -69,7 +69,7 @@ int main(int argc, char* argv[]) { > > sip_client.connect(con); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > sip_client.run(); > > while(!received) { >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/subprotocol_server/SConscript websocketpp-hingobway/examples/subprotocol_server/SConscript >--- websocketpp-zaphoyd/examples/subprotocol_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/subprotocol_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('subprotocol_server', ["subprotocol_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/subprotocol_server/subprotocol_server.cpp websocketpp-hingobway/examples/subprotocol_server/subprotocol_server.cpp >--- websocketpp-zaphoyd/examples/subprotocol_server/subprotocol_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/subprotocol_server/subprotocol_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -39,7 +39,7 @@ int main() { > > s.init_asio(); > s.listen(9005); >- s.start_accept(); >+ s.start_accept(NULL); // omit error handling to keep example consise > > s.run(); > } catch (websocketpp::exception const & e) { >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/telemetry_client/SConscript websocketpp-hingobway/examples/telemetry_client/SConscript >--- websocketpp-zaphoyd/examples/telemetry_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/telemetry_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('telemetry_client', ["telemetry_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/telemetry_client/telemetry_client.cpp websocketpp-hingobway/examples/telemetry_client/telemetry_client.cpp >--- websocketpp-zaphoyd/examples/telemetry_client/telemetry_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/telemetry_client/telemetry_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -62,10 +62,10 @@ public: > m_hdl = con->get_handle(); > > // Queue the connection. No DNS queries or network connections will be >- // made until the io_service event loop is run. >+ // made until the io_context event loop is run. > m_client.connect(con); > >- // Create a thread to run the ASIO io_service event loop >+ // Create a thread to run the ASIO io_context event loop > websocketpp::lib::thread asio_thread(&client::run, &m_client); > > // Create a thread to run the telemetry loop >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/telemetry_server/SConscript websocketpp-hingobway/examples/telemetry_server/SConscript >--- websocketpp-zaphoyd/examples/telemetry_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/telemetry_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('telemetry_server', ["telemetry_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/telemetry_server/telemetry_server.cpp websocketpp-hingobway/examples/telemetry_server/telemetry_server.cpp >--- websocketpp-zaphoyd/examples/telemetry_server/telemetry_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/telemetry_server/telemetry_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -8,6 +8,11 @@ > #include <streambuf> > #include <string> > >+using websocketpp::lib::placeholders::_1; >+using websocketpp::lib::placeholders::_2; >+using websocketpp::lib::bind; >+using websocketpp::lib::error_code; >+ > /** > * The telemetry server accepts connections and sends a message every second to > * each client containing an integer count. This example can be used as the >@@ -43,8 +48,6 @@ public: > m_endpoint.init_asio(); > > // Bind the handlers we are using >- using websocketpp::lib::placeholders::_1; >- using websocketpp::lib::bind; > m_endpoint.set_open_handler(bind(&telemetry_server::on_open,this,_1)); > m_endpoint.set_close_handler(bind(&telemetry_server::on_close,this,_1)); > m_endpoint.set_http_handler(bind(&telemetry_server::on_http,this,_1)); >@@ -61,12 +64,12 @@ public: > m_endpoint.listen(port); > > // Start the server accept loop >- m_endpoint.start_accept(); >+ m_endpoint.start_accept(bind(&telemetry_server::on_end_accept,this,_1,_2)); > > // Set the initial timer to start telemetry > set_timer(); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > try { > m_endpoint.run(); > } catch (websocketpp::exception const & e) { >@@ -85,7 +88,7 @@ public: > ); > } > >- void on_timer(websocketpp::lib::error_code const & ec) { >+ void on_timer(error_code const & ec) { > if (ec) { > // there was an error, stop telemetry > m_endpoint.get_alog().write(websocketpp::log::alevel::app, >@@ -149,7 +152,7 @@ public: > response.assign((std::istreambuf_iterator<char>(file)), > std::istreambuf_iterator<char>()); > >- con->set_body(response); >+ con->set_body(std::move(response)); > con->set_status(websocketpp::http::status_code::ok); > } > >@@ -160,6 +163,11 @@ public: > void on_close(connection_hdl hdl) { > m_connections.erase(hdl); > } >+ >+ void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+ } > private: > typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list; > >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/testee_client/SConscript websocketpp-hingobway/examples/testee_client/SConscript >--- websocketpp-zaphoyd/examples/testee_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/testee_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z'] > prgs += env_cpp11.Program('testee_client', ["testee_client.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/testee_client/testee_client.cpp websocketpp-hingobway/examples/testee_client/testee_client.cpp >--- websocketpp-zaphoyd/examples/testee_client/testee_client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/testee_client/testee_client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -117,7 +117,7 @@ int main(int argc, char* argv[]) { > client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec); > c.connect(con); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > c.run(); > > std::cout << "case count: " << case_count << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/testee_server/SConscript websocketpp-hingobway/examples/testee_server/SConscript >--- websocketpp-zaphoyd/examples/testee_server/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/testee_server/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,7 +13,7 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z'] > prgs += env_cpp11.Program('testee_server', ["testee_server.cpp"], LIBS = ALL_LIBS) > else: >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/testee_server/testee_server.cpp websocketpp-hingobway/examples/testee_server/testee_server.cpp >--- websocketpp-zaphoyd/examples/testee_server/testee_server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/testee_server/testee_server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -78,6 +78,7 @@ typedef websocketpp::server<testee_confi > using websocketpp::lib::placeholders::_1; > using websocketpp::lib::placeholders::_2; > using websocketpp::lib::bind; >+using websocketpp::lib::error_code; > > // pull out the type of messages sent by our config > typedef server::message_ptr message_ptr; >@@ -87,11 +88,17 @@ void on_message(server* s, websocketpp:: > s->send(hdl, msg->get_payload(), msg->get_opcode()); > } > >-void on_socket_init(websocketpp::connection_hdl, boost::asio::ip::tcp::socket & s) { >- boost::asio::ip::tcp::no_delay option(true); >+void on_socket_init(websocketpp::connection_hdl, websocketpp::lib::asio::ip::tcp::socket & s) { >+ websocketpp::lib::asio::ip::tcp::no_delay option(true); > s.set_option(option); > } > >+// Define a callback to handle failures accepting connections >+void on_end_accept(error_code lib_ec, error_code trans_ec) { >+ std::cout << "Accept loop ended " >+ << lib_ec.message() << "/" << trans_ec.message() << std::endl; >+} >+ > int main(int argc, char * argv[]) { > // Create a server endpoint > server testee_server; >@@ -122,9 +129,9 @@ int main(int argc, char * argv[]) { > testee_server.listen(port); > > // Start the server accept loop >- testee_server.start_accept(); >+ testee_server.start_accept(&on_end_accept); > >- // Start the ASIO io_service run loop >+ // Start the ASIO io_context run loop > if (num_threads == 1) { > testee_server.run(); > } else { >diff '--color=auto' -urNp websocketpp-zaphoyd/examples/utility_client/SConscript websocketpp-hingobway/examples/utility_client/SConscript >--- websocketpp-zaphoyd/examples/utility_client/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/examples/utility_client/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -13,11 +13,11 @@ env_cpp11 = env_cpp11.Clone () > prgs = [] > > # if a C++11 environment is available build using that, otherwise use boost >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] > prgs += env_cpp11.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS) > else: > ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] > prgs += env.Program('utility_client', ["utility_client.cpp"], LIBS = ALL_LIBS) > >-Return('prgs') >\ Nincs új sor a fájl végén >+Return('prgs') >diff '--color=auto' -urNp websocketpp-zaphoyd/readme.md websocketpp-hingobway/readme.md >--- websocketpp-zaphoyd/readme.md 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/readme.md 2025-03-10 21:33:06.000000000 +0100 >@@ -1,4 +1,4 @@ >-WebSocket++ (0.8.2) >+WebSocket++ (0.8.x-dev) > ========================== > > WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket >@@ -44,6 +44,10 @@ http://groups.google.com/group/websocket > **Discussion / Development / Support Mailing List / Forum** > http://groups.google.com/group/websocketpp/ > >+License >+====== >+3-Clause BSD (See COPYING for more details) >+ > Author > ====== > Peter Thorson - websocketpp@zaphoyd.com >diff '--color=auto' -urNp websocketpp-zaphoyd/SConstruct websocketpp-hingobway/SConstruct >--- websocketpp-zaphoyd/SConstruct 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/SConstruct 2025-03-10 21:33:06.000000000 +0100 >@@ -1,18 +1,20 @@ >-import os, sys, commands >+import os, sys, SCons.Errors >+from subprocess import check_output >+ > env = Environment(ENV = os.environ) > > # figure out a better way to configure this >-if os.environ.has_key('CXX'): >+if 'CXX' in os.environ: > env['CXX'] = os.environ['CXX'] > >-if os.environ.has_key('DEBUG'): >+if 'DEBUG' in os.environ: > env['DEBUG'] = os.environ['DEBUG'] > >-if os.environ.has_key('CXXFLAGS'): >+if 'CXXFLAGS' in os.environ: > #env['CXXFLAGS'] = os.environ['CXXFLAGS'] > env.Append(CXXFLAGS = os.environ['CXXFLAGS']) > >-if os.environ.has_key('LINKFLAGS'): >+if 'LINKFLAGS' in os.environ: > #env['LDFLAGS'] = os.environ['LDFLAGS'] > env.Append(LINKFLAGS = os.environ['LINKFLAGS']) > >@@ -22,24 +24,24 @@ if os.environ.has_key('LINKFLAGS'): > ## or set BOOST_INCLUDES and BOOST_LIBS if Boost comes with your OS distro e.g. and > ## needs BOOST_INCLUDES=/usr/include/boost and BOOST_LIBS=/usr/lib like Ubuntu. > ## >-if os.environ.has_key('BOOSTROOT'): >+if 'BOOSTROOT' in os.environ: > os.environ['BOOST_ROOT'] = os.environ['BOOSTROOT'] > >-if os.environ.has_key('BOOST_ROOT'): >+if 'BOOST_ROOT' in os.environ: > env['BOOST_INCLUDES'] = os.environ['BOOST_ROOT'] > env['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT'], 'stage', 'lib') >-elif os.environ.has_key('BOOST_INCLUDES') and os.environ.has_key('BOOST_LIBS'): >+elif 'BOOST_INCLUDES' in os.environ and 'BOOST_LIBS' in os.environ: > env['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES'] > env['BOOST_LIBS'] = os.environ['BOOST_LIBS'] > else: >- raise SCons.Errors.UserError, "Neither BOOST_ROOT, nor BOOST_INCLUDES + BOOST_LIBS was set!" >+ raise SCons.Errors.UserError("Neither BOOST_ROOT, nor BOOST_INCLUDES + BOOST_LIBS were set!") > > ## Custom OpenSSL >-if os.environ.has_key('OPENSSL_PATH'): >+if 'OPENSSL_PATH' in os.environ: > env.Append(CPPPATH = os.path.join(os.environ['OPENSSL_PATH'], 'include')) > env.Append(LIBPATH = os.environ['OPENSSL_PATH']) > >-if os.environ.has_key('WSPP_ENABLE_CPP11'): >+if 'WSPP_ENABLE_CPP11' in os.environ: > env['WSPP_ENABLE_CPP11'] = True > else: > env['WSPP_ENABLE_CPP11'] = False >@@ -76,7 +78,7 @@ if env['PLATFORM'].startswith('win'): > env['CCFLAGS'] = '%s /EHsc /GR /GS- /MD /nologo %s %s' % (warn_flags, arch_flags, opt_flags) > env['LINKFLAGS'] = '/INCREMENTAL:NO /MANIFEST /NOLOGO /OPT:REF /OPT:ICF /MACHINE:X86' > elif env['PLATFORM'] == 'posix': >- if env.has_key('DEBUG'): >+ if 'DEBUG' in env: > env.Append(CCFLAGS = ['-g', '-O0']) > else: > env.Append(CPPDEFINES = ['NDEBUG']) >@@ -84,9 +86,9 @@ elif env['PLATFORM'] == 'posix': > env.Append(CCFLAGS = ['-Wall']) > #env['LINKFLAGS'] = '' > elif env['PLATFORM'] == 'darwin': >- if not os.environ.has_key('CXX'): >+ if not 'CXX' in os.environ: > env['CXX'] = "clang++" >- if env.has_key('DEBUG'): >+ if 'DEBUG' in env: > env.Append(CCFLAGS = ['-g', '-O0']) > else: > env.Append(CPPDEFINES = ['NDEBUG']) >@@ -157,29 +159,29 @@ env_cpp11 = env.Clone () > > if env_cpp11['CXX'].startswith('g++'): > # TODO: check g++ version >- GCC_VERSION = commands.getoutput(env_cpp11['CXX'] + ' -dumpversion') >+ GCC_VERSION = check_output([env_cpp11['CXX'], '-dumpversion']).decode("utf-8") > > if GCC_VERSION > "4.4.0": >- print "C++11 build environment partially enabled" >+ print("C++11 build environment partially enabled") > env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x'],TOOLSET = ['g++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_']) > else: >- print "C++11 build environment is not supported on this version of G++" >+ print("C++11 build environment is not supported on this version of G++") > elif env_cpp11['CXX'].startswith('clang++'): >- print "C++11 build environment enabled" >- env.Append(CXXFLANGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++']) >+ print("C++11 build environment enabled") >+ env.Append(CXXFLAGS = ['-stdlib=libc++'],LINKFLAGS=['-stdlib=libc++']) > env_cpp11.Append(WSPP_CPP11_ENABLED = "true",CXXFLAGS = ['-std=c++0x','-stdlib=libc++'],LINKFLAGS = ['-stdlib=libc++'],TOOLSET = ['clang++'],CPPDEFINES = ['_WEBSOCKETPP_CPP11_STL_']) > > # look for optional second boostroot compiled with clang's libc++ STL library > # this prevents warnings/errors when linking code built with two different > # incompatible STL libraries. >- if os.environ.has_key('BOOST_ROOT_CPP11'): >+ if 'BOOST_ROOT_CPP11' in os.environ: > env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_ROOT_CPP11'] > env_cpp11['BOOST_LIBS'] = os.path.join(os.environ['BOOST_ROOT_CPP11'], 'stage', 'lib') >- elif os.environ.has_key('BOOST_INCLUDES_CPP11') and os.environ.has_key('BOOST_LIBS_CPP11'): >+ elif 'BOOST_INCLUDES_CPP11' in os.environ and 'BOOST_LIBS_CPP11' in os.environ: > env_cpp11['BOOST_INCLUDES'] = os.environ['BOOST_INCLUDES_CPP11'] > env_cpp11['BOOST_LIBS'] = os.environ['BOOST_LIBS_CPP11'] > else: >- print "C++11 build environment disabled" >+ print("C++11 build environment disabled") > > # if the build system is known to allow the isystem modifier for library include > # values then use it for the boost libraries. Otherwise just add them to the >@@ -271,8 +273,8 @@ subprotocol_server = SConscript('#/examp > # telemetry_server > telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0) > >-# external_io_service >-external_io_service = SConscript('#/examples/external_io_service/SConscript',variant_dir = builddir + 'external_io_service',duplicate = 0) >+# external_io_context >+external_io_context = SConscript('#/examples/external_io_context/SConscript',variant_dir = builddir + 'external_io_context',duplicate = 0) > > if not env['PLATFORM'].startswith('win'): > # iostream_server >diff '--color=auto' -urNp websocketpp-zaphoyd/test/connection/connection.cpp websocketpp-hingobway/test/connection/connection.cpp >--- websocketpp-zaphoyd/test/connection/connection.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/connection/connection.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -175,6 +175,20 @@ void http_func(server* s, websocketpp::c > BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok)); > } > >+void http_func_with_move(server* s, websocketpp::connection_hdl hdl) { >+ using namespace websocketpp::http; >+ >+ server::connection_ptr con = s->get_con_from_hdl(hdl); >+ >+ std::string res = con->get_resource(); >+ >+ con->set_body(std::move(res)); >+ con->set_status(status_code::ok); >+ >+ BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok); >+ BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok)); >+} >+ > void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) { > *deferred = true; > >@@ -239,6 +253,18 @@ BOOST_AUTO_TEST_CASE( http_request ) { > > BOOST_CHECK_EQUAL(run_server_test(s,input), output); > } >+ >+BOOST_AUTO_TEST_CASE( http_request_with_move ) { >+ std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n"; >+ std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: "; >+ output+=websocketpp::user_agent; >+ output+="\r\n\r\n/foo/bar"; >+ >+ server s; >+ s.set_http_handler(bind(&http_func_with_move,&s,::_1)); >+ >+ BOOST_CHECK_EQUAL(run_server_test(s,input), output); >+} > > BOOST_AUTO_TEST_CASE( deferred_http_request ) { > std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n"; >diff '--color=auto' -urNp websocketpp-zaphoyd/test/connection/SConscript websocketpp-hingobway/test/connection/SConscript >--- websocketpp-zaphoyd/test/connection/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/connection/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -16,7 +16,7 @@ objs = env.Object('connection_boost.o', > objs = env.Object('connection_tu2_boost.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS) > prgs = env.Program('test_connection_boost', ["connection_boost.o","connection_tu2_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('connection_tu2_stl.o', ["connection_tu2.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/endpoint/endpoint.cpp websocketpp-hingobway/test/endpoint/endpoint.cpp >--- websocketpp-zaphoyd/test/endpoint/endpoint.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/endpoint/endpoint.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE( initialize_server_ > > BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) { > websocketpp::server<websocketpp::config::asio> s; >- boost::asio::io_service ios; >- s.init_asio(&ios); >+ websocketpp::lib::asio::io_context ctx; >+ s.init_asio(&ctx); > } > > #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ >@@ -141,8 +141,8 @@ BOOST_AUTO_TEST_CASE( listen_after_liste > server1.init_asio(); > server2.init_asio(); > >- boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345); >- boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456); >+ websocketpp::lib::asio::ip::tcp::endpoint ep1(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 12345); >+ websocketpp::lib::asio::ip::tcp::endpoint ep2(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 23456); > > server1.listen(ep1, ec); > BOOST_CHECK(!ec); >diff '--color=auto' -urNp websocketpp-zaphoyd/test/endpoint/SConscript websocketpp-hingobway/test/endpoint/SConscript >--- websocketpp-zaphoyd/test/endpoint/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/endpoint/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -16,7 +16,7 @@ BOOST_LIBS = boostlibs(['unit_test_frame > objs = env.Object('endpoint_boost.o', ["endpoint.cpp"], LIBS = BOOST_LIBS) > prgs = env.Program('test_endpoint_boost', ["endpoint_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > objs += env_cpp11.Object('endpoint_stl.o', ["endpoint.cpp"], LIBS = BOOST_LIBS_CPP11) > prgs += env_cpp11.Program('test_endpoint_stl', ["endpoint_stl.o"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/extension/SConscript websocketpp-hingobway/test/extension/SConscript >--- websocketpp-zaphoyd/test/extension/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/extension/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -17,7 +17,7 @@ objs += env.Object('permessage_deflate_b > prgs = env.Program('test_extension_boost', ["extension_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_permessage_deflate_boost', ["permessage_deflate_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z'] > objs += env_cpp11.Object('extension_stl.o', ["extension.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('permessage_deflate_stl.o', ["permessage_deflate.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/http/parser.cpp websocketpp-hingobway/test/http/parser.cpp >--- websocketpp-zaphoyd/test/http/parser.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/http/parser.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -412,15 +412,10 @@ BOOST_AUTO_TEST_CASE( blank_consume ) { > > std::string raw; > >- bool exception = false; >- >- try { >- r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >- >- BOOST_CHECK( exception == false ); >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); >+ >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK( r.ready() == false ); > } > >@@ -429,15 +424,10 @@ BOOST_AUTO_TEST_CASE( blank_request ) { > > std::string raw = "\r\n\r\n"; > >- bool exception = false; >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >- try { >- r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >- >- BOOST_CHECK( exception == true ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(websocketpp::http::error::incomplete_request)); > BOOST_CHECK( r.ready() == false ); > } > >@@ -446,15 +436,10 @@ BOOST_AUTO_TEST_CASE( bad_request_no_hos > > std::string raw = "GET / HTTP/1.1\r\n\r\n"; > >- bool exception = false; >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >- try { >- r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >- >- BOOST_CHECK( exception == true ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code(websocketpp::http::error::incomplete_request)); > BOOST_CHECK( r.ready() == false ); > } > >@@ -463,17 +448,12 @@ BOOST_AUTO_TEST_CASE( basic_request ) { > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); > >- BOOST_CHECK( exception == false ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK( pos == 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >@@ -487,17 +467,12 @@ BOOST_AUTO_TEST_CASE( basic_request_with > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 5\r\n\r\nabcdef"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); > >- BOOST_CHECK( exception == false ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK_EQUAL( pos, 65 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -526,18 +501,15 @@ BOOST_AUTO_TEST_CASE( basic_request_with > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabc"; > std::string raw2 = "def"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- pos += r.consume(raw2.c_str(),raw2.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ pos += r.consume(raw2.c_str(),raw2.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 66 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -555,16 +527,12 @@ BOOST_AUTO_TEST_CASE( trailing_body_char > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\na"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); > >- BOOST_CHECK( exception == false ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK( pos == 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >@@ -579,16 +547,12 @@ BOOST_AUTO_TEST_CASE( trailing_body_char > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"; > raw.append(websocketpp::http::max_header_size,'*'); > >- bool exception = false; > size_t pos = 0; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); > >- BOOST_CHECK( exception == false ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK( pos == 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >@@ -603,18 +567,16 @@ BOOST_AUTO_TEST_CASE( basic_split1 ) { > std::string raw = "GET / HTTP/1.1\r\n"; > std::string raw2 = "Host: www.example.com\r\n\r\na"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- pos += r.consume(raw2.c_str(),raw2.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ BOOST_CHECK( pos == raw.size() ); >+ >+ pos += r.consume(raw2.c_str(),raw2.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK( pos == 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >@@ -629,18 +591,16 @@ BOOST_AUTO_TEST_CASE( basic_split2 ) { > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r"; > std::string raw2 = "\n\r\na"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- pos += r.consume(raw2.c_str(),raw2.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ websocketpp::lib::error_code ec; >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ BOOST_CHECK( pos == raw.size() ); >+ >+ pos += r.consume(raw2.c_str(),raw2.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK( pos == 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >@@ -655,18 +615,11 @@ BOOST_AUTO_TEST_CASE( max_header_len ) { > std::string raw(websocketpp::http::max_header_size-1,'*'); > raw += "\r\n"; > >- bool exception = false; >- size_t pos = 0; >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (const websocketpp::http::exception& e) { >- if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) { >- exception = true; >- } >- } >- >- BOOST_CHECK( exception == true ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::request_header_fields_too_large)); > } > > BOOST_AUTO_TEST_CASE( max_header_len_split ) { >@@ -675,19 +628,16 @@ BOOST_AUTO_TEST_CASE( max_header_len_spl > std::string raw(websocketpp::http::max_header_size-1,'*'); > std::string raw2(2,'*'); > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- pos += r.consume(raw2.c_str(),raw2.size()); >- } catch (const websocketpp::http::exception& e) { >- if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) { >- exception = true; >- } >- } >- >- BOOST_CHECK( exception == true ); >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ BOOST_CHECK_EQUAL(pos, raw.size()); >+ >+ r.consume(raw2.c_str(),raw2.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::request_header_fields_too_large)); > } > > BOOST_AUTO_TEST_CASE( max_body_len ) { >@@ -697,18 +647,12 @@ BOOST_AUTO_TEST_CASE( max_body_len ) { > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabcdef"; > >- bool exception = false; >- size_t pos = 0; >- >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (websocketpp::http::exception const & e) { >- exception = true; >- BOOST_CHECK_EQUAL(e.m_error_code,websocketpp::http::status_code::request_entity_too_large); >- } >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::body_too_large)); > BOOST_CHECK_EQUAL(r.get_max_body_size(),5); >- BOOST_CHECK( exception == true ); > } > > BOOST_AUTO_TEST_CASE( firefox_full_request ) { >@@ -716,33 +660,30 @@ BOOST_AUTO_TEST_CASE( firefox_full_reque > > 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"; > >- bool exception = false; > size_t pos = 0; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ websocketpp::lib::error_code ec; >+ >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); >- BOOST_CHECK( pos == 482 ); >+ BOOST_CHECK_EQUAL( pos, 482 ); > BOOST_CHECK( r.ready() == true ); >- BOOST_CHECK( r.get_version() == "HTTP/1.1" ); >- BOOST_CHECK( r.get_method() == "GET" ); >- BOOST_CHECK( r.get_uri() == "/" ); >- BOOST_CHECK( r.get_header("Host") == "localhost:5000" ); >- 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" ); >- BOOST_CHECK( r.get_header("Accept") == "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ); >- BOOST_CHECK( r.get_header("Accept-Language") == "en-us,en;q=0.5" ); >- BOOST_CHECK( r.get_header("Accept-Encoding") == "gzip, deflate" ); >- BOOST_CHECK( r.get_header("Connection") == "keep-alive, Upgrade" ); >- BOOST_CHECK( r.get_header("Sec-WebSocket-Version") == "8" ); >- BOOST_CHECK( r.get_header("Sec-WebSocket-Origin") == "http://zaphoyd.com" ); >- BOOST_CHECK( r.get_header("Sec-WebSocket-Key") == "pFik//FxwFk0riN4ZiPFjQ==" ); >- BOOST_CHECK( r.get_header("Pragma") == "no-cache" ); >- BOOST_CHECK( r.get_header("Cache-Control") == "no-cache" ); >- BOOST_CHECK( r.get_header("Upgrade") == "websocket" ); >+ BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >+ BOOST_CHECK_EQUAL( r.get_method(), "GET" ); >+ BOOST_CHECK_EQUAL( r.get_uri(), "/" ); >+ BOOST_CHECK_EQUAL( r.get_header("Host"), "localhost:5000" ); >+ 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" ); >+ BOOST_CHECK_EQUAL( r.get_header("Accept"), "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ); >+ BOOST_CHECK_EQUAL( r.get_header("Accept-Language"), "en-us,en;q=0.5" ); >+ BOOST_CHECK_EQUAL( r.get_header("Accept-Encoding"), "gzip, deflate" ); >+ BOOST_CHECK_EQUAL( r.get_header("Connection"), "keep-alive, Upgrade" ); >+ BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Version"), "8" ); >+ BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Origin"),"http://zaphoyd.com" ); >+ BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Key"), "pFik//FxwFk0riN4ZiPFjQ==" ); >+ BOOST_CHECK_EQUAL( r.get_header("Pragma"), "no-cache" ); >+ BOOST_CHECK_EQUAL( r.get_header("Cache-Control"), "no-cache" ); >+ BOOST_CHECK_EQUAL( r.get_header("Upgrade"),"websocket" ); > } > > BOOST_AUTO_TEST_CASE( bad_method ) { >@@ -750,15 +691,11 @@ BOOST_AUTO_TEST_CASE( bad_method ) { > > std::string raw = "GE]T / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"; > >- bool exception = false; >- >- try { >- r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >- BOOST_CHECK( exception == true ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::invalid_format)); > } > > BOOST_AUTO_TEST_CASE( bad_header_name ) { >@@ -766,15 +703,11 @@ BOOST_AUTO_TEST_CASE( bad_header_name ) > > std::string raw = "GET / HTTP/1.1\r\nHo]st: www.example.com\r\n\r\n"; > >- bool exception = false; >+ websocketpp::lib::error_code ec; >+ r.consume(raw.c_str(),raw.size(),ec); > >- try { >- r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >- >- BOOST_CHECK( exception == true ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::invalid_header_name)); > } > > BOOST_AUTO_TEST_CASE( old_http_version ) { >@@ -782,16 +715,12 @@ BOOST_AUTO_TEST_CASE( old_http_version ) > > std::string raw = "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 41 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.0" ); >@@ -805,16 +734,12 @@ BOOST_AUTO_TEST_CASE( new_http_version1 > > std::string raw = "GET / HTTP/1.12\r\nHost: www.example.com\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 42 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.12" ); >@@ -828,16 +753,12 @@ BOOST_AUTO_TEST_CASE( new_http_version2 > > std::string raw = "GET / HTTP/12.12\r\nHost: www.example.com\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 43 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/12.12" ); >@@ -870,16 +791,12 @@ BOOST_AUTO_TEST_CASE( header_whitespace1 > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com \r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 43 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -893,16 +810,12 @@ BOOST_AUTO_TEST_CASE( header_whitespace2 > > std::string raw = "GET / HTTP/1.1\r\nHost:www.example.com\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 40 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -916,16 +829,12 @@ BOOST_AUTO_TEST_CASE( header_aggregation > > std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nFoo: bar\r\nFoo: bat\r\n\r\n"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos = r.consume(raw.c_str(),raw.size()); >- } catch (...) { >- exception = true; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 61 ); > BOOST_CHECK( r.ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -939,17 +848,12 @@ BOOST_AUTO_TEST_CASE( wikipedia_example_ > > 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"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 159 ); > BOOST_CHECK( r.headers_ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -967,17 +871,12 @@ BOOST_AUTO_TEST_CASE( wikipedia_example_ > std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n"; > raw += "a"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 159 ); > BOOST_CHECK( r.headers_ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -995,17 +894,12 @@ BOOST_AUTO_TEST_CASE( wikipedia_example_ > std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n"; > raw.append(websocketpp::http::max_header_size,'*'); > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 159 ); > BOOST_CHECK( r.headers_ready() == true ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -1022,17 +916,12 @@ BOOST_AUTO_TEST_CASE( response_with_non_ > > 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"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 158 ); > BOOST_CHECK( r.headers_ready() ); > BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" ); >@@ -1049,17 +938,12 @@ BOOST_AUTO_TEST_CASE( plain_http_respons > > 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>"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(raw.c_str(),raw.size()); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(raw.c_str(),raw.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK( exception == false ); > BOOST_CHECK_EQUAL( pos, 405 ); > BOOST_CHECK( r.headers_ready() == true ); > BOOST_CHECK( r.ready() == true ); >@@ -1084,17 +968,12 @@ BOOST_AUTO_TEST_CASE( parse_istream ) { > > 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>"; > >- bool exception = false; > size_t pos = 0; >+ websocketpp::lib::error_code ec; > >- try { >- pos += r.consume(s); >- } catch (std::exception &e) { >- exception = true; >- std::cout << e.what() << std::endl; >- } >+ pos += r.consume(s,ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- BOOST_CHECK_EQUAL( exception, false ); > BOOST_CHECK_EQUAL( pos, 405 ); > BOOST_CHECK_EQUAL( r.headers_ready(), true ); > BOOST_CHECK_EQUAL( r.ready(), true ); >@@ -1104,23 +983,47 @@ BOOST_AUTO_TEST_CASE( write_request_basi > websocketpp::http::parser::request r; > > std::string raw = "GET / HTTP/1.1\r\n\r\n"; >+ websocketpp::lib::error_code ec; >+ >+ ec = r.set_version("HTTP/1.1"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.set_method("GET"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- r.set_version("HTTP/1.1"); >- r.set_method("GET"); >- r.set_uri("/"); >+ ec = r.set_uri("/"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( r.raw(), raw ); > } > >+BOOST_AUTO_TEST_CASE( write_request_bad_method ) { >+ websocketpp::http::parser::request r; >+ >+ websocketpp::lib::error_code ec; >+ >+ ec = r.set_method("foo bar"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::http::error::make_error_code( >+ websocketpp::http::error::invalid_format)); >+} >+ > BOOST_AUTO_TEST_CASE( write_request_with_header ) { > websocketpp::http::parser::request r; > > std::string raw = "GET / HTTP/1.1\r\nHost: http://example.com\r\n\r\n"; >+ websocketpp::lib::error_code ec; >+ >+ ec = r.set_version("HTTP/1.1"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.set_method("GET"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.set_uri("/"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- r.set_version("HTTP/1.1"); >- r.set_method("GET"); >- r.set_uri("/"); >- r.replace_header("Host","http://example.com"); >+ ec = r.replace_header("Host","http://example.com"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( r.raw(), raw ); > } >@@ -1129,13 +1032,25 @@ BOOST_AUTO_TEST_CASE( write_request_with > websocketpp::http::parser::request r; > > 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¶msXML=string"; >+ websocketpp::lib::error_code ec; >+ >+ ec = r.set_version("HTTP/1.1"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.set_method("POST"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.set_uri("/"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.replace_header("Host","http://example.com"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); >+ >+ ec = r.replace_header("Content-Type","application/x-www-form-urlencoded"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > >- r.set_version("HTTP/1.1"); >- r.set_method("POST"); >- r.set_uri("/"); >- r.replace_header("Host","http://example.com"); >- r.replace_header("Content-Type","application/x-www-form-urlencoded"); >- r.set_body("licenseID=string&content=string¶msXML=string"); >+ ec = r.set_body("licenseID=string&content=string¶msXML=string"); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( r.raw(), raw ); > } >diff '--color=auto' -urNp websocketpp-zaphoyd/test/http/parser_perf.cpp websocketpp-hingobway/test/http/parser_perf.cpp >--- websocketpp-zaphoyd/test/http/parser_perf.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/http/parser_perf.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -31,11 +31,11 @@ > > class scoped_timer { > public: >- scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) { >+ scoped_timer(std::string i) : m_id(i),m_start(timer_ptr::element_type::clock_type::now()) { > std::cout << "Clock " << i << ": "; > } > ~scoped_timer() { >- std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start; >+ std::chrono::nanoseconds time_taken = timer_ptr::element_type::clock_type::now()-m_start; > > //nanoseconds_per_test > >diff '--color=auto' -urNp websocketpp-zaphoyd/test/http/SConscript websocketpp-hingobway/test/http/SConscript >--- websocketpp-zaphoyd/test/http/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/http/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -15,7 +15,7 @@ BOOST_LIBS = boostlibs(['unit_test_frame > objs = env.Object('parser_boost.o', ["parser.cpp"], LIBS = BOOST_LIBS) > prgs = env.Program('test_http_boost', ["parser_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('parser_stl.o', ["parser.cpp"], LIBS = BOOST_LIBS_CPP11) > prgs += env_cpp11.Program('test_http_stl', ["parser_stl.o"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/logger/SConscript websocketpp-hingobway/test/logger/SConscript >--- websocketpp-zaphoyd/test/logger/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/logger/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -15,7 +15,7 @@ BOOST_LIBS = boostlibs(['unit_test_frame > objs = env.Object('logger_basic_boost.o', ["basic.cpp"], LIBS = BOOST_LIBS) > prgs = env.Program('logger_basic_boost', ["logger_basic_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('logger_basic_stl.o', ["basic.cpp"], LIBS = BOOST_LIBS_CPP11) > prgs += env_cpp11.Program('logger_basic_stl', ["logger_basic_stl.o"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/message_buffer/SConscript websocketpp-hingobway/test/message_buffer/SConscript >--- websocketpp-zaphoyd/test/message_buffer/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/message_buffer/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -17,7 +17,7 @@ objs += env.Object('alloc_boost.o', ["al > prgs = env.Program('test_message_boost', ["message_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_alloc_boost', ["alloc_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('message_stl.o', ["message.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('alloc_stl.o', ["alloc.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/hybi00.cpp websocketpp-hingobway/test/processors/hybi00.cpp >--- websocketpp-zaphoyd/test/processors/hybi00.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/hybi00.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -68,7 +68,8 @@ BOOST_AUTO_TEST_CASE( exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","WjN}|M(6"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >@@ -100,7 +101,8 @@ BOOST_AUTO_TEST_CASE( non_get_method ) { > > std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","janelle!"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >@@ -113,7 +115,8 @@ BOOST_AUTO_TEST_CASE( old_http_version ) > > std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","janelle!"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >@@ -126,7 +129,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","janelle!"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >@@ -139,7 +143,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","janelle!"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >@@ -153,7 +158,8 @@ BOOST_AUTO_TEST_CASE( bad_host ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nOrigin: http://example.com\r\nSec-WebSocket-Key1: 3e6b263 4 17 80\r\nSec-WebSocket-Key2: 17 9 G`ZD9 2 2b 7X 3 /r90\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ env.req.consume(handshake.c_str(),handshake.size(),env.ec); >+ BOOST_CHECK_EQUAL(env.ec, websocketpp::lib::error_code()); > env.req.replace_header("Sec-WebSocket-Key3","janelle!"); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/hybi07.cpp websocketpp-hingobway/test/processors/hybi07.cpp >--- websocketpp-zaphoyd/test/processors/hybi07.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/hybi07.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -76,7 +76,8 @@ BOOST_AUTO_TEST_CASE( exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -110,7 +111,8 @@ BOOST_AUTO_TEST_CASE( non_get_method ) { > > std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -128,7 +130,8 @@ BOOST_AUTO_TEST_CASE( old_http_version ) > > std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -146,7 +149,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -164,7 +168,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -182,7 +187,8 @@ BOOST_AUTO_TEST_CASE( bad_host ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/hybi08.cpp websocketpp-hingobway/test/processors/hybi08.cpp >--- websocketpp-zaphoyd/test/processors/hybi08.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/hybi08.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -76,7 +76,8 @@ BOOST_AUTO_TEST_CASE( exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -110,7 +111,8 @@ BOOST_AUTO_TEST_CASE( non_get_method ) { > > std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -128,7 +130,8 @@ BOOST_AUTO_TEST_CASE( old_http_version ) > > std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -146,7 +149,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -164,7 +168,8 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >@@ -183,7 +188,8 @@ BOOST_AUTO_TEST_CASE( bad_host ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == p.get_version()); >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/hybi13.cpp websocketpp-hingobway/test/processors/hybi13.cpp >--- websocketpp-zaphoyd/test/processors/hybi13.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/hybi13.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -122,7 +122,10 @@ BOOST_AUTO_TEST_CASE( exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); > BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version()); >@@ -149,7 +152,10 @@ BOOST_AUTO_TEST_CASE( non_get_method ) { > > std::string handshake = "POST / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); > BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version()); >@@ -161,7 +167,10 @@ BOOST_AUTO_TEST_CASE( old_http_version ) > > std::string handshake = "GET / HTTP/1.0\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(env.req)); > BOOST_CHECK_EQUAL(websocketpp::processor::get_websocket_version(env.req), env.p.get_version()); >@@ -173,7 +182,10 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) ); > BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() ); >@@ -185,7 +197,10 @@ BOOST_AUTO_TEST_CASE( missing_handshake_ > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) ); > BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() ); >@@ -197,7 +212,10 @@ BOOST_AUTO_TEST_CASE( bad_host ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com:70000\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: foo\r\n\r\n"; > >- env.req.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ >+ env.req.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( websocketpp::processor::is_websocket_handshake(env.req) ); > BOOST_CHECK_EQUAL( websocketpp::processor::get_websocket_version(env.req), env.p.get_version() ); >@@ -558,7 +576,10 @@ BOOST_AUTO_TEST_CASE( client_handshake_r > processor_setup env(false); > > std::string res = "HTTP/1.1 404 Not Found\r\n\r\n"; >- env.res.consume(res.data(),res.size()); >+ >+ websocketpp::lib::error_code ec; >+ env.res.consume(res.data(),res.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::invalid_http_status ); > } >@@ -567,7 +588,9 @@ BOOST_AUTO_TEST_CASE( client_handshake_r > processor_setup env(false); > > std::string res = "HTTP/1.1 101 Switching Protocols\r\n\r\n"; >- env.res.consume(res.data(),res.size()); >+ websocketpp::lib::error_code ec; >+ env.res.consume(res.data(),res.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header ); > } >@@ -576,7 +599,9 @@ BOOST_AUTO_TEST_CASE( client_handshake_r > processor_setup env(false); > > std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\n\r\n"; >- env.res.consume(res.data(),res.size()); >+ websocketpp::lib::error_code ec; >+ env.res.consume(res.data(),res.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header ); > } >@@ -585,7 +610,9 @@ BOOST_AUTO_TEST_CASE( client_handshake_r > processor_setup env(false); > > std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\n\r\n"; >- env.res.consume(res.data(),res.size()); >+ websocketpp::lib::error_code ec; >+ env.res.consume(res.data(),res.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_EQUAL( env.p.validate_server_handshake_response(env.req,env.res), websocketpp::processor::error::missing_required_header ); > } >@@ -596,7 +623,9 @@ BOOST_AUTO_TEST_CASE( client_handshake_r > env.req.append_header("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ=="); > > std::string res = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: foo, wEbsOckEt\r\nConnection: bar, UpGrAdE\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"; >- env.res.consume(res.data(),res.size()); >+ websocketpp::lib::error_code ec; >+ env.res.consume(res.data(),res.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( !env.p.validate_server_handshake_response(env.req,env.res) ); > } >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/processor.cpp websocketpp-hingobway/test/processors/processor.cpp >--- websocketpp-zaphoyd/test/processors/processor.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/processor.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -39,7 +39,9 @@ BOOST_AUTO_TEST_CASE( exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > } >@@ -49,7 +51,9 @@ BOOST_AUTO_TEST_CASE( non_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(!websocketpp::processor::is_websocket_handshake(r)); > } >@@ -59,7 +63,9 @@ BOOST_AUTO_TEST_CASE( ci_exact_match ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: UpGrAde\r\nUpgrade: WebSocket\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > } >@@ -69,7 +75,9 @@ BOOST_AUTO_TEST_CASE( non_exact_match1 ) > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade,foo\r\nUpgrade: websocket,foo\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > } >@@ -79,7 +87,9 @@ BOOST_AUTO_TEST_CASE( non_exact_match2 ) > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: keep-alive,Upgrade,foo\r\nUpgrade: foo,websocket,bar\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::is_websocket_handshake(r)); > } >@@ -89,7 +99,9 @@ BOOST_AUTO_TEST_CASE( version_blank ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 0); > } >@@ -99,7 +111,9 @@ BOOST_AUTO_TEST_CASE( version_7 ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 7\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 7); > } >@@ -109,7 +123,9 @@ BOOST_AUTO_TEST_CASE( version_8 ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 8\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 8); > } >@@ -119,7 +135,9 @@ BOOST_AUTO_TEST_CASE( version_13 ) { > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == 13); > } >@@ -129,7 +147,9 @@ BOOST_AUTO_TEST_CASE( version_non_numeri > > std::string handshake = "GET / HTTP/1.1\r\nHost: www.example.com\r\nUpgrade: websocket\r\nSec-WebSocket-Version: abc\r\n\r\n"; > >- r.consume(handshake.c_str(),handshake.size()); >+ websocketpp::lib::error_code ec; >+ r.consume(handshake.c_str(),handshake.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK(websocketpp::processor::get_websocket_version(r) == -1); > } >\ Nincs új sor a fájl végén >diff '--color=auto' -urNp websocketpp-zaphoyd/test/processors/SConscript websocketpp-hingobway/test/processors/SConscript >--- websocketpp-zaphoyd/test/processors/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/processors/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -26,7 +26,7 @@ prgs += env.Program('test_hybi07_boost', > prgs += env.Program('test_hybi00_boost', ["test_hybi00_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_extension_permessage_compress_boost', ["test_extension_permessage_compress_boost.o"], LIBS = BOOST_LIBS + ['z']) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] + ['z'] > # no C++11 features are used in processor so there are no C++11 versions of > # these tests. >diff '--color=auto' -urNp websocketpp-zaphoyd/test/random/SConscript websocketpp-hingobway/test/random/SConscript >--- websocketpp-zaphoyd/test/random/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/random/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -17,7 +17,7 @@ objs += env.Object('random_device_boost. > prgs = env.Program('test_random_none_boost', ["random_none_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_random_device_boost', ["random_device_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('random_none_stl.o', ["none.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('random_device_stl.o', ["random_device.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/roles/client.cpp websocketpp-hingobway/test/roles/client.cpp >--- websocketpp-zaphoyd/test/roles/client.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/roles/client.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -104,11 +104,13 @@ BOOST_AUTO_TEST_CASE( connect_con ) { > c.register_ostream(&out); > > connection_ptr con = c.get_connection("ws://localhost/", ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > c.connect(con); > > o = out.str(); > websocketpp::http::parser::request r; >- r.consume(o.data(),o.size()); >+ r.consume(o.data(),o.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( r.ready() ); > BOOST_CHECK_EQUAL( r.get_method(), "GET"); >@@ -174,10 +176,11 @@ BOOST_AUTO_TEST_CASE( add_subprotocols ) > c.register_ostream(&out); > > connection_ptr con = c.get_connection("ws://localhost/", ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > BOOST_CHECK( con ); > > con->add_subprotocol("foo",ec); >- BOOST_CHECK( !ec ); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK_NO_THROW( con->add_subprotocol("bar") ); > >@@ -185,7 +188,8 @@ BOOST_AUTO_TEST_CASE( add_subprotocols ) > > o = out.str(); > websocketpp::http::parser::request r; >- r.consume(o.data(),o.size()); >+ r.consume(o.data(),o.size(),ec); >+ BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code()); > > BOOST_CHECK( r.ready() ); > BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "foo, bar"); >diff '--color=auto' -urNp websocketpp-zaphoyd/test/roles/SConscript websocketpp-hingobway/test/roles/SConscript >--- websocketpp-zaphoyd/test/roles/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/roles/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -17,7 +17,7 @@ objs += env.Object('server_boost.o', ["s > prgs = env.Program('test_client_boost', ["client_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_server_boost', ["server_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('client_stl.o', ["client.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('server_stl.o', ["server.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/roles/server.cpp websocketpp-hingobway/test/roles/server.cpp >--- websocketpp-zaphoyd/test/roles/server.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/roles/server.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -35,6 +35,9 @@ > #include <websocketpp/config/core.hpp> > #include <websocketpp/server.hpp> > >+#include <websocketpp/transport/base/endpoint.hpp> >+#include <websocketpp/transport/stub/endpoint.hpp> >+ > typedef websocketpp::server<websocketpp::config::core> server; > typedef websocketpp::config::core::message_type::ptr message_ptr; > >@@ -71,7 +74,8 @@ std::string run_server_test(server& s, s > s.clear_access_channels(websocketpp::log::alevel::all); > s.clear_error_channels(websocketpp::log::elevel::all); > >- con = s.get_connection(); >+ websocketpp::lib::error_code ec; >+ con = s.get_connection(ec); > con->start(); > > std::stringstream channel; >@@ -236,6 +240,254 @@ BOOST_AUTO_TEST_CASE( accept_subprotocol > BOOST_CHECK_EQUAL(open, "bar"); > } > >+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) { >+ *rec = ec; >+ *rtec = tec; >+} >+ >+namespace test_transport { >+ >+template <typename config> >+struct endpoint : websocketpp::transport::stub::endpoint<config> { >+ void config_test(int accept_cons, bool init_connections) { >+ m_accept_cons = accept_cons; >+ m_init_connections = init_connections; >+ } >+ >+ bool is_listening() const { >+ if (m_accept_cons > 0) { >+ return true; >+ } else { >+ return false; >+ } >+ } >+ >+ typedef typename websocketpp::transport::stub::endpoint<config>::transport_con_ptr transport_con_ptr; >+ >+ websocketpp::lib::error_code init(transport_con_ptr tcon) { >+ if (m_init_connections) { >+ return websocketpp::lib::error_code(); >+ } else { >+ return websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented); >+ } >+ } >+ >+ void async_accept(transport_con_ptr tcon, websocketpp::transport::accept_handler cb, websocketpp::lib::error_code & ec) { >+ m_accept_cons--; >+ >+ ec = websocketpp::lib::error_code(); >+ cb(ec); >+ } >+ >+ int m_accept_cons; >+ bool m_init_connections; >+}; >+ >+} // namespace test_transport >+ >+struct test_config : public websocketpp::config::core { >+ typedef test_transport::endpoint<websocketpp::config::core::transport_config> transport_type; >+}; >+ >+void handle_fail(websocketpp::server<test_config> * s, websocketpp::lib::error_code * rec, websocketpp::connection_hdl hdl) { >+ websocketpp::server<test_config>::connection_ptr con = s->get_con_from_hdl(hdl); >+ >+ *rec = con->get_ec(); >+} >+ >+void handle_fail_count(websocketpp::server<test_config> * s, websocketpp::lib::error_code rec, int * count, websocketpp::connection_hdl hdl) { >+ websocketpp::server<test_config>::connection_ptr con = s->get_con_from_hdl(hdl); >+ >+ if (con->get_ec() == rec) { >+ (*count)++; >+ } >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_not_listening ) { >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is not listening or generating connections >+ s.config_test(0, false); >+ >+ // attempt to start accepting connections >+ s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2)); >+ >+ // confirm the right library and transport error codes >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error)); >+ BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening)); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_con_creation_failed ) { >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that is listening but not generating connections >+ s.config_test(1,false); >+ >+ // attempt to start accepting connections >+ s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2)); >+ >+ // confirm the right library and transport error codes >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed)); >+ BOOST_CHECK_EQUAL(rtec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented)); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_con_1 ) { >+ // this case tests the full successful start accept loop up to connection initialization. >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rsec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(1,true); >+ >+ // we are expecting to fail due to connection initiation being "not implemented" >+ s.set_fail_handler(bind(&handle_fail,&s,&rsec,::_1)); >+ >+ // attempt to start accepting connections >+ s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2)); >+ >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error)); >+ BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening)); >+ BOOST_CHECK_EQUAL(rsec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented)); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_con_2 ) { >+ // this case tests the full successful start accept loop up to connection initialization >+ // for two full accept cycles before cancelling listening. >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rtec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(2,true); >+ >+ websocketpp::lib::error_code xec = websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented); >+ int count = 0; >+ >+ // we are expecting to fail due to connection initiation being "not implemented" >+ // this handler will count the number of times it is called with "not implemented" >+ s.set_fail_handler(bind(&handle_fail_count,&s,xec,&count,::_1)); >+ >+ // attempt to start accepting connections >+ s.start_accept(bind(&handle_start_accept,&rec,&rtec,::_1,::_2)); >+ >+ // confirm that the final return was as expected >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::transport_error)); >+ BOOST_CHECK_EQUAL(rtec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening)); >+ // confirm that we saw two init attempts >+ BOOST_CHECK_EQUAL(count, 2); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_not_listening_deprecated ) { >+ // test deprecated start_accept(ec) failure path 1 >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(0,false); >+ >+ // attempt to start accepting connections >+ s.start_accept(rec); >+ >+ // confirm that the final return was as expected >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::async_accept_not_listening)); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_con_creation_failed_deprecated ) { >+ // test deprecated start_accept(ec) failure path 2 >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(1,false); >+ >+ // attempt to start accepting connections >+ s.start_accept(rec); >+ >+ // confirm that the final return was as expected >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed)); >+} >+ >+BOOST_AUTO_TEST_CASE( start_accept_deprecated ) { >+ // this case tests the full successful start accept loop up to connection initialization. >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ websocketpp::lib::error_code rsec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(1,true); >+ >+ // we are expecting to fail due to connection initiation being "not implemented" >+ s.set_fail_handler(bind(&handle_fail,&s,&rsec,::_1)); >+ >+ // attempt to start accepting connections >+ s.start_accept(rec); >+ >+ BOOST_CHECK_EQUAL(rec, websocketpp::lib::error_code()); >+ BOOST_CHECK_EQUAL(rsec, websocketpp::transport::stub::error::make_error_code(websocketpp::transport::stub::error::not_implemented)); >+ // we can't automated test how/why the accept loop ends because this version has >+ // no method for capturing that output other than the error log >+} >+ >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+BOOST_AUTO_TEST_CASE( start_accept_exception_con_creation_failed_deprecated ) { >+ // this case tests two things: >+ // 1. the existance of the deprecated start_accept() [with exceptions] function >+ // 2. Error handling of the deprecated start_accept() in the case that the transport >+ // cannot create new connections. >+ >+ websocketpp::lib::error_code rec = websocketpp::error::make_error_code(websocketpp::error::test); >+ >+ websocketpp::server<test_config> s; >+ >+ // config the test endpoint to report that it is listening for exactly >+ // one connection and generating connections >+ s.config_test(1,false); >+ >+ // attempt to start accepting connections >+ try { >+ s.start_accept(); >+ } catch (websocketpp::exception const & e) { >+ rec = e.code(); >+ } >+ >+ // confirm that the final return was as expected >+ BOOST_CHECK_EQUAL(rec, websocketpp::error::make_error_code(websocketpp::error::con_creation_failed)); >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+BOOST_AUTO_TEST_CASE( get_connection_deprecated ) { >+ // exercise the deprecated get_connection function to help avoid regressions. >+ // this test should be removed if the deprecated function is removed. >+ >+ server s; >+ server::connection_ptr con = s.get_connection(); >+ >+ BOOST_CHECK(con); >+} >+ > /*BOOST_AUTO_TEST_CASE( user_reject_origin ) { > std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n"; > std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n"; >diff '--color=auto' -urNp websocketpp-zaphoyd/test/transport/asio/SConscript websocketpp-hingobway/test/transport/asio/SConscript >--- websocketpp-zaphoyd/test/transport/asio/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/transport/asio/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -20,7 +20,7 @@ prgs = env.Program('test_base_boost', [" > prgs += env.Program('test_timers_boost', ["timers_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_security_boost', ["security_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > objs += env_cpp11.Object('base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('timers_stl.o', ["timers.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/transport/asio/timers.cpp websocketpp-hingobway/test/transport/asio/timers.cpp >--- websocketpp-zaphoyd/test/transport/asio/timers.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/transport/asio/timers.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -54,9 +54,9 @@ void run_dummy_server(int port) { > using boost::asio::ip::tcp; > > try { >- boost::asio::io_service io_service; >- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); >- tcp::socket socket(io_service); >+ boost::asio::io_context io_context; >+ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); >+ tcp::socket socket(io_context); > > acceptor.accept(socket); > for (;;) { >@@ -79,8 +79,9 @@ void run_dummy_server(int port) { > > // Wait for the specified time period then fail the test > void run_test_timer(long value) { >- boost::asio::io_service ios; >- boost::asio::deadline_timer t(ios,boost::posix_time::milliseconds(value)); >+ boost::asio::io_context ctx; >+ boost::asio::system_timer t(ctx); >+ t.expires_after(std::chrono::milliseconds(value)); > boost::system::error_code ec; > t.wait(ec); > BOOST_FAIL( "Test timed out" ); >@@ -106,9 +107,9 @@ struct config { > }; > > // Mock context that does no validation >-typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr; >+typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr; > context_ptr on_tls_init(websocketpp::connection_hdl) { >- return context_ptr(new boost::asio::ssl::context(boost::asio::ssl::context::sslv23)); >+ return context_ptr(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::sslv23)); > } > > // Mock connection >diff '--color=auto' -urNp websocketpp-zaphoyd/test/transport/integration.cpp websocketpp-hingobway/test/transport/integration.cpp >--- websocketpp-zaphoyd/test/transport/integration.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/transport/integration.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -38,6 +38,8 @@ > #include <websocketpp/server.hpp> > #include <websocketpp/client.hpp> > >+#include "boost/date_time/posix_time/posix_time.hpp" >+ > struct config : public websocketpp::config::asio_client { > typedef config type; > typedef websocketpp::config::asio base; >@@ -218,19 +220,19 @@ void run_time_limited_client(client & c, > } > > void run_dummy_server(int port) { >- using boost::asio::ip::tcp; >+ using websocketpp::lib::asio::ip::tcp; > > try { >- boost::asio::io_service io_service; >- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); >- tcp::socket socket(io_service); >+ websocketpp::lib::asio::io_context io_context; >+ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); >+ tcp::socket socket(io_context); > > acceptor.accept(socket); > for (;;) { > char data[512]; >- boost::system::error_code ec; >- socket.read_some(boost::asio::buffer(data), ec); >- if (ec == boost::asio::error::eof) { >+ websocketpp::lib::asio::error_code ec; >+ socket.read_some(websocketpp::lib::asio::buffer(data), ec); >+ if (ec == websocketpp::lib::asio::error::eof) { > break; > } else if (ec) { > // other error >@@ -239,27 +241,26 @@ void run_dummy_server(int port) { > } > } catch (std::exception & e) { > std::cout << e.what() << std::endl; >- } catch (boost::system::error_code & ec) { >+ } catch (websocketpp::lib::asio::error_code & ec) { > std::cout << ec.message() << std::endl; > } > } > > void run_dummy_client(std::string port) { >- using boost::asio::ip::tcp; >+ using websocketpp::lib::asio::ip::tcp; > > try { >- boost::asio::io_service io_service; >- tcp::resolver resolver(io_service); >- tcp::resolver::query query("localhost", port); >- tcp::resolver::iterator iterator = resolver.resolve(query); >- tcp::socket socket(io_service); >+ websocketpp::lib::asio::io_context io_context; >+ tcp::resolver resolver(io_context); >+ tcp::resolver::results_type results = resolver.resolve("localhost", port); >+ tcp::socket socket(io_context); > >- boost::asio::connect(socket, iterator); >+ websocketpp::lib::asio::connect(socket, results); > for (;;) { > char data[512]; >- boost::system::error_code ec; >- socket.read_some(boost::asio::buffer(data), ec); >- if (ec == boost::asio::error::eof) { >+ websocketpp::lib::asio::error_code ec; >+ socket.read_some(websocketpp::lib::asio::buffer(data), ec); >+ if (ec == websocketpp::lib::asio::error::eof) { > break; > } else if (ec) { > // other error >@@ -268,7 +269,7 @@ void run_dummy_client(std::string port) > } > } catch (std::exception & e) { > std::cout << e.what() << std::endl; >- } catch (boost::system::error_code & ec) { >+ } catch (websocketpp::lib::asio::error_code & ec) { > std::cout << ec.message() << std::endl; > } > } >@@ -354,33 +355,34 @@ void close(T * e, websocketpp::connectio > e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,""); > } > >-class test_deadline_timer >+class test_system_timer > { > public: >- test_deadline_timer(int seconds) >- : m_timer(m_io_service, boost::posix_time::seconds(seconds)) >+ test_system_timer(int seconds) >+ : m_timer(m_io_context) > { >- m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1)); >- std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run; >- m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_service)); >+ m_timer.expires_after(std::chrono::seconds(seconds)); >+ m_timer.async_wait(bind(&test_system_timer::expired, this, ::_1)); >+ std::size_t (websocketpp::lib::asio::io_context::*run)() = &websocketpp::lib::asio::io_context::run; >+ m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context)); > } >- ~test_deadline_timer() >+ ~test_system_timer() > { > m_timer.cancel(); > m_timer_thread.join(); > } > > private: >- void expired(const boost::system::error_code & ec) >+ void expired(const websocketpp::lib::asio::error_code & ec) > { >- if (ec == boost::asio::error::operation_aborted) >+ if (ec == websocketpp::lib::asio::error::operation_aborted) > return; > BOOST_CHECK(!ec); > BOOST_FAIL("Test timed out"); > } > >- boost::asio::io_service m_io_service; >- boost::asio::deadline_timer m_timer; >+ websocketpp::lib::asio::io_context m_io_context; >+ websocketpp::lib::asio::system_timer m_timer; > websocketpp::lib::thread m_timer_thread; > }; > >@@ -426,7 +428,7 @@ BOOST_AUTO_TEST_CASE( pong_timeout ) { > websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); > sleep(1); // give the server thread some time to start > >- test_deadline_timer deadline(10); >+ test_system_timer deadline(10); > > run_client(c, "http://localhost:9005",false); > >@@ -447,7 +449,7 @@ BOOST_AUTO_TEST_CASE( client_open_handsh > > sleep(1); // give the server thread some time to start > >- test_deadline_timer deadline(10); >+ test_system_timer deadline(10); > > run_client(c, "http://localhost:9005"); > } >@@ -463,7 +465,7 @@ BOOST_AUTO_TEST_CASE( server_open_handsh > > websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); > >- test_deadline_timer deadline(10); >+ test_system_timer deadline(10); > > sleep(1); // give the server thread some time to start > >@@ -488,7 +490,7 @@ BOOST_AUTO_TEST_CASE( client_self_initia > > websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); > >- test_deadline_timer deadline(10); >+ test_system_timer deadline(10); > > sleep(1); // give the server thread some time to start > >@@ -521,7 +523,7 @@ BOOST_AUTO_TEST_CASE( server_self_initia > c.set_open_handler(bind(&delay,::_1,1)); > > websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); >- test_deadline_timer deadline(10); >+ test_system_timer deadline(10); > > sleep(1); // give the server thread some time to start > >@@ -533,7 +535,7 @@ BOOST_AUTO_TEST_CASE( server_self_initia > BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) { > client c; > >- test_deadline_timer deadline(3); >+ test_system_timer deadline(3); > > websocketpp::lib::error_code ec; > c.init_asio(ec); >@@ -541,7 +543,7 @@ BOOST_AUTO_TEST_CASE( client_runs_out_of > > c.run(); > >- // This test checks that an io_service with no work ends immediately. >+ // This test checks that an io_context with no work ends immediately. > BOOST_CHECK(true); > } > >@@ -599,7 +601,7 @@ BOOST_AUTO_TEST_CASE( stop_listening ) { > c.set_open_handler(bind(&close<client>,&c,::_1)); > > websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); >- test_deadline_timer deadline(5); >+ test_system_timer deadline(5); > > sleep(1); // give the server thread some time to start > >diff '--color=auto' -urNp websocketpp-zaphoyd/test/transport/iostream/SConscript websocketpp-hingobway/test/transport/iostream/SConscript >--- websocketpp-zaphoyd/test/transport/iostream/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/transport/iostream/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -19,7 +19,7 @@ prgs = env.Program('test_iostream_base_b > prgs += env.Program('test_iostream_connection_boost', ["iostream_connection_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_iostream_endpoint_boost', ["iostream_endpoint_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('iostream_base_stl.o', ["base.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('iostream_connection_stl.o', ["connection.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/transport/SConscript websocketpp-hingobway/test/transport/SConscript >--- websocketpp-zaphoyd/test/transport/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/transport/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -16,7 +16,7 @@ BOOST_LIBS = boostlibs(['unit_test_frame > objs = env.Object('boost_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS) > prgs = env.Program('test_boost_integration', ["boost_integration.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework','system'],env_cpp11) + [platform_libs] + [polyfill_libs] + [tls_libs] > objs += env_cpp11.Object('stl_integration.o', ["integration.cpp"], LIBS = BOOST_LIBS_CPP11) > prgs += env_cpp11.Program('test_stl_integration', ["stl_integration.o"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/utility/SConscript websocketpp-hingobway/test/utility/SConscript >--- websocketpp-zaphoyd/test/utility/SConscript 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/utility/SConscript 2025-03-10 21:33:06.000000000 +0100 >@@ -24,7 +24,7 @@ prgs += env.Program('test_close_boost', > prgs += env.Program('test_sha1_boost', ["sha1_boost.o"], LIBS = BOOST_LIBS) > prgs += env.Program('test_error_boost', ["error_boost.o"], LIBS = BOOST_LIBS) > >-if env_cpp11.has_key('WSPP_CPP11_ENABLED'): >+if 'WSPP_CPP11_ENABLED' in env_cpp11: > BOOST_LIBS_CPP11 = boostlibs(['unit_test_framework'],env_cpp11) + [platform_libs] + [polyfill_libs] > objs += env_cpp11.Object('utilities_stl.o', ["utilities.cpp"], LIBS = BOOST_LIBS_CPP11) > objs += env_cpp11.Object('uri_stl.o', ["uri.cpp"], LIBS = BOOST_LIBS_CPP11) >diff '--color=auto' -urNp websocketpp-zaphoyd/test/utility/uri.cpp websocketpp-hingobway/test/utility/uri.cpp >--- websocketpp-zaphoyd/test/utility/uri.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/utility/uri.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -33,6 +33,9 @@ > > #include <websocketpp/uri.hpp> > >+// Many URI tests are inspired by the comprehensive test suite from >+// the uriparser project (https://uriparser.github.io) >+ > // Test a regular valid ws URI > BOOST_AUTO_TEST_CASE( uri_valid ) { > websocketpp::uri uri("ws://localhost:9000/chat"); >@@ -46,6 +49,137 @@ BOOST_AUTO_TEST_CASE( uri_valid ) { > BOOST_CHECK_EQUAL( uri.get_query(), "" ); > } > >+BOOST_AUTO_TEST_CASE( uri_valid_ipv4 ) { >+ //BOOST_CHECK( !websocketpp::uri("ws://01.0.0.0").get_valid() ); >+ //BOOST_CHECK( !websocketpp::uri("ws://001.0.0.0").get_valid() ); >+ >+ >+} >+ >+BOOST_AUTO_TEST_CASE( uri_valid_ipv6 ) { >+ // Quad length >+ BOOST_CHECK( websocketpp::uri("ws://[abcd::]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[abcd::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[abcd::12]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[abcd::123]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[abcd::1234]").get_valid() ); >+ >+ // Full length >+ BOOST_CHECK( websocketpp::uri("ws://[2001:0db8:0100:f101:0210:a4ff:fee3:9566]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[2001:0DB8:0100:F101:0210:A4FF:FEE3:9566]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[2001:db8:100:f101:210:a4ff:fee3:9566]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[2001:0db8:100:f101:0:0:0:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6:255.255.255.255]").get_valid() ); >+ >+ // Legal IPv4 >+ BOOST_CHECK( websocketpp::uri("ws://[::1.2.3.4]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[3:4::5:1.2.3.4]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[::ffff:1.2.3.4]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[::0.0.0.0]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[::255.255.255.255]").get_valid() ); >+ >+ // Zipper position >+ BOOST_CHECK( websocketpp::uri("ws://[::1:2:3:4:5:6:7]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1::1:2:3:4:5:6]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2::1:2:3:4:5]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3::1:2:3:4]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4::1:2:3]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5::1:2]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:2:3:4:5:6:7::]").get_valid() ); >+ >+ // Zipper length >+ BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1:1:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:1:1::1:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:1::1:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1:1::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[1::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[::]").get_valid() ); >+ >+ // Misc >+ BOOST_CHECK( websocketpp::uri("ws://[21ff:abcd::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[2001:db8:100:f101::1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[a:b:c::12:1]").get_valid() ); >+ BOOST_CHECK( websocketpp::uri("ws://[a:b::0:1:2:3]").get_valid() ); >+} >+ >+BOOST_AUTO_TEST_CASE( uri_invalid_ipv6 ) { >+ // 5 char quad >+ BOOST_CHECK( !websocketpp::uri("ws://[::12345]").get_valid() ); >+ >+ // Two zippers >+ BOOST_CHECK( !websocketpp::uri("ws://[abcd::abcd::abcd]").get_valid() ); >+ >+ // Triple-colon zipper >+ BOOST_CHECK( !websocketpp::uri("ws://[:::1234]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[1234:::1234:1234]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[1234:1234:::1234]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[1234:::]").get_valid() ); >+ >+ // No quads, just IPv4. These are valid uris, just shouldn't parse as IPv6 literal >+ websocketpp::uri ipv4_1("ws://1.2.3.4"); >+ BOOST_CHECK( ipv4_1.get_valid() ); >+ BOOST_CHECK( !ipv4_1.is_ipv6_literal() ); >+ >+ // Five quads >+ BOOST_CHECK( !websocketpp::uri("ws://[0000:0000:0000:0000:0000:1.2.3.4]").get_valid() ); >+ >+ // Seven quads >+ BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0:]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[0:0:0:0:0:0:0:1.2.3.4]").get_valid() ); >+ >+ // Nine quads (or more) >+ BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4:5:6:7:8:9]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::2:3:4:5:6:7:8:9]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4::6:7:8:9]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[1:2:3:4:5:6:7:8::]").get_valid() ); >+ >+ // Invalid IPv4 part >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:001.02.03.004]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.1111]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.256]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:311.2.3.4]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3:4]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3a.4]").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::ffff:1.2.3.4:123]").get_valid() ); >+ >+ // Nonhex >+ BOOST_CHECK( !websocketpp::uri("ws://[g:0:0:0:0:0:0]").get_valid() ); >+ >+ // missing end bracket >+ BOOST_CHECK( !websocketpp::uri("ws://[::1").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::1:80").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::1/foo").get_valid() ); >+ BOOST_CHECK( !websocketpp::uri("ws://[::1#foo").get_valid() ); >+} >+ >+BOOST_AUTO_TEST_CASE( uri_valid_no_slash ) { >+ websocketpp::uri uri("ws://localhost"); >+ >+ BOOST_CHECK( uri.get_valid() ); >+ BOOST_CHECK( !uri.get_secure() ); >+ BOOST_CHECK_EQUAL( uri.get_scheme(), "ws"); >+ BOOST_CHECK_EQUAL( uri.get_host(), "localhost"); >+ BOOST_CHECK_EQUAL( uri.get_port(), 80 ); >+ BOOST_CHECK_EQUAL( uri.get_resource(), "/" ); >+} >+ >+BOOST_AUTO_TEST_CASE( uri_valid_no_slash_with_fragment ) { >+ websocketpp::uri uri("ws://localhost#foo"); >+ >+ BOOST_CHECK( uri.get_valid() ); >+ BOOST_CHECK( !uri.get_secure() ); >+ BOOST_CHECK_EQUAL( uri.get_scheme(), "ws"); >+ BOOST_CHECK_EQUAL( uri.get_host(), "localhost"); >+ BOOST_CHECK_EQUAL( uri.get_port(), 80 ); >+ BOOST_CHECK_EQUAL( uri.get_resource(), "#foo" ); >+} >+ > // Test a regular valid ws URI > BOOST_AUTO_TEST_CASE( uri_valid_no_port_unsecure ) { > websocketpp::uri uri("ws://localhost/chat"); >@@ -92,6 +226,24 @@ BOOST_AUTO_TEST_CASE( uri_valid_ipv6_lit > BOOST_CHECK_EQUAL( uri.get_host(), "::1"); > BOOST_CHECK_EQUAL( uri.get_port(), 9000 ); > BOOST_CHECK_EQUAL( uri.get_resource(), "/chat" ); >+ BOOST_CHECK_EQUAL( uri.str(), "wss://[::1]:9000/chat" ); >+ BOOST_CHECK_EQUAL( uri.get_host_port(), "[::1]:9000" ); >+ BOOST_CHECK_EQUAL( uri.get_authority(), "[::1]:9000" ); >+} >+ >+// Valid URI IPv6 Literal with default port >+BOOST_AUTO_TEST_CASE( uri_valid_ipv6_literal_default_port ) { >+ websocketpp::uri uri("wss://[::1]/chat"); >+ >+ BOOST_CHECK( uri.get_valid() ); >+ BOOST_CHECK( uri.get_secure() ); >+ BOOST_CHECK_EQUAL( uri.get_scheme(), "wss"); >+ BOOST_CHECK_EQUAL( uri.get_host(), "::1"); >+ BOOST_CHECK_EQUAL( uri.get_port(), 443 ); >+ BOOST_CHECK_EQUAL( uri.get_resource(), "/chat" ); >+ BOOST_CHECK_EQUAL( uri.str(), "wss://[::1]/chat" ); >+ BOOST_CHECK_EQUAL( uri.get_host_port(), "::1" ); >+ BOOST_CHECK_EQUAL( uri.get_authority(), "[::1]:443" ); > } > > // Valid URI with more complicated host >@@ -192,6 +344,13 @@ BOOST_AUTO_TEST_CASE( uri_invalid_bad_v6 > BOOST_CHECK( !uri.get_valid() ); > } > >+// Invalid URI with stray [] >+BOOST_AUTO_TEST_CASE( uri_invalid_free_delim ) { >+ websocketpp::uri uri("wss://localhos[]t/chat"); >+ >+ BOOST_CHECK( !uri.get_valid() ); >+} >+ > // Valid URI complicated resource path with query > BOOST_AUTO_TEST_CASE( uri_valid_4 ) { > websocketpp::uri uri("wss://localhost:9000/chat/foo/bar?foo=bar"); >@@ -236,11 +395,4 @@ BOOST_AUTO_TEST_CASE( uri_invalid_no_sch > BOOST_CHECK( !uri.get_valid() ); > } > >-// Invalid IPv6 literal >-/*BOOST_AUTO_TEST_CASE( uri_invalid_v6_nonhex ) { >- websocketpp::uri uri("wss://[g::1]:9000/"); >- >- BOOST_CHECK( uri.get_valid() == false ); >-}*/ >- >-// TODO: tests for the other two constructors >+// TODO: tests for the other constructors, especially with IP literals >diff '--color=auto' -urNp websocketpp-zaphoyd/test/utility/utilities.cpp websocketpp-hingobway/test/utility/utilities.cpp >--- websocketpp-zaphoyd/test/utility/utilities.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/test/utility/utilities.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -56,10 +56,10 @@ BOOST_AUTO_TEST_CASE( substr_not_found ) > BOOST_CHECK(websocketpp::utility::ci_find_substr(haystack,needle) == haystack.end()); > } > >-BOOST_AUTO_TEST_CASE( to_lower ) { >- std::string in = "AbCd"; >+BOOST_AUTO_TEST_CASE( to_hex ) { >+ std::string in = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"; > >- BOOST_CHECK_EQUAL(websocketpp::utility::to_lower(in), "abcd"); >+ BOOST_CHECK_EQUAL(websocketpp::utility::to_hex(in), "01 23 45 67 89 AB CD EF "); > } > > BOOST_AUTO_TEST_CASE( string_replace_all ) { >diff '--color=auto' -urNp websocketpp-zaphoyd/.travis.yml websocketpp-hingobway/.travis.yml >--- websocketpp-zaphoyd/.travis.yml 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/.travis.yml 2025-03-10 21:33:06.000000000 +0100 >@@ -1,18 +1,27 @@ > language: cpp >+dist: bionic > compiler: > - gcc >-before_install: >- #- sudo apt-get install libboost-chrono1.48-dev libboost-regex1.48-dev libboost-system1.48-dev libboost-thread1.48-dev libboost-test1.48-dev libboost-random1.48-dev -y >- - sudo add-apt-repository -y ppa:boost-latest/ppa && sudo apt-get update -q && sudo apt-get install -y libboost-chrono1.55-dev libboost-random1.55-dev libboost-regex1.55-dev libboost-system1.55-dev libboost-thread1.55-dev libboost-test1.55-dev >+addons: >+ apt: >+ packages: >+ - libboost-random-dev >+ - libboost-system-dev >+ - libboost-test-dev >+ - libboost-thread-dev >+ - zlib1g-dev >+ - cmake > env: > global: > - BOOST_INCLUDES=/usr/include > - BOOST_LIBS=/usr/lib/x86_64-linux-gnu >-script: scons -j 2 && scons test >+script: cmake -DBUILD_EXAMPLES=1 -DBUILD_TESTS=1 . && make -j 2 && make test > branches: >- only: >- - master >- - develop >+ except: >+ - 0.2.x >+ - experimental >+ - legacy >+ > notifications: > recipients: > - travis@zaphoyd.com >diff '--color=auto' -urNp websocketpp-zaphoyd/tutorials/utility_server/step1.cpp websocketpp-hingobway/tutorials/utility_server/step1.cpp >--- websocketpp-zaphoyd/tutorials/utility_server/step1.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/tutorials/utility_server/step1.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -57,7 +57,7 @@ public: > // Queues a connection accept operation > m_endpoint.start_accept(); > >- // Start the Asio io_service run loop >+ // Start the Asio io_context run loop > m_endpoint.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/tutorials/utility_server/step2.cpp websocketpp-hingobway/tutorials/utility_server/step2.cpp >--- websocketpp-zaphoyd/tutorials/utility_server/step2.cpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/tutorials/utility_server/step2.cpp 2025-03-10 21:33:06.000000000 +0100 >@@ -68,7 +68,7 @@ public: > // Queues a connection accept operation > m_endpoint.start_accept(); > >- // Start the Asio io_service run loop >+ // Start the Asio io_context run loop > m_endpoint.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/tutorials/utility_server/utility_server.md websocketpp-hingobway/tutorials/utility_server/utility_server.md >--- websocketpp-zaphoyd/tutorials/utility_server/utility_server.md 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/tutorials/utility_server/utility_server.md 2025-03-10 21:33:06.000000000 +0100 >@@ -56,7 +56,7 @@ m_endpoint.set_access_channels(websocket > > 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. > >-> **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?] >+> **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?] > > ~~~{.cpp} > m_endpoint.init_asio(); >@@ -64,7 +64,7 @@ m_endpoint.init_asio(); > > #### `utility_server::run` method > >-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. >+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. > > ~~~{.cpp} > // Listen on port 9002 >@@ -73,7 +73,7 @@ m_endpoint.listen(9002); > // Queues a connection accept operation > m_endpoint.start_accept(); > >-// Start the Asio io_service run loop >+// Start the Asio io_context run loop > m_endpoint.run(); > ~~~ > >@@ -123,7 +123,7 @@ public: > // Queues a connection accept operation > m_endpoint.start_accept(); > >- // Start the Asio io_service run loop >+ // Start the Asio io_context run loop > m_endpoint.run(); > } > private: >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/common/asio.hpp websocketpp-hingobway/websocketpp/common/asio.hpp >--- websocketpp-zaphoyd/websocketpp/common/asio.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/common/asio.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -51,7 +51,7 @@ > > #include <asio.hpp> > #include <asio/steady_timer.hpp> >- #include <websocketpp/common/chrono.hpp> >+ #include <websocketpp/common/chrono.hpp> > #else > #include <boost/version.hpp> > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/common/cpp11.hpp websocketpp-hingobway/websocketpp/common/cpp11.hpp >--- websocketpp-zaphoyd/websocketpp/common/cpp11.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/common/cpp11.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -88,9 +88,11 @@ > #endif > > #ifndef __GNUC__ >- // GCC as of version 4.9 (latest) does not support std::put_time yet. >+ // GCC as of version 4.9 does not support std::put_time yet. > // so ignore it > #define _WEBSOCKETPP_PUTTIME_ >+ >+ // todo: std::put_time may be present in version 5+ > #endif > #else > // In the absence of a blanket define, try to use compiler versions or >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/common/md5.hpp websocketpp-hingobway/websocketpp/common/md5.hpp >--- websocketpp-zaphoyd/websocketpp/common/md5.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/common/md5.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -364,7 +364,7 @@ void md5_append(md5_state_t *pms, md5_by > return; > > /* Update the message length. */ >- pms->count[1] += nbytes >> 29; >+ pms->count[1] += static_cast<md5_word_t>(nbytes >> 29); > pms->count[0] += nbits; > if (pms->count[0] < nbits) > pms->count[1]++; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/connection.hpp websocketpp-hingobway/websocketpp/connection.hpp >--- websocketpp-zaphoyd/websocketpp/connection.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/connection.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -82,7 +82,7 @@ typedef lib::function<void(connection_hd > /** > * The interrupt handler is called when a connection receives an interrupt > * request from the application. Interrupts allow the application to trigger a >- * handler to be run in the absense of a WebSocket level handler trigger (like >+ * handler to be run in the absence of a WebSocket level handler trigger (like > * a new message). > * > * This is typically used by another application thread to schedule some tasks >@@ -687,22 +687,22 @@ public: > */ > lib::error_code send(message_ptr msg); > >- /// Asyncronously invoke handler::on_inturrupt >+ /// Asynchronously invoke handler::on_interrupt > /** >- * Signals to the connection to asyncronously invoke the on_inturrupt >+ * Signals to the connection to asynchronously invoke the on_interrupt > * callback for this connection's handler once it is safe to do so. > * >- * When the on_inturrupt handler callback is called it will be from >+ * When the on_interrupt handler callback is called it will be from > * within the transport event loop with all the thread safety features > * guaranteed by the transport to regular handlers > * >- * Multiple inturrupt signals can be active at once on the same connection >+ * Multiple interrupt signals can be active at once on the same connection > * > * @return An error code > */ > lib::error_code interrupt(); > >- /// Transport inturrupt callback >+ /// Transport interrupt callback > void handle_interrupt(); > > /// Pause reading of new data >@@ -865,7 +865,7 @@ public: > // Subprotocol negotiation // > ///////////////////////////// > >- /// Gets the negotated subprotocol >+ /// Gets the negotiated subprotocol > /** > * Retrieves the subprotocol that was negotiated during the handshake. This > * method is valid in the open handler and later. >@@ -888,26 +888,25 @@ public: > * Adds a subprotocol to the list to send with the opening handshake. This > * may be called multiple times to request more than one. If the server > * supports one of these, it may choose one. If so, it will return it >- * in it's handshake reponse and the value will be available via >+ * in it's handshake response and the value will be available via > * get_subprotocol(). Subprotocol requests should be added in order of > * preference. > * >- * @param request The subprotocol to request >- * @param ec A reference to an error code that will be filled in the case of >- * errors >+ * @param[in] request The subprotocol to request >+ * @param[out] ec A status code describing the outcome of the operation > */ > void add_subprotocol(std::string const & request, lib::error_code & ec); > >- /// Adds the given subprotocol string to the request list >+ /// Adds the given subprotocol string to the request list (exception) > /** > * Adds a subprotocol to the list to send with the opening handshake. This > * may be called multiple times to request more than one. If the server > * supports one of these, it may choose one. If so, it will return it >- * in it's handshake reponse and the value will be available via >+ * in it's handshake response and the value will be available via > * get_subprotocol(). Subprotocol requests should be added in order of > * preference. > * >- * @param request The subprotocol to request >+ * @param[in] request The subprotocol to request > */ > void add_subprotocol(std::string const & request); > >@@ -920,13 +919,12 @@ public: > * > * This member function is valid on server endpoints/connections only > * >- * @param value The subprotocol to select >- * @param ec A reference to an error code that will be filled in the case of >- * errors >+ * @param[in] value The subprotocol to select >+ * @param[out] ec A status code describing the outcome of the operation > */ > void select_subprotocol(std::string const & value, lib::error_code & ec); > >- /// Select a subprotocol to use >+ /// Select a subprotocol to use (exception) > /** > * Indicates which subprotocol should be used for this connection. Valid > * only during the validate handler callback. Subprotocol selected must have >@@ -935,7 +933,7 @@ public: > * > * This member function is valid on server endpoints/connections only > * >- * @param value The subprotocol to select >+ * @param[in] value The subprotocol to select > */ > void select_subprotocol(std::string const & value); > >@@ -947,7 +945,7 @@ public: > /** > * Retrieve the value of a header from the handshake HTTP request. > * >- * @param key Name of the header to get >+ * @param[in] key Name of the header to get > * @return The value of the header > */ > std::string const & get_request_header(std::string const & key) const; >@@ -967,7 +965,7 @@ public: > /** > * Retrieve the value of a header from the handshake HTTP request. > * >- * @param key Name of the header to get >+ * @param[in] key Name of the header to get > * @return The value of the header > */ > std::string const & get_response_header(std::string const & key) const; >@@ -996,7 +994,7 @@ public: > return m_response.get_status_msg(); > } > >- /// Set response status code and message >+ /// Set response status code and message (exception free) > /** > * Sets the response status code to `code` and looks up the corresponding > * message for standard codes. Non-standard codes will be entered as Unknown >@@ -1006,13 +1004,36 @@ public: > * This member function is valid only from the http() and validate() handler > * callbacks. > * >- * @param code Code to set >- * @param msg Message to set >- * @see websocketpp::http::response::set_status >+ * @since 0.9.0 >+ * >+ * @param[in] code Code to set >+ * @param[in] msg Message to set >+ * @param[out] ec A status code describing the outcome of the operation >+ * @see websocketpp::http::parser::response::set_status >+ * @see websocketpp::http::status_code::value (list of valid codes) >+ */ >+ void set_status(http::status_code::value code, lib::error_code & ec); >+ >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// Set response status code and message (exception) >+ /** >+ * Sets the response status code and message to independent custom values. >+ * use set_status(status_code::value) to set the code and have the standard >+ * message be automatically set. >+ * >+ * This member function is valid only from the http() and validate() handler >+ * callbacks. >+ * >+ * @param[in] code Code to set >+ * @param[in] msg Message to set >+ * @throw websocketpp::exception >+ * @see websocketpp::http::parser::response::set_status() >+ * @see websocketpp::http::status_code::value (list of valid codes) > */ > void set_status(http::status_code::value code); >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > >- /// Set response status code and message >+ /// Set response status code and message (exception free) > /** > * Sets the response status code and message to independent custom values. > * use set_status(status_code::value) to set the code and have the standard >@@ -1021,13 +1042,35 @@ public: > * This member function is valid only from the http() and validate() handler > * callbacks. > * >- * @param code Code to set >- * @param msg Message to set >- * @see websocketpp::http::response::set_status >+ * @since 0.9.0 >+ * >+ * @param[in] code Code to set >+ * @param[in] msg Message to set >+ * @param[out] ec A status code describing the outcome of the operation >+ * @see websocketpp::http::response::set_status() >+ * @see websocketpp::http::status_code::value (list of valid codes) >+ */ >+ void set_status(http::status_code::value code, std::string const & msg, >+ lib::error_code & ec); >+ >+ /// Set response status code and message (exception) >+ /** >+ * Sets the response status code and message to independent custom values. >+ * use set_status(status_code::value) to set the code and have the standard >+ * message be automatically set. >+ * >+ * This member function is valid only from the http() and validate() handler >+ * callbacks. >+ * >+ * @param[in] code Code to set >+ * @param[in] msg Message to set >+ * @throw websocketpp::exception >+ * @see websocketpp::http::parser::response::set_status() >+ * @see websocketpp::http::status_code::value (list of valid codes) > */ > void set_status(http::status_code::value code, std::string const & msg); > >- /// Set response body content >+ /// Set response body content (exception free) > /** > * Set the body content of the HTTP response to the parameter string. Note > * set_body will also set the Content-Length HTTP header to the appropriate >@@ -1037,51 +1080,159 @@ public: > * This member function is valid only from the http() and validate() handler > * callbacks. > * >- * @param value String data to include as the body content. >+ * @since 0.9.0 >+ * >+ * @param[in] value String data to include as the body content. >+ * @param[out] ec A status code describing the outcome of the operation > * @see websocketpp::http::response::set_body >+ * @see set_body(std::string const &) (exception version) > */ >- void set_body(std::string const & value); >+ void set_body(std::string const & value, lib::error_code & ec); > >- /// Append a header >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// Set response body content (exception) > /** >- * If a header with this name already exists the value will be appended to >- * the existing header to form a comma separated list of values. Use >- * `connection::replace_header` to overwrite existing values. >+ * Set the body content of the HTTP response to the parameter string. Note >+ * set_body will also set the Content-Length HTTP header to the appropriate >+ * value. If you want the Content-Length header to be something else set it >+ * to something else after calling set_body > * > * This member function is valid only from the http() and validate() handler >- * callbacks, or to a client connection before connect has been called. >+ * callbacks. >+ * >+ * @param[in] value String data to include as the body content. >+ * @throw websocketpp::exception >+ * @see websocketpp::http::response::set_body >+ * @see set_body(std::string const &, lib::error_code &) >+ * (exception free version) >+ */ >+ void set_body(std::string const & value); >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ >+ /// @copydoc websocketpp::connection::set_body(std::string const &, lib::error_code &) >+ void set_body(std::string && value, lib::error_code & ec); >+ >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// @copydoc websocketpp::connection::set_body(std::string const &) >+ void set_body(std::string && value); >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+#endif // _WEBSOCKETPP_MOVE_SEMANTICS_ >+ >+ /// Append a header (exception free) >+ /** >+ * Set the value of a header in the handshake HTTP request or response. If >+ * a header with this name already exists the value will be appended to the >+ * existing header to form a comma separated list of values. Use >+ * `connection::replace_header` to overwrite existing values. >+ * >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called >+ * >+ * @since 0.9.0 >+ * >+ * @param[in] key Name of the header to set >+ * @param[in] val Value to add >+ * @param[out] ec A status code describing the outcome of the operation >+ * @see connection::replace_header >+ * @see websocketpp::http::parser::parser::append_header >+ * @see append_header(std::string const &, std::string const &) >+ * (exception version) >+ */ >+ void append_header(std::string const & key, std::string const & val, >+ lib::error_code & ec); >+ >+ /// Append a header (exception) >+ /** >+ * Set the value of a header in the handshake HTTP request or response. If >+ * a header with this name already exists the value will be appended to the >+ * existing header to form a comma separated list of values. Use >+ * `connection::replace_header` to overwrite existing values. > * >- * @param key Name of the header to set >- * @param val Value to add >- * @see replace_header >- * @see websocketpp::http::parser::append_header >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called >+ * >+ * @param[in] key Name of the header to set >+ * @param[in] val Value to add >+ * @throw websocketpp::exception >+ * @see connection::replace_header >+ * @see websocketpp::http::parser::parser::append_header >+ * @see append_header(std::string const &, std::string const &, >+ * lib::error_code &) (exception free version) > */ > void append_header(std::string const & key, std::string const & val); > >- /// Replace a header >+ /// Replace a header (exception free) > /** >- * If a header with this name already exists the old value will be replaced >+ * Set the value of a header in the handshake HTTP request or response. If >+ * a header with this name already exists the old value will be replaced > * Use `connection::append_header` to append to a list of existing values. > * >- * This member function is valid only from the http() and validate() handler >- * callbacks, or to a client connection before connect has been called. >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called >+ * >+ * @param[in] key Name of the header to set >+ * @param[in] val Value to set >+ * @param[out] ec A status code describing the outcome of the operation >+ * @see connection::append_header >+ * @see websocketpp::http::parser::parser::replace_header >+ * @see replace_header(std::string const &, std::string const &) >+ * (exception version) >+ */ >+ void replace_header(std::string const & key, std::string const & val, >+ lib::error_code & ec); >+ >+ /// Replace a header (exception) >+ /** >+ * Set the value of a header in the handshake HTTP request or response. If >+ * a header with this name already exists the old value will be replaced >+ * Use `connection::append_header` to append to a list of existing values. > * >- * @param key Name of the header to set >- * @param val Value to set >- * @see append_header >- * @see websocketpp::http::parser::replace_header >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called >+ * >+ * @param[in] key Name of the header to set >+ * @param[in] val Value to set >+ * @throw websocketpp::exception >+ * @see connection::append_header >+ * @see websocketpp::http::parser::parser::replace_header >+ * @see replace_header(std::string const & key, std::string const & val, >+ * lib::error_code & ec) (exception free version) > */ > void replace_header(std::string const & key, std::string const & val); > >- /// Remove a header >+ /// Remove a header (exception free) > /** >- * Removes a header from the response. >+ * Removes a header from the handshake HTTP request or response. > * >- * This member function is valid only from the http() and validate() handler >- * callbacks, or to a client connection before connect has been called. >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called >+ * >+ * @param[in] key The name of the header to remove >+ * @param[out] ec A status code describing the outcome of the operation >+ * @see websocketpp::http::parser::parser::remove_header >+ * @see remove_header(std::string const &) (exception version) >+ */ >+ void remove_header(std::string const & key, lib::error_code & ec); >+ >+ /// Remove a header (exception) >+ /** >+ * Removes a header from the handshake HTTP request or response. >+ * >+ * *When can this member function be called?* >+ * - Servers: Valid from the http and validate handlers >+ * - Clients: Valid before websocketpp::client::connect() has been called > * >- * @param key The name of the header to remove >- * @see websocketpp::http::parser::remove_header >+ * @param[in] key The name of the header to remove >+ * @throw websocketpp::exception >+ * @see websocketpp::http::parser::parser::remove_header >+ * @see remove_header(std::string const &, lib::error_code &) >+ * (exception free version) > */ > void remove_header(std::string const & key); > >@@ -1125,8 +1276,8 @@ public: > /// Defer HTTP Response until later (Exception free) > /** > * Used in the http handler to defer the HTTP response for this connection >- * until later. Handshake timers will be canceled and the connection will be >- * left open until `send_http_response` or an equivalent is called. >+ * until later. Handshake timers will be canceled and the connection will >+ * be left open until `send_http_response` or an equivalent is called. > * > * Warning: deferred connections won't time out and as a result can tie up > * resources. >@@ -1389,7 +1540,7 @@ private: > /** > * If no arguments are present no close code/reason will be specified. > * >- * Note: the close code/reason values provided here may be overrided by >+ * Note: the close code/reason values provided here may be overridden by > * other settings (such as silent close). > * > * @param code The close code to send >@@ -1403,7 +1554,7 @@ private: > /** > * If no arguments are present no close code/reason will be specified. > * >- * Note: the close code/reason values provided here may be overrided by >+ * Note: the close code/reason values provided here may be overridden by > * other settings (such as silent close). > * > * The ack flag determines what to do in the case of a blank status and >@@ -1573,7 +1724,7 @@ private: > */ > size_t m_send_buffer_size; > >- /// buffer holding the various parts of the current message being writen >+ /// buffer holding the various parts of the current message being written > /** > * Lock m_write_lock > */ >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/endpoint.hpp websocketpp-hingobway/websocketpp/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -28,6 +28,8 @@ > #ifndef WEBSOCKETPP_ENDPOINT_HPP > #define WEBSOCKETPP_ENDPOINT_HPP > >+#include <websocketpp/transport/base/endpoint.hpp> >+ > #include <websocketpp/connection.hpp> > > #include <websocketpp/logger/levels.hpp> >@@ -109,7 +111,7 @@ public: > > > /// Destructor >- ~endpoint<connection,config>() {} >+ ~endpoint() {} > > #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ > // no copy constructor because endpoints are not copyable >@@ -476,7 +478,7 @@ public: > * can produce one additional type of error, the bad_connection error, that > * indicates that the conversion from connection_hdl to connection_ptr > * failed due to the connection not existing anymore. Each method has a >- * default and an exception free varient. >+ * default and an exception free variant. > */ > > void interrupt(connection_hdl hdl, lib::error_code & ec); >@@ -566,7 +568,6 @@ public: > * @param [in] hdl The handle identifying the connection to send via. > * @param [in] payload The payload string to generated the message with > * @param [in] op The opcode to generated the message with. >- * @param [out] ec A code to fill in for errors > */ > void send(connection_hdl hdl, std::string const & payload, > frame::opcode::value op); >@@ -649,6 +650,7 @@ public: > return con; > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > /// Retrieves a connection_ptr from a connection_hdl (exception version) > connection_ptr get_con_from_hdl(connection_hdl hdl) { > lib::error_code ec; >@@ -658,8 +660,9 @@ public: > } > return con; > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > protected: >- connection_ptr create_connection(); >+ connection_ptr create_connection(lib::error_code & ec); > > lib::shared_ptr<alog_type> m_alog; > lib::shared_ptr<elog_type> m_elog; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/error.hpp websocketpp-hingobway/websocketpp/error.hpp >--- websocketpp-zaphoyd/websocketpp/error.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/error.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -143,7 +143,10 @@ enum value { > http_parse_error, > > /// Extension negotiation failed >- extension_neg_failed >+ extension_neg_failed, >+ >+ /// General transport error, consult more specific transport error code >+ transport_error > }; // enum value > > >@@ -221,6 +224,8 @@ public: > return "HTTP parse error"; > case error::extension_neg_failed: > return "Extension negotiation failed"; >+ case error::transport_error: >+ return "An error occurred in the underlying transport. Consult transport error code for more details."; > default: > return "Unknown"; > } >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/frame.hpp websocketpp-hingobway/websocketpp/frame.hpp >--- websocketpp-zaphoyd/websocketpp/frame.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/frame.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -234,17 +234,17 @@ struct basic_header { > /// The variable size component of a WebSocket frame header > struct extended_header { > extended_header() { >- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); >+ std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00)); > } > > extended_header(uint64_t payload_size) { >- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); >+ std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00)); > > copy_payload(payload_size); > } > > extended_header(uint64_t payload_size, uint32_t masking_key) { >- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); >+ std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH, static_cast<uint8_t>(0x00)); > > // Copy payload size > int offset = copy_payload(payload_size); >@@ -831,7 +831,7 @@ inline size_t byte_mask_circ(uint8_t * i > size_t prepared_key) > { > uint32_converter key; >- key.i = prepared_key; >+ key.i = static_cast<uint32_t>(prepared_key); > > for (size_t i = 0; i < length; ++i) { > output[i] = input[i] ^ key.c[i % 4]; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/constants.hpp websocketpp-hingobway/websocketpp/http/constants.hpp >--- websocketpp-zaphoyd/websocketpp/http/constants.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/constants.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -34,275 +34,428 @@ > #include <vector> > #include <utility> > >+#include <websocketpp/common/system_error.hpp> >+ > namespace websocketpp { > /// HTTP handling support > namespace http { >- /// The type of an HTTP attribute list >- /** >- * The attribute list is an unordered key/value map. Encoded attribute >- * values are delimited by semicolons. >- */ >- typedef std::map<std::string,std::string> attribute_list; >- >- /// The type of an HTTP parameter list >- /** >- * The parameter list is an ordered pairing of a parameter and its >- * associated attribute list. Encoded parameter values are delimited by >- * commas. >- */ >- typedef std::vector< std::pair<std::string,attribute_list> > parameter_list; >- >- /// Literal value of the HTTP header delimiter >- static char const header_delimiter[] = "\r\n"; >- >- /// Literal value of the HTTP header separator >- static char const header_separator[] = ":"; >+ >+/// The type of an HTTP attribute list >+/** >+ * The attribute list is an unordered key/value map. Encoded attribute >+ * values are delimited by semicolons. >+ */ >+typedef std::map<std::string,std::string> attribute_list; >+ >+/// The type of an HTTP parameter list >+/** >+ * The parameter list is an ordered pairing of a parameter and its >+ * associated attribute list. Encoded parameter values are delimited by >+ * commas. >+ */ >+typedef std::vector< std::pair<std::string,attribute_list> > parameter_list; >+ >+/// Literal value of the HTTP header delimiter >+static char const header_delimiter[] = "\r\n"; >+ >+/// Literal value of the HTTP header separator >+static char const header_separator[] = ":"; >+ >+/// Literal value of an empty header >+static std::string const empty_header; >+ >+/// Maximum size in bytes before rejecting an HTTP header as too big. >+size_t const max_header_size = 16000; >+ >+/// Default Maximum size in bytes for HTTP message bodies. >+size_t const max_body_size = 32000000; >+ >+/// Number of bytes to use for temporary istream read buffers >+size_t const istream_buffer = 512; >+ >+/// invalid HTTP token characters >+/** >+ * 0x00 - 0x32, 0x7f-0xff >+ * ( ) < > @ , ; : \ " / [ ] ? = { } >+ */ >+static char const header_token[] = { >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f >+ 0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f >+ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f >+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f >+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f >+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f >+ 1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef >+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff >+}; >+ >+/// Is the character a token >+inline bool is_token_char(unsigned char c) { >+ return (header_token[c] == 1); >+} > >- /// Literal value of an empty header >- static std::string const empty_header; >+/// Is the character a non-token >+inline bool is_not_token_char(unsigned char c) { >+ return !header_token[c]; >+} > >- /// Maximum size in bytes before rejecting an HTTP header as too big. >- size_t const max_header_size = 16000; >- >- /// Default Maximum size in bytes for HTTP message bodies. >- size_t const max_body_size = 32000000; >+/// Is the character whitespace >+/** >+ * whitespace is space (32) or horizontal tab (9) >+ */ >+inline bool is_whitespace_char(unsigned char c) { >+ return (c == 9 || c == 32); >+} > >- /// Number of bytes to use for temporary istream read buffers >- size_t const istream_buffer = 512; >+/// Is the character non-whitespace >+inline bool is_not_whitespace_char(unsigned char c) { >+ return (c != 9 && c != 32); >+} > >- /// invalid HTTP token characters >- /** >- * 0x00 - 0x32, 0x7f-0xff >- * ( ) < > @ , ; : \ " / [ ] ? = { } >- */ >- static char const header_token[] = { >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f >- 0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f >- 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f >- 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f >- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f >- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f >- 1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef >- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff >- }; >- >- /// Is the character a token >- inline bool is_token_char(unsigned char c) { >- return (header_token[c] == 1); >+/// HTTP Status codes >+namespace status_code { >+/// Known values for HTTP Status codes >+enum value { >+ uninitialized = 0, >+ >+ continue_code = 100, >+ switching_protocols = 101, >+ >+ ok = 200, >+ created = 201, >+ accepted = 202, >+ non_authoritative_information = 203, >+ no_content = 204, >+ reset_content = 205, >+ partial_content = 206, >+ >+ multiple_choices = 300, >+ moved_permanently = 301, >+ found = 302, >+ see_other = 303, >+ not_modified = 304, >+ use_proxy = 305, >+ temporary_redirect = 307, >+ >+ bad_request = 400, >+ unauthorized = 401, >+ payment_required = 402, >+ forbidden = 403, >+ not_found = 404, >+ method_not_allowed = 405, >+ not_acceptable = 406, >+ proxy_authentication_required = 407, >+ request_timeout = 408, >+ conflict = 409, >+ gone = 410, >+ length_required = 411, >+ precondition_failed = 412, >+ request_entity_too_large = 413, >+ request_uri_too_long = 414, >+ unsupported_media_type = 415, >+ request_range_not_satisfiable = 416, >+ expectation_failed = 417, >+ im_a_teapot = 418, >+ upgrade_required = 426, >+ precondition_required = 428, >+ too_many_requests = 429, >+ request_header_fields_too_large = 431, >+ >+ internal_server_error = 500, >+ not_implemented = 501, >+ bad_gateway = 502, >+ service_unavailable = 503, >+ gateway_timeout = 504, >+ http_version_not_supported = 505, >+ not_extended = 510, >+ network_authentication_required = 511 >+}; >+ >+/// Given a status code value, return the default status message >+/** >+ * >+ * @param[in] code The HTTP status code to look up >+ * @return A string representing the default status message for this code >+ * @see websocketpp::http::status_code::value (list of valid codes) >+ */ >+inline std::string get_string(value code) { >+ switch (code) { >+ case uninitialized: >+ return "Uninitialized"; >+ case continue_code: >+ return "Continue"; >+ case switching_protocols: >+ return "Switching Protocols"; >+ case ok: >+ return "OK"; >+ case created: >+ return "Created"; >+ case accepted: >+ return "Accepted"; >+ case non_authoritative_information: >+ return "Non Authoritative Information"; >+ case no_content: >+ return "No Content"; >+ case reset_content: >+ return "Reset Content"; >+ case partial_content: >+ return "Partial Content"; >+ case multiple_choices: >+ return "Multiple Choices"; >+ case moved_permanently: >+ return "Moved Permanently"; >+ case found: >+ return "Found"; >+ case see_other: >+ return "See Other"; >+ case not_modified: >+ return "Not Modified"; >+ case use_proxy: >+ return "Use Proxy"; >+ case temporary_redirect: >+ return "Temporary Redirect"; >+ case bad_request: >+ return "Bad Request"; >+ case unauthorized: >+ return "Unauthorized"; >+ case payment_required: >+ return "Payment Required"; >+ case forbidden: >+ return "Forbidden"; >+ case not_found: >+ return "Not Found"; >+ case method_not_allowed: >+ return "Method Not Allowed"; >+ case not_acceptable: >+ return "Not Acceptable"; >+ case proxy_authentication_required: >+ return "Proxy Authentication Required"; >+ case request_timeout: >+ return "Request Timeout"; >+ case conflict: >+ return "Conflict"; >+ case gone: >+ return "Gone"; >+ case length_required: >+ return "Length Required"; >+ case precondition_failed: >+ return "Precondition Failed"; >+ case request_entity_too_large: >+ return "Request Entity Too Large"; >+ case request_uri_too_long: >+ return "Request-URI Too Long"; >+ case unsupported_media_type: >+ return "Unsupported Media Type"; >+ case request_range_not_satisfiable: >+ return "Requested Range Not Satisfiable"; >+ case expectation_failed: >+ return "Expectation Failed"; >+ case im_a_teapot: >+ return "I'm a teapot"; >+ case upgrade_required: >+ return "Upgrade Required"; >+ case precondition_required: >+ return "Precondition Required"; >+ case too_many_requests: >+ return "Too Many Requests"; >+ case request_header_fields_too_large: >+ return "Request Header Fields Too Large"; >+ case internal_server_error: >+ return "Internal Server Error"; >+ case not_implemented: >+ return "Not Implemented"; >+ case bad_gateway: >+ return "Bad Gateway"; >+ case service_unavailable: >+ return "Service Unavailable"; >+ case gateway_timeout: >+ return "Gateway Timeout"; >+ case http_version_not_supported: >+ return "HTTP Version Not Supported"; >+ case not_extended: >+ return "Not Extended"; >+ case network_authentication_required: >+ return "Network Authentication Required"; >+ default: >+ return "Unknown"; > } >+} >+ >+} // namespace status_code > >- /// Is the character a non-token >- inline bool is_not_token_char(unsigned char c) { >- return !header_token[c]; >+/// An exception type specific to HTTP errors >+/** >+ * Includes additional details, such as HTTP error code, >+ * HTTP error message, and a body to return with the HTTP >+ * error response. >+ */ >+class exception : public std::exception { >+public: >+ exception(const std::string& log_msg, >+ status_code::value error_code, >+ const std::string& error_msg = std::string(), >+ const std::string& body = std::string()) >+ : m_msg(log_msg) >+ , m_error_msg(error_msg) >+ , m_body(body) >+ , m_error_code(error_code) {} >+ >+ ~exception() throw() {} >+ >+ virtual const char* what() const throw() { >+ return m_msg.c_str(); > } > >- /// Is the character whitespace >- /** >- * whitespace is space (32) or horizontal tab (9) >- */ >- inline bool is_whitespace_char(unsigned char c) { >- return (c == 9 || c == 32); >+ std::string m_msg; >+ std::string m_error_msg; >+ std::string m_body; >+ status_code::value m_error_code; >+}; >+ >+ >+/// HTTP parser errors >+namespace error { >+enum value { >+ /// Catch-all error for http parser errors that don't fit in other >+ /// categories >+ general = 1, >+ >+ /// The specified data contains illegal characters for the context >+ invalid_format, >+ >+ /// The header name specified contains illegal characters >+ invalid_header_name, >+ >+ /// The body value is larger than the configured maximum size >+ body_too_large, >+ >+ /// The transfer encoding is not supported >+ unsupported_transfer_encoding, >+ >+ /// The transfer encoding is unknown >+ unknown_transfer_encoding, >+ >+ /// A header line was missing a separator >+ missing_header_separator, >+ >+ /// The request headers are larger than the configured maximum size >+ request_header_fields_too_large, >+ >+ /// The request was missing some required values >+ incomplete_request, >+ >+ /// The response status line was missing some required values >+ incomplete_status_line, >+ >+ /// An istream read command returned with the bad flag set >+ istream_bad, >+ >+ /// An istream read succeeded but read (and discarded) more bits from the >+ /// stream than it needed >+ istream_overread, >+}; >+ >+/// Get the HTTP status code associated with the error >+inline status_code::value get_status_code(error::value value) { >+ switch(value) { >+ case error::general: >+ return status_code::bad_request; >+ case error::invalid_format: >+ return status_code::bad_request; >+ case error::invalid_header_name: >+ return status_code::bad_request; >+ case error::body_too_large: >+ return status_code::request_entity_too_large; >+ case error::unsupported_transfer_encoding: >+ return status_code::internal_server_error; >+ case error::unknown_transfer_encoding: >+ return status_code::bad_request; >+ case error::missing_header_separator: >+ return status_code::bad_request; >+ case error::request_header_fields_too_large: >+ return status_code::request_header_fields_too_large; >+ case error::incomplete_request: >+ return status_code::bad_request; >+ case error::incomplete_status_line: >+ return status_code::bad_request; >+ case error::istream_bad: >+ return status_code::internal_server_error; >+ case error::istream_overread: >+ return status_code::internal_server_error; >+ default: >+ return status_code::bad_request; > } >+} > >- /// Is the character non-whitespace >- inline bool is_not_whitespace_char(unsigned char c) { >- return (c != 9 && c != 32); >+/// HTTP parser error category >+class category : public lib::error_category { >+public: >+ char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { >+ return "websocketpp.http"; > } > >- /// HTTP Status codes >- namespace status_code { >- enum value { >- uninitialized = 0, >- >- continue_code = 100, >- switching_protocols = 101, >- >- ok = 200, >- created = 201, >- accepted = 202, >- non_authoritative_information = 203, >- no_content = 204, >- reset_content = 205, >- partial_content = 206, >- >- multiple_choices = 300, >- moved_permanently = 301, >- found = 302, >- see_other = 303, >- not_modified = 304, >- use_proxy = 305, >- temporary_redirect = 307, >- >- bad_request = 400, >- unauthorized = 401, >- payment_required = 402, >- forbidden = 403, >- not_found = 404, >- method_not_allowed = 405, >- not_acceptable = 406, >- proxy_authentication_required = 407, >- request_timeout = 408, >- conflict = 409, >- gone = 410, >- length_required = 411, >- precondition_failed = 412, >- request_entity_too_large = 413, >- request_uri_too_long = 414, >- unsupported_media_type = 415, >- request_range_not_satisfiable = 416, >- expectation_failed = 417, >- im_a_teapot = 418, >- upgrade_required = 426, >- precondition_required = 428, >- too_many_requests = 429, >- request_header_fields_too_large = 431, >- >- internal_server_error = 500, >- not_implemented = 501, >- bad_gateway = 502, >- service_unavailable = 503, >- gateway_timeout = 504, >- http_version_not_supported = 505, >- not_extended = 510, >- network_authentication_required = 511 >- }; >- >- // TODO: should this be inline? >- inline std::string get_string(value c) { >- switch (c) { >- case uninitialized: >- return "Uninitialized"; >- case continue_code: >- return "Continue"; >- case switching_protocols: >- return "Switching Protocols"; >- case ok: >- return "OK"; >- case created: >- return "Created"; >- case accepted: >- return "Accepted"; >- case non_authoritative_information: >- return "Non Authoritative Information"; >- case no_content: >- return "No Content"; >- case reset_content: >- return "Reset Content"; >- case partial_content: >- return "Partial Content"; >- case multiple_choices: >- return "Multiple Choices"; >- case moved_permanently: >- return "Moved Permanently"; >- case found: >- return "Found"; >- case see_other: >- return "See Other"; >- case not_modified: >- return "Not Modified"; >- case use_proxy: >- return "Use Proxy"; >- case temporary_redirect: >- return "Temporary Redirect"; >- case bad_request: >- return "Bad Request"; >- case unauthorized: >- return "Unauthorized"; >- case payment_required: >- return "Payment Required"; >- case forbidden: >- return "Forbidden"; >- case not_found: >- return "Not Found"; >- case method_not_allowed: >- return "Method Not Allowed"; >- case not_acceptable: >- return "Not Acceptable"; >- case proxy_authentication_required: >- return "Proxy Authentication Required"; >- case request_timeout: >- return "Request Timeout"; >- case conflict: >- return "Conflict"; >- case gone: >- return "Gone"; >- case length_required: >- return "Length Required"; >- case precondition_failed: >- return "Precondition Failed"; >- case request_entity_too_large: >- return "Request Entity Too Large"; >- case request_uri_too_long: >- return "Request-URI Too Long"; >- case unsupported_media_type: >- return "Unsupported Media Type"; >- case request_range_not_satisfiable: >- return "Requested Range Not Satisfiable"; >- case expectation_failed: >- return "Expectation Failed"; >- case im_a_teapot: >- return "I'm a teapot"; >- case upgrade_required: >- return "Upgrade Required"; >- case precondition_required: >- return "Precondition Required"; >- case too_many_requests: >- return "Too Many Requests"; >- case request_header_fields_too_large: >- return "Request Header Fields Too Large"; >- case internal_server_error: >- return "Internal Server Error"; >- case not_implemented: >- return "Not Implemented"; >- case bad_gateway: >- return "Bad Gateway"; >- case service_unavailable: >- return "Service Unavailable"; >- case gateway_timeout: >- return "Gateway Timeout"; >- case http_version_not_supported: >- return "HTTP Version Not Supported"; >- case not_extended: >- return "Not Extended"; >- case network_authentication_required: >- return "Network Authentication Required"; >- default: >- return "Unknown"; >- } >+ std::string message(int value) const { >+ switch(value) { >+ case error::general: >+ return "Generic http parser error"; >+ case error::invalid_format: >+ return "The specified data contains illegal characters for the context"; >+ case error::invalid_header_name: >+ return "The header name specified contains illegal characters"; >+ case error::body_too_large: >+ return "The body value is larger than the configured maximum size"; >+ case error::unsupported_transfer_encoding: >+ return "The transfer encoding is not supported"; >+ case error::unknown_transfer_encoding: >+ return "The transfer encoding is unknown"; >+ case error::missing_header_separator: >+ return "A header line was missing a separator"; >+ case error::request_header_fields_too_large: >+ return "The request headers are larger than the configured maximum size"; >+ case error::incomplete_request: >+ return "The request was missing some required values"; >+ case error::incomplete_status_line: >+ return "The response status line was missing some required values"; >+ case error::istream_bad: >+ return "An istream read command returned with the bad flag set"; >+ case error::istream_overread: >+ return "An istream read succeeded but read (and discarded) more bits from the stream than it needed"; >+ default: >+ return "Unknown"; > } > } >+}; > >- class exception : public std::exception { >- public: >- exception(const std::string& log_msg, >- status_code::value error_code, >- const std::string& error_msg = std::string(), >- const std::string& body = std::string()) >- : m_msg(log_msg) >- , m_error_msg(error_msg) >- , m_body(body) >- , m_error_code(error_code) {} >+/// Get a reference to a static copy of the asio transport error category >+inline lib::error_category const & get_category() { >+ static category instance; >+ return instance; >+} > >- ~exception() throw() {} >+/// Create an error code with the given value and the asio transport category >+inline lib::error_code make_error_code(error::value e) { >+ return lib::error_code(static_cast<int>(e), get_category()); >+} >+ >+} // namespace error >+} // namespace http >+} // namespace websocketpp >+ >+_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ >+template<> struct is_error_code_enum<websocketpp::http::error::value> >+{ >+ static bool const value = true; >+}; >+_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ > >- virtual const char* what() const throw() { >- return m_msg.c_str(); >- } > >- std::string m_msg; >- std::string m_error_msg; >- std::string m_body; >- status_code::value m_error_code; >- }; >-} >-} > > #endif // HTTP_CONSTANTS_HPP >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/impl/parser.hpp websocketpp-hingobway/websocketpp/http/impl/parser.hpp >--- websocketpp-zaphoyd/websocketpp/http/impl/parser.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/impl/parser.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -38,11 +38,16 @@ namespace websocketpp { > namespace http { > namespace parser { > >-inline void parser::set_version(std::string const & version) { >+inline lib::error_code parser::set_version(std::string const & version) { >+ // todo: validation? > m_version = version; >+ >+ return lib::error_code(); > } > > inline std::string const & parser::get_header(std::string const & key) const { >+ // This find is case insensitive due to the case insensitive comparator >+ // templated into header_list. > header_list::const_iterator h = m_headers.find(key); > > if (h == m_headers.end()) { >@@ -64,11 +69,11 @@ inline bool parser::get_header_as_plist( > return this->parse_parameter_list(it->second,out); > } > >-inline void parser::append_header(std::string const & key, std::string const & >+inline lib::error_code parser::append_header(std::string const & key, std::string const & > val) > { > if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) { >- throw exception("Invalid header name",status_code::bad_request); >+ return error::make_error_code(error::invalid_header_name); > } > > if (this->get_header(key).empty()) { >@@ -76,32 +81,51 @@ inline void parser::append_header(std::s > } else { > m_headers[key] += ", " + val; > } >+ return lib::error_code(); > } > >-inline void parser::replace_header(std::string const & key, std::string const & >+inline lib::error_code parser::replace_header(std::string const & key, std::string const & > val) > { >+ if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) { >+ return error::make_error_code(error::invalid_header_name); >+ } >+ > m_headers[key] = val; >+ return lib::error_code(); > } > >-inline void parser::remove_header(std::string const & key) { >+inline lib::error_code parser::remove_header(std::string const & key) >+{ >+ if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) { >+ return error::make_error_code(error::invalid_header_name); >+ } >+ > m_headers.erase(key); >+ return lib::error_code(); > } > >-inline void parser::set_body(std::string const & value) { >+inline lib::error_code parser::set_body(std::string const & value) { >+ lib::error_code ec; > if (value.size() == 0) { >- remove_header("Content-Length"); >+ ec = remove_header("Content-Length"); >+ if (ec) { return ec; } >+ > m_body.clear(); >- return; >+ return lib::error_code(); > } > >- // TODO: should this method respect the max size? If so how should errors >- // be indicated? >+ if (value.size() > m_body_bytes_max) { >+ return error::make_error_code(error::body_too_large); >+ } > > std::stringstream len; > len << value.size(); >- replace_header("Content-Length", len.str()); >+ ec = replace_header("Content-Length", len.str()); >+ if (ec) { return ec; } >+ > m_body = value; >+ return lib::error_code(); > } > > inline bool parser::parse_parameter_list(std::string const & in, >@@ -116,7 +140,7 @@ inline bool parser::parse_parameter_list > return (it == in.begin()); > } > >-inline bool parser::prepare_body() { >+inline bool parser::prepare_body(lib::error_code & ec) { > if (!get_header("Content-Length").empty()) { > std::string const & cl_header = get_header("Content-Length"); > char * end; >@@ -127,38 +151,44 @@ inline bool parser::prepare_body() { > m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10); > > if (m_body_bytes_needed > m_body_bytes_max) { >- throw exception("HTTP message body too large", >- status_code::request_entity_too_large); >+ ec = error::make_error_code(error::body_too_large); >+ return false; > } > > m_body_encoding = body_encoding::plain; >+ ec = lib::error_code(); > return true; > } else if (get_header("Transfer-Encoding") == "chunked") { >- // TODO >+ // ec = error::make_error_code(error::unsupported_transfer_encoding); >+ // TODO: support for chunked transfers? Is that too much HTTP logic? > //m_body_encoding = body_encoding::chunked; > return false; > } else { >+ ec = lib::error_code(); > return false; > } > } > >-inline size_t parser::process_body(char const * buf, size_t len) { >+inline size_t parser::process_body(char const * buf, size_t len, >+ lib::error_code & ec) >+{ > if (m_body_encoding == body_encoding::plain) { > size_t processed = (std::min)(m_body_bytes_needed,len); > m_body.append(buf,processed); > m_body_bytes_needed -= processed; >+ ec = lib::error_code(); > return processed; > } else if (m_body_encoding == body_encoding::chunked) { >- // TODO: >- throw exception("Unexpected body encoding", >- status_code::internal_server_error); >+ ec = error::make_error_code(error::unsupported_transfer_encoding); >+ return 0; >+ // TODO: support for chunked transfers? > } else { >- throw exception("Unexpected body encoding", >- status_code::internal_server_error); >+ ec = error::make_error_code(error::unknown_transfer_encoding); >+ return 0; > } > } > >-inline void parser::process_header(std::string::iterator begin, >+inline lib::error_code parser::process_header(std::string::iterator begin, > std::string::iterator end) > { > std::string::iterator cursor = std::search( >@@ -169,11 +199,13 @@ inline void parser::process_header(std:: > ); > > if (cursor == end) { >- throw exception("Invalid header line",status_code::bad_request); >+ return error::make_error_code(error::body_too_large); > } > >- append_header(strip_lws(std::string(begin,cursor)), >- strip_lws(std::string(cursor+sizeof(header_separator)-1,end))); >+ // any error from append header represents our final error status >+ return append_header( >+ strip_lws(std::string(begin,cursor)), >+ strip_lws(std::string(cursor+sizeof(header_separator)-1,end))); > } > > inline header_list const & parser::get_headers() const { >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/impl/request.hpp websocketpp-hingobway/websocketpp/http/impl/request.hpp >--- websocketpp-zaphoyd/websocketpp/http/impl/request.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/impl/request.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -38,20 +38,37 @@ namespace websocketpp { > namespace http { > namespace parser { > >-inline size_t request::consume(char const * buf, size_t len) { >- size_t bytes_processed; >+inline size_t request::consume(char const * buf, size_t len, lib::error_code & ec) >+{ >+ size_t bytes_processed = 0; > >- if (m_ready) {return 0;} >+ if (m_ready) { >+ // the request is already complete. End immediately without reading. >+ ec = lib::error_code(); >+ return 0; >+ } > > if (m_body_bytes_needed > 0) { >- bytes_processed = process_body(buf,len); >+ // The headers are complete, but we are still expecting more body >+ // bytes. Process body bytes. >+ bytes_processed = process_body(buf, len, ec); >+ if (ec) { >+ return bytes_processed; >+ } >+ >+ // if we have ready all the expected body bytes set the ready flag > if (body_ready()) { > m_ready = true; > } > return bytes_processed; > } > >- // copy new header bytes into buffer >+ // at this point we have an incomplete request still waiting for headers >+ >+ // copy new candidate bytes into our local buffer. This buffer may have >+ // leftover bytes from previous calls. Not all of these bytes are >+ // necessarily header bytes (they might be body or even data after this >+ // request entirely for a keepalive request) > m_buf->append(buf,len); > > // Search for delimiter in buf. If found read until then. If not read all >@@ -59,39 +76,66 @@ inline size_t request::consume(char cons > std::string::iterator end; > > for (;;) { >- // search for line delimiter >+ // search for line delimiter in our local buffer > end = std::search( > begin, > m_buf->end(), > header_delimiter, > header_delimiter+sizeof(header_delimiter)-1 > ); >- >- m_header_bytes += (end-begin+sizeof(header_delimiter)); >- >- if (m_header_bytes > max_header_size) { >- // exceeded max header size >- throw exception("Maximum header size exceeded.", >- status_code::request_header_fields_too_large); >- } > > if (end == m_buf->end()) { >- // we are out of bytes. Discard the processed bytes and copy the >- // remaining unprecessed bytes to the beginning of the buffer >- std::copy(begin,end,m_buf->begin()); >- m_buf->resize(static_cast<std::string::size_type>(end-begin)); >- m_header_bytes -= m_buf->size(); >+ // we didn't find the delimiter >+ >+ // check that the confirmed header bytes plus the outstanding >+ // candidate bytes do not put us over the header size limit. >+ if (m_header_bytes + (end - begin) > max_header_size) { >+ ec = error::make_error_code(error::request_header_fields_too_large); >+ return 0; >+ } > >+ // We are out of bytes but not over any limits yet. Discard the >+ // processed bytes and copy the remaining unprecessed bytes to the >+ // beginning of the buffer in prep for another call to consume. >+ >+ // If there are no processed bytes in the buffer right now don't >+ // copy the unprocessed ones over themselves. >+ if (begin != m_buf->begin()) { >+ std::copy(begin,end,m_buf->begin()); >+ m_buf->resize(static_cast<std::string::size_type>(end-begin)); >+ } >+ >+ ec = lib::error_code(); > return len; > } > >- //the range [begin,end) now represents a line to be processed. >+ // at this point we have found a delimiter and the range [begin,end) >+ // represents a line to be processed >+ >+ // update count of header bytes read so far >+ m_header_bytes += (end-begin+sizeof(header_delimiter)); >+ >+ >+ if (m_header_bytes > max_header_size) { >+ // This read exceeded max header size >+ ec = error::make_error_code(error::request_header_fields_too_large); >+ return 0; >+ } >+ > if (end-begin == 0) { >- // we got a blank line >+ // we got a blank line, which indicates the end of the headers >+ >+ // If we never got a valid method or are missing a host header then >+ // this request is invalid. > if (m_method.empty() || get_header("Host").empty()) { >- throw exception("Incomplete Request",status_code::bad_request); >+ ec = error::make_error_code(error::incomplete_request); >+ return 0; > } > >+ // any bytes left over in the local buffer are bytes we didn't use. >+ // When we report how many bytes we consumed we need to subtract >+ // these so the caller knows that they need to be processed by some >+ // other logic. > bytes_processed = ( > len - static_cast<std::string::size_type>(m_buf->end()-end) > + sizeof(header_delimiter) - 1 >@@ -104,27 +148,47 @@ inline size_t request::consume(char cons > // continue capturing content-length bytes and expose them as a > // request body. > >- if (prepare_body()) { >- bytes_processed += process_body(buf+bytes_processed,len-bytes_processed); >+ bool need_more = prepare_body(ec); >+ if (ec) { >+ return 0; >+ } >+ >+ if (need_more) { >+ bytes_processed += process_body(buf+bytes_processed,len-bytes_processed,ec); >+ if (ec) { >+ return 0; >+ } > if (body_ready()) { > m_ready = true; > } >+ ec = lib::error_code(); > return bytes_processed; > } else { > m_ready = true; > > // return number of bytes processed (starting bytes - bytes left) >+ ec = lib::error_code(); > return bytes_processed; > } > } else { >+ // we got a line with content > if (m_method.empty()) { >- this->process(begin,end); >+ // if we haven't found a method yet process this line as a first line >+ ec = this->process(begin, end); > } else { >- this->process_header(begin,end); >+ // this is a second (or later) line, process as a header >+ ec = this->process_header(begin, end); >+ } >+ if (ec) { >+ return 0; > } > } > >+ // if we got here it means there is another header line to read. >+ // advance our cursor to the first character after the most recent >+ // delimiter found. > begin = end+(sizeof(header_delimiter)-1); >+ > } > } > >@@ -148,40 +212,49 @@ inline std::string request::raw_head() c > return ret.str(); > } > >-inline void request::set_method(std::string const & method) { >+inline lib::error_code request::set_method(std::string const & method) >+{ > if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) { >- throw exception("Invalid method token.",status_code::bad_request); >+ return error::make_error_code(error::invalid_format); > } > > m_method = method; >+ return lib::error_code(); > } > >-inline void request::set_uri(std::string const & uri) { >+inline lib::error_code request::set_uri(std::string const & uri) { > // TODO: validation? > m_uri = uri; >+ >+ return lib::error_code(); > } > >-inline void request::process(std::string::iterator begin, std::string::iterator >+inline lib::error_code request::process(std::string::iterator begin, std::string::iterator > end) > { >+ lib::error_code ec; >+ > std::string::iterator cursor_start = begin; > std::string::iterator cursor_end = std::find(begin,end,' '); > > if (cursor_end == end) { >- throw exception("Invalid request line1",status_code::bad_request); >+ return error::make_error_code(error::incomplete_request); > } > >- set_method(std::string(cursor_start,cursor_end)); >+ ec = set_method(std::string(cursor_start,cursor_end)); >+ if (ec) { return ec; } > > cursor_start = cursor_end+1; > cursor_end = std::find(cursor_start,end,' '); > > if (cursor_end == end) { >- throw exception("Invalid request line2",status_code::bad_request); >+ return error::make_error_code(error::incomplete_request); > } > >- set_uri(std::string(cursor_start,cursor_end)); >- set_version(std::string(cursor_end+1,end)); >+ ec = set_uri(std::string(cursor_start,cursor_end)); >+ if (ec) { return ec; } >+ >+ return set_version(std::string(cursor_end+1,end)); > } > > } // namespace parser >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/impl/response.hpp websocketpp-hingobway/websocketpp/http/impl/response.hpp >--- websocketpp-zaphoyd/websocketpp/http/impl/response.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/impl/response.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -39,14 +39,25 @@ namespace websocketpp { > namespace http { > namespace parser { > >-inline size_t response::consume(char const * buf, size_t len) { >- if (m_state == DONE) {return 0;} >+inline size_t response::consume(char const * buf, size_t len, lib::error_code & ec) { >+ if (m_state == DONE) { >+ // the response is already complete. End immediately without reading. >+ ec = lib::error_code(); >+ return 0; >+ } > > if (m_state == BODY) { >- return this->process_body(buf,len); >+ // The headers are complete, but we are still expecting more body >+ // bytes. Process body bytes. >+ return this->process_body(buf,len,ec); > } > >- // copy new header bytes into buffer >+ // at this point we have an incomplete response still waiting for headers >+ >+ // copy new candidate bytes into our local buffer. This buffer may have >+ // leftover bytes from previous calls. Not all of these bytes are >+ // necessarily header bytes (they might be body or even data after this >+ // request entirely for a keepalive request) > m_buf->append(buf,len); > > // Search for delimiter in buf. If found read until then. If not read all >@@ -63,80 +74,119 @@ inline size_t response::consume(char con > header_delimiter + sizeof(header_delimiter) - 1 > ); > >- m_header_bytes += (end-begin+sizeof(header_delimiter)); >- >- if (m_header_bytes > max_header_size) { >- // exceeded max header size >- throw exception("Maximum header size exceeded.", >- status_code::request_header_fields_too_large); >- } >- > if (end == m_buf->end()) { >- // we are out of bytes. Discard the processed bytes and copy the >- // remaining unprecessed bytes to the beginning of the buffer >- std::copy(begin,end,m_buf->begin()); >- m_buf->resize(static_cast<std::string::size_type>(end-begin)); >+ // we didn't find the delimiter >+ >+ // check that the confirmed header bytes plus the outstanding >+ // candidate bytes do not put us over the header size limit. >+ if (m_header_bytes + (end - begin) > max_header_size) { >+ ec = error::make_error_code(error::request_header_fields_too_large); >+ return 0; >+ } >+ >+ // We are out of bytes but not over any limits yet. Discard the >+ // processed bytes and copy the remaining unprecessed bytes to the >+ // beginning of the buffer in prep for another call to consume. >+ >+ // If there are no processed bytes in the buffer right now don't >+ // copy the unprocessed ones over themselves. >+ if (begin != m_buf->begin()) { >+ std::copy(begin,end,m_buf->begin()); >+ m_buf->resize(static_cast<std::string::size_type>(end-begin)); >+ } > > m_read += len; >- m_header_bytes -= m_buf->size(); > >+ ec = lib::error_code(); > return len; > } > >- //the range [begin,end) now represents a line to be processed. >+ // at this point we have found a delimiter and the range [begin,end) >+ // represents a line to be processed >+ >+ // update count of header bytes read so far >+ m_header_bytes += (end-begin+sizeof(header_delimiter)); >+ >+ if (m_header_bytes > max_header_size) { >+ // This read exceeded max header size >+ ec = error::make_error_code(error::request_header_fields_too_large); >+ return 0; >+ } >+ > > if (end-begin == 0) { >- // we got a blank line >+ // we got a blank line, which indicates the end of the headers >+ >+ // If we are still looking for a response line then this request >+ // is incomplete > if (m_state == RESPONSE_LINE) { >- throw exception("Incomplete Request",status_code::bad_request); >+ ec = error::make_error_code(error::incomplete_request); >+ return 0; > } > > // TODO: grab content-length > std::string length = get_header("Content-Length"); > > if (length.empty()) { >- // no content length found, read indefinitely >+ // no content length found, read indefinitely? > m_read = 0; > } else { > std::istringstream ss(length); > > if ((ss >> m_read).fail()) { >- throw exception("Unable to parse Content-Length header", >- status_code::bad_request); >+ ec = error::make_error_code(error::invalid_format); >+ return 0; > } > } > >+ // transition state to reading the response body > m_state = BODY; > >- // calc header bytes processed (starting bytes - bytes left) >+ // calculate how many bytes in the local buffer are bytes we didn't >+ // use for the headers. > size_t read = ( > len - static_cast<std::string::size_type>(m_buf->end() - end) > + sizeof(header_delimiter) - 1 > ); > >- // if there were bytes left process them as body bytes >+ // if there were bytes left process them as body bytes. >+ // read is incremented with the number of body bytes processed. >+ // It is possible that there are still some bytes not read. These >+ // will be 'returned' to the caller by having the return value be >+ // less than len. > if (read < len) { >- read += this->process_body(buf+read,(len-read)); >+ read += this->process_body(buf+read,(len-read),ec); >+ } >+ if (ec) { >+ return 0; > } > > // frees memory used temporarily during header parsing > m_buf.reset(); > >+ ec = lib::error_code(); > return read; > } else { >+ // we got a line > if (m_state == RESPONSE_LINE) { >- this->process(begin,end); >+ ec = this->process(begin,end); > m_state = HEADERS; > } else { >- this->process_header(begin,end); >+ ec = this->process_header(begin,end); >+ } >+ if (ec) { >+ return 0; > } > } > >+ // if we got here it means there is another header line to read. >+ // advance our cursor to the first character after the most recent >+ // delimiter found. > begin = end+(sizeof(header_delimiter) - 1); > } > } > >-inline size_t response::consume(std::istream & s) { >+inline size_t response::consume(std::istream & s, lib::error_code & ec) { > char buf[istream_buffer]; > size_t bytes_read; > size_t bytes_processed; >@@ -147,12 +197,21 @@ inline size_t response::consume(std::ist > bytes_read = static_cast<size_t>(s.gcount()); > > if (s.fail() || s.eof()) { >- bytes_processed = this->consume(buf,bytes_read); >+ bytes_processed = this->consume(buf,bytes_read,ec); > total += bytes_processed; > >+ if (ec) { return total; } >+ > if (bytes_processed != bytes_read) { >- // problem >- break; >+ // we read more data from the stream than we needed for the >+ // HTTP response. This extra data gets thrown away now. >+ // Returning it to the caller is complicated so we alert the >+ // caller at least. This whole method has been deprecated >+ // because this convenience method doesnt really add useful >+ // functionality to the library, but makes it difficult to >+ // recover from error cases. >+ ec = error::make_error_code(error::istream_overread); >+ return total; > } > } else if (s.bad()) { > // problem >@@ -162,12 +221,21 @@ inline size_t response::consume(std::ist > // the newline that was discarded, since our raw consume function > // expects the newline to be be there. > buf[bytes_read-1] = '\n'; >- bytes_processed = this->consume(buf,bytes_read); >+ bytes_processed = this->consume(buf,bytes_read,ec); > total += bytes_processed; > >+ if (ec) { return total; } >+ > if (bytes_processed != bytes_read) { >- // problem >- break; >+ // we read more data from the stream than we needed for the >+ // HTTP response. This extra data gets thrown away now. >+ // Returning it to the caller is complicated so we alert the >+ // caller at least. This whole method has been deprecated >+ // because this convenience method doesnt really add useful >+ // functionality to the library, but makes it difficult to >+ // recover from error cases. >+ ec = error::make_error_code(error::istream_overread); >+ return total; > } > } > } >@@ -188,28 +256,41 @@ inline std::string response::raw() const > return ret.str(); > } > >-inline void response::set_status(status_code::value code) { >- // TODO: validation? >+inline lib::error_code response::set_status(status_code::value code) { >+ // In theory the type of status_code::value should prevent setting any >+ // invalid values. Messages are canned and looked up and known to be >+ // valid. >+ // TODO: Is there anything else that would need validation here? > m_status_code = code; > m_status_msg = get_string(code); >+ return lib::error_code(); > } > >-inline void response::set_status(status_code::value code, std::string const & >- msg) >+inline lib::error_code response::set_status(status_code::value code, >+ std::string const & msg) > { >- // TODO: validation? >+ // In theory the type of status_code::value should prevent setting any >+ // invalid values. >+ // TODO: Is there anything else that would need validation here? >+ // length or content of message? >+ // Per RFC2616 >+ // Reason-Phrase = *<TEXT, excluding CR, LF> >+ // TEXT = = <any OCTET except CTLs,but including LWS> >+ // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> >+ // LWS = [CRLF] 1*( SP | HT ) > m_status_code = code; > m_status_msg = msg; >+ return lib::error_code(); > } > >-inline void response::process(std::string::iterator begin, >+inline lib::error_code response::process(std::string::iterator begin, > std::string::iterator end) > { > std::string::iterator cursor_start = begin; > std::string::iterator cursor_end = std::find(begin,end,' '); > > if (cursor_end == end) { >- throw exception("Invalid response line",status_code::bad_request); >+ return error::make_error_code(error::incomplete_status_line); > } > > set_version(std::string(cursor_start,cursor_end)); >@@ -218,7 +299,7 @@ inline void response::process(std::strin > cursor_end = std::find(cursor_start,end,' '); > > if (cursor_end == end) { >- throw exception("Invalid request line",status_code::bad_request); >+ return error::make_error_code(error::incomplete_status_line); > } > > int code; >@@ -226,18 +307,23 @@ inline void response::process(std::strin > std::istringstream ss(std::string(cursor_start,cursor_end)); > > if ((ss >> code).fail()) { >- throw exception("Unable to parse response code",status_code::bad_request); >+ return error::make_error_code(error::incomplete_status_line); > } > >- set_status(status_code::value(code),std::string(cursor_end+1,end)); >+ // todo: validation of status code? Technically there are limits on what >+ // status codes can be. Right now we follow Postel's law and check only >+ // that the valid is an integer and let the next layer decide what to do. >+ // Is this reasonable or should we be more aggressive? >+ >+ // validation of the status message will pass through >+ return set_status(status_code::value(code),std::string(cursor_end+1,end)); > } > >-inline size_t response::process_body(char const * buf, size_t len) { >+inline size_t response::process_body(char const * buf, size_t len, lib::error_code & ec) { > // If no content length was set then we read forever and never set m_ready > if (m_read == 0) { >- //m_body.append(buf,len); >- //return len; > m_state = DONE; >+ ec = lib::error_code(); > return 0; > } > >@@ -256,6 +342,7 @@ inline size_t response::process_body(cha > > m_body.append(buf,to_read); > m_read -= to_read; >+ ec = lib::error_code(); > return to_read; > } > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/parser.hpp websocketpp-hingobway/websocketpp/http/parser.hpp >--- websocketpp-zaphoyd/websocketpp/http/parser.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/parser.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -417,12 +417,13 @@ public: > * @todo Does this method need any validation? > * > * @param [in] version The value to set the HTTP version to. >+ * @return A status code describing the outcome of the operation. > */ >- void set_version(std::string const & version); >+ lib::error_code set_version(std::string const & version); > > /// Get the value of an HTTP header > /** >- * @todo Make this method case insensitive. >+ * Note: per HTTP specs header values are compared case insensitively. > * > * @param [in] key The name/key of the header to get. > * @return The value associated with the given HTTP header key. >@@ -457,16 +458,19 @@ public: > * indicated value. If a header with the name `key` already exists, `val` > * will be appended to the existing value. > * >- * @todo Make this method case insensitive. >+ * Note: per HTTP specs header values are compared case insensitively. >+ * > * @todo Should there be any restrictions on which keys are allowed? >- * @todo Exception free varient > * > * @see replace_header > * >+ * @since 0.9.0 (return value added, exceptions removed) >+ * > * @param [in] key The name/key of the header to append to. > * @param [in] val The value to append. >+ * @return A status code describing the outcome of the operation. > */ >- void append_header(std::string const & key, std::string const & val); >+ lib::error_code append_header(std::string const & key, std::string const & val); > > /// Set a value for an HTTP header, replacing an existing value > /** >@@ -474,27 +478,33 @@ public: > * indicated value. If a header with the name `key` already exists, `val` > * will replace the existing value. > * >- * @todo Make this method case insensitive. >- * @todo Should there be any restrictions on which keys are allowed? >- * @todo Exception free varient >+ * Note: per HTTP specs header values are compared case insensitively. > * > * @see append_header > * >+ * @since 0.9.0 (return value added) >+ * > * @param [in] key The name/key of the header to append to. > * @param [in] val The value to append. >+ * @return A status code describing the outcome of the operation. > */ >- void replace_header(std::string const & key, std::string const & val); >+ lib::error_code replace_header(std::string const & key, std::string const & val); > > /// Remove a header from the parser > /** > * Removes the header entirely from the parser. This is different than > * setting the value of the header to blank. > * >- * @todo Make this method case insensitive. >+ * Note: per HTTP specs header values are compared case insensitively. > * >+ * @since 0.9.0 (return value added) >+ * > * @param [in] key The name/key of the header to remove. >+ * @return A status code describing the outcome of the operation. > */ >- void remove_header(std::string const & key); >+ lib::error_code remove_header(std::string const & key); >+ >+ // todo exception varients for the above 3? > > /// Get HTTP body > /** >@@ -513,9 +523,12 @@ public: > * value. If you want the Content-Length header to be something else, do so > * via replace_header("Content-Length") after calling set_body() > * >+ * @since 0.9.0 (return value added) >+ * > * @param value String data to include as the body content. >+ * @return A status code describing the outcome of the operation. > */ >- void set_body(std::string const & value); >+ lib::error_code set_body(std::string const & value); > > /// Get body size limit > /** >@@ -554,12 +567,14 @@ public: > protected: > /// Process a header line > /** >- * @todo Update this method to be exception free. >- * >+ * @since 0.9.0 (return value added, exceptions removed) >+ * > * @param [in] begin An iterator to the beginning of the sequence. > * @param [in] end An iterator to the end of the sequence. >+ * @return A status code describing the outcome of the operation. > */ >- void process_header(std::string::iterator begin, std::string::iterator end); >+ lib::error_code process_header(std::string::iterator begin, >+ std::string::iterator end); > > /// Prepare the parser to begin parsing body data > /** >@@ -570,23 +585,27 @@ protected: > * > * Must not be called until after all headers have been processed. > * >- * @since 0.5.0 >+ * @since 0.5.0 (no parameters) >+ * @since 0.9.0 (ec parameter added, exceptions removed) > * >+ * @param [out] ec A status code describing the outcome of the operation. > * @return True if more bytes are needed to load the body, false otherwise. > */ >- bool prepare_body(); >+ bool prepare_body(lib::error_code & ec); > > /// Process body data > /** > * Parses body data. > * > * @since 0.5.0 >+ * @since 0.9.0 (ec parameter added, exceptions removed) > * > * @param [in] begin An iterator to the beginning of the sequence. > * @param [in] end An iterator to the end of the sequence. >+ * @param [out] ec A status code describing the outcome of the operation. > * @return The number of bytes processed > */ >- size_t process_body(char const * buf, size_t len); >+ size_t process_body(char const * buf, size_t len, lib::error_code & ec); > > /// Check if the parser is done parsing the body > /** >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/request.hpp websocketpp-hingobway/websocketpp/http/request.hpp >--- websocketpp-zaphoyd/websocketpp/http/request.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/request.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -72,11 +72,14 @@ public: > * error reasons include malformed requests, incomplete requests, and max > * header size being reached. > * >- * @param buf Pointer to byte buffer >- * @param len Size of byte buffer >+ * @since 0.9.0 Added ec parameter >+ * >+ * @param [in] buf Pointer to byte buffer >+ * @param [in] len Size of byte buffer >+ * @param [out] ec A status code describing the outcome of the operation. > * @return Number of bytes processed. > */ >- size_t consume(char const * buf, size_t len); >+ size_t consume(char const * buf, size_t len, lib::error_code & ec); > > /// Returns whether or not the request is ready for reading. > bool ready() const { >@@ -89,16 +92,32 @@ public: > /// Returns the raw request headers only (similar to an HTTP HEAD request) > std::string raw_head() const; > >- /// Set the HTTP method. Must be a valid HTTP token >- void set_method(std::string const & method); >+ /// Set the HTTP method. >+ /** >+ * Must be a valid HTTP token >+ * >+ * @since 0.9.0 added return value and removed exception >+ * >+ * @param [in] method The value to set the method to. >+ * @return A status code describing the outcome of the operation. >+ */ >+ lib::error_code set_method(std::string const & method); > > /// Return the request method > std::string const & get_method() const { > return m_method; > } > >- /// Set the HTTP uri. Must be a valid HTTP uri >- void set_uri(std::string const & uri); >+ /// Set the HTTP uri. >+ /** >+ * Must be a valid HTTP uri >+ * >+ * @since 0.9.0 Return value added >+ * >+ * @param uri The URI to set >+ * @return A status code describing the outcome of the operation. >+ */ >+ lib::error_code set_uri(std::string const & uri); > > /// Return the requested URI > std::string const & get_uri() const { >@@ -107,7 +126,14 @@ public: > > private: > /// Helper function for message::consume. Process request line >- void process(std::string::iterator begin, std::string::iterator end); >+ /** >+ * @since 0.9.0 (ec parameter added, exceptions removed) >+ * >+ * @param [in] begin An iterator to the beginning of the sequence. >+ * @param [in] end An iterator to the end of the sequence. >+ * @return A status code describing the outcome of the operation. >+ */ >+ lib::error_code process(std::string::iterator begin, std::string::iterator end); > > lib::shared_ptr<std::string> m_buf; > std::string m_method; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/http/response.hpp websocketpp-hingobway/websocketpp/http/response.hpp >--- websocketpp-zaphoyd/websocketpp/http/response.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/http/response.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -77,21 +77,24 @@ public: > * the ready flag will be set. Further calls to consume once ready will be > * ignored. > * >- * Consume will throw an http::exception in the case of an error. Typical >- * error reasons include malformed responses, incomplete responses, and max >- * header size being reached. >- * >- * @param buf Pointer to byte buffer >- * @param len Size of byte buffer >+ * As of 0.9.0, consume will return a status code describing the output of >+ * the operation. Earlier versions threw an `http::exception`. The status >+ * code will be zero/default constructed on success and non-zero on error. >+ * Typical error reasons include malformed responses, incomplete responses, >+ * and max header size being reached. >+ * >+ * @since 0.9.0 Added ec parameter >+ * >+ * @param [in] buf Pointer to byte buffer >+ * @param [in] len Size of byte buffer >+ * @param [out] ec A status code describing the outcome of the operation. > * @return Number of bytes processed. > */ >- size_t consume(char const * buf, size_t len); >+ size_t consume(char const * buf, size_t len, lib::error_code & ec); > > /// Process bytes in the input buffer (istream version) > /** > * Process bytes from istream s. Returns the number of bytes processed. >- * Bytes left unprocessed means bytes left over after the final header >- * delimiters. > * > * Consume is a streaming processor. It may be called multiple times on one > * response and the full headers need not be available before processing can >@@ -99,15 +102,40 @@ public: > * the ready flag will be set. Further calls to consume once ready will be > * ignored. > * >- * Consume will throw an http::exception in the case of an error. Typical >- * error reasons include malformed responses, incomplete responses, and max >- * header size being reached. >+ * As of 0.9.0, consume will return a status code describing the output of >+ * the operation. Earlier versions threw an `http::exception`. The status >+ * code will be zero/default constructed on success and non-zero on error. >+ * Typical error reasons include malformed responses, incomplete responses, >+ * and max header size being reached. >+ * >+ * **WARNING:** If not all the bytes were needed to complete the HTTP >+ * request those bytes will still be removed from the istream and discarded. >+ * If this happens an error `istream_overread` will be returned. This means >+ * that the response read was successful but that some unrelated data was >+ * lost. If you don't care about these bytes you can ignore the error. >+ * >+ * If there is an HTTP processing error and an istream overread in the same >+ * call only the HTTP processing error will be returned. >+ * >+ * If you might need bytes after the header in the istream you should NOT >+ * use this wrapper and instead read data out of the istream directly and >+ * pass it to consume(char const *, size_t, lib::error_code). This method >+ * allows you to retain overread data. >+ * >+ * @deprecated 0.9.0 This overload is dangerous in that it can overread the >+ * stream and there isn't a good way to recover bytes lost this way. As of >+ * 0.9.0 an error is raised when this situation happens, but generally, it >+ * would be better for the calling application to read the stream itself and >+ * call consume(char const *, size_t, lib::error_code) instead which provides >+ * a better method of identifying and recovering from overreads. >+ * >+ * @since 0.9.0 Added ec parameter > * >- * @param buf Pointer to byte buffer >- * @param len Size of byte buffer >+ * @param s pointer to an istream to read from >+ * @param [out] ec A status code describing the outcome of the operation. > * @return Number of bytes processed. > */ >- size_t consume(std::istream & s); >+ size_t consume(std::istream & s, lib::error_code & ec); > > /// Returns true if the response is ready. > /** >@@ -132,10 +160,12 @@ public: > * use set_status(status_code::value,std::string) overload to set both > * values explicitly. > * >+ * @since 0.9.0 Added return value >+ * > * @param code Code to set >- * @param msg Message to set >+ * @return A status code describing the outcome of the operation. > */ >- void set_status(status_code::value code); >+ lib::error_code set_status(status_code::value code); > > /// Set response status code and message > /** >@@ -143,10 +173,13 @@ public: > * use set_status(status_code::value) to set the code and have the standard > * message be automatically set. > * >+ * @since 0.9.0 Added return value >+ * > * @param code Code to set > * @param msg Message to set >+ * @return A status code describing the outcome of the operation. > */ >- void set_status(status_code::value code, std::string const & msg); >+ lib::error_code set_status(status_code::value code, std::string const & msg); > > /// Return the response status code > status_code::value get_status_code() const { >@@ -159,10 +192,10 @@ public: > } > private: > /// Helper function for consume. Process response line >- void process(std::string::iterator begin, std::string::iterator end); >+ lib::error_code process(std::string::iterator begin, std::string::iterator end); > > /// Helper function for processing body bytes >- size_t process_body(char const * buf, size_t len); >+ size_t process_body(char const * buf, size_t len, lib::error_code & ec); > > enum state { > RESPONSE_LINE = 0, >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/impl/connection_impl.hpp websocketpp-hingobway/websocketpp/impl/connection_impl.hpp >--- websocketpp-zaphoyd/websocketpp/impl/connection_impl.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/impl/connection_impl.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -220,6 +220,7 @@ void connection<config>::ping(std::strin > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template<typename config> > void connection<config>::ping(std::string const & payload) { > lib::error_code ec; >@@ -228,6 +229,7 @@ void connection<config>::ping(std::strin > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > template<typename config> > void connection<config>::handle_pong_timeout(std::string payload, >@@ -291,6 +293,7 @@ void connection<config>::pong(std::strin > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template<typename config> > void connection<config>::pong(std::string const & payload) { > lib::error_code ec; >@@ -299,6 +302,7 @@ void connection<config>::pong(std::strin > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > template <typename config> > void connection<config>::close(close::status::value const code, >@@ -322,6 +326,7 @@ void connection<config>::close(close::st > ec = this->send_close_frame(code,tr,false,close::status::terminal(code)); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template<typename config> > void connection<config>::close(close::status::value const code, > std::string const & reason) >@@ -332,6 +337,7 @@ void connection<config>::close(close::st > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > /// Trigger the on_interrupt handler > /** >@@ -474,6 +480,7 @@ void connection<config>::add_subprotocol > m_requested_subprotocols.push_back(value); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::add_subprotocol(std::string const & value) { > lib::error_code ec; >@@ -482,6 +489,7 @@ void connection<config>::add_subprotocol > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > > template <typename config> >@@ -510,8 +518,10 @@ void connection<config>::select_subproto > } > > m_subprotocol = value; >+ ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::select_subprotocol(std::string const & value) { > lib::error_code ec; >@@ -520,6 +530,7 @@ void connection<config>::select_subproto > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > > template <typename config> >@@ -540,112 +551,203 @@ connection<config>::get_response_header( > return m_response.get_header(key); > } > >-// TODO: EXCEPTION_FREE >+template <typename config> >+void connection<config>::set_status(http::status_code::value code, >+ lib::error_code & ec) >+{ >+ if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { >+ ec = error::make_error_code(error::invalid_state); >+ return; >+ } >+ ec = m_response.set_status(code); >+} >+ >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::set_status(http::status_code::value code) > { >+ lib::error_code ec; >+ this->set_status(code, ec); >+ if (ec) { >+ throw exception("Call to set_status from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+template <typename config> >+void connection<config>::set_status(http::status_code::value code, >+ std::string const & msg, lib::error_code & ec) >+{ > if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { >- throw exception("Call to set_status from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); >+ return; > } >- m_response.set_status(code); >+ >+ ec = m_response.set_status(code,msg); > } > >-// TODO: EXCEPTION_FREE >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::set_status(http::status_code::value code, > std::string const & msg) > { >+ lib::error_code ec; >+ this->set_status(code, msg); >+ if (ec) { >+ throw exception("Call to set_status from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+template <typename config> >+void connection<config>::set_body(std::string const & value, >+ lib::error_code & ec) >+{ > if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { >- throw exception("Call to set_status from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); >+ return; > } > >- m_response.set_status(code,msg); >+ ec = m_response.set_body(value); > } > >-// TODO: EXCEPTION_FREE >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::set_body(std::string const & value) { >+ lib::error_code ec; >+ this->set_body(value, ec); >+ if (ec) { >+ throw exception("Call to set_body from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ >+template <typename config> >+void connection<config>::set_body(std::string && value, >+ lib::error_code & ec) >+{ > if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { >- throw exception("Call to set_status from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); >+ return; > } > >- m_response.set_body(value); >+ ec = m_response.set_body(std::move(value)); > } > >-// TODO: EXCEPTION_FREE >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+template <typename config> >+void connection<config>::set_body(std::string && value) { >+ lib::error_code ec; >+ this->set_body(std::move(value), ec); >+ if (ec) { >+ throw exception("Call to set_body from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+#endif // _WEBSOCKETPP_MOVE_SEMANTICS_ >+ > template <typename config> > void connection<config>::append_header(std::string const & key, >- std::string const & val) >+ std::string const & val, lib::error_code & ec) > { > if (m_is_server) { > if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { > // we are setting response headers for an incoming server connection >- m_response.append_header(key,val); >+ ec = m_response.append_header(key, val); > } else { >- throw exception("Call to append_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } else { > if (m_internal_state == istate::USER_INIT) { > // we are setting initial headers for an outgoing client connection >- m_request.append_header(key,val); >+ ec = m_request.append_header(key, val); > } else { >- throw exception("Call to append_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } > } > >-// TODO: EXCEPTION_FREE >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> >-void connection<config>::replace_header(std::string const & key, >+void connection<config>::append_header(std::string const & key, > std::string const & val) > { >+ lib::error_code ec; >+ this->append_header(key, val, ec); >+ if (ec) { >+ throw exception("Call to append_header from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+template <typename config> >+void connection<config>::replace_header(std::string const & key, >+ std::string const & val, lib::error_code & ec) >+{ > if (m_is_server) { > if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { > // we are setting response headers for an incoming server connection >- m_response.replace_header(key,val); >+ ec = m_response.replace_header(key, val); > } else { >- throw exception("Call to replace_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } else { > if (m_internal_state == istate::USER_INIT) { > // we are setting initial headers for an outgoing client connection >- m_request.replace_header(key,val); >+ ec = m_request.replace_header(key, val); > } else { >- throw exception("Call to replace_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } > } > >-// TODO: EXCEPTION_FREE >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> >-void connection<config>::remove_header(std::string const & key) >+void connection<config>::replace_header(std::string const & key, >+ std::string const & val) >+{ >+ lib::error_code ec; >+ this->replace_header(key, val, ec); >+ if (ec) { >+ throw exception("Call to replace_header from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ >+template <typename config> >+void connection<config>::remove_header(std::string const & key, >+ lib::error_code & ec) > { > if (m_is_server) { > if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { > // we are setting response headers for an incoming server connection >- m_response.remove_header(key); >+ ec = m_response.remove_header(key); > } else { >- throw exception("Call to remove_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } else { > if (m_internal_state == istate::USER_INIT) { > // we are setting initial headers for an outgoing client connection >- m_request.remove_header(key); >+ ec = m_request.remove_header(key); > } else { >- throw exception("Call to remove_header from invalid state", >- error::make_error_code(error::invalid_state)); >+ ec = error::make_error_code(error::invalid_state); > } > } > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+template <typename config> >+void connection<config>::remove_header(std::string const & key) >+{ >+ lib::error_code ec; >+ this->remove_header(key, ec); >+ if (ec) { >+ throw exception("Call to remove_header from invalid state", ec); >+ } >+} >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ >+ > /// Defer HTTP Response until later > /** > * Used in the http handler to defer the HTTP response for this connection >@@ -698,6 +800,7 @@ void connection<config>::send_http_respo > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > template <typename config> > void connection<config>::send_http_response() { > lib::error_code ec; >@@ -706,6 +809,7 @@ void connection<config>::send_http_respo > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > > >@@ -848,12 +952,14 @@ void connection<config>::handle_read_han > } > > size_t bytes_processed = 0; >- try { >- bytes_processed = m_request.consume(m_buf,bytes_transferred); >- } catch (http::exception &e) { >- // All HTTP exceptions will result in this request failing and an error >+ lib::error_code consume_ec; >+ >+ bytes_processed = m_request.consume(m_buf, bytes_transferred, consume_ec); >+ if (consume_ec) { >+ // All HTTP errors will result in this request failing and an error > // response being returned. No more bytes will be read in this con. >- m_response.set_status(e.m_error_code,e.m_error_msg); >+ m_response.set_status(http::error::get_status_code(http::error::value(consume_ec.value()))); >+ log_err(log::elevel::fatal,"Fatal error reading request: ",consume_ec); > this->write_http_response_error(error::make_error_code(error::http_parse_error)); > return; > } >@@ -925,6 +1031,15 @@ void connection<config>::handle_read_han > this->write_http_response(handshake_ec); > } > } else { >+ // The HTTP parser reported that it was not ready and wants more data. >+ // Assert that it actually consumed all the data present before overwriting >+ // the buffer. This should always be the case. >+ if (bytes_transferred != bytes_processed) { >+ m_elog->write(log::elevel::fatal,"Assertion Failed: HTTP request parser failed to consume all bytes from a read request."); >+ this->terminate(make_error_code(error::general)); >+ return; >+ } >+ > // read at least 1 more byte > transport_con_type::async_read_at_least( > 1, >@@ -1197,7 +1312,7 @@ lib::error_code connection<config>::proc > return error::make_error_code(error::http_connection_ended); > } > } else { >- set_status(http::status_code::upgrade_required); >+ m_response.set_status(http::status_code::upgrade_required); > return error::make_error_code(error::upgrade_required); > } > >@@ -1302,6 +1417,7 @@ void connection<config>::write_http_resp > } > > if (m_response.get_status_code() == http::status_code::uninitialized) { >+ lib::error_code status_ec; > m_response.set_status(http::status_code::internal_server_error); > m_ec = error::make_error_code(error::general); > } else { >@@ -1583,12 +1699,15 @@ void connection<config>::handle_read_htt > } > > size_t bytes_processed = 0; >- // TODO: refactor this to use error codes rather than exceptions >- try { >- bytes_processed = m_response.consume(m_buf,bytes_transferred); >- } catch (http::exception & e) { >- m_elog->write(log::elevel::rerror, >- std::string("error in handle_read_http_response: ")+e.what()); >+ >+ lib::error_code consume_ec; >+ >+ bytes_processed = m_response.consume(m_buf, bytes_transferred, consume_ec); >+ if (consume_ec) { >+ // An HTTP error while reading a response doesn't give us many options other than log >+ // and terminate. >+ m_response.set_status(http::error::get_status_code(http::error::value(consume_ec.value()))); >+ log_err(log::elevel::rerror,"error in handle_read_http_response: ",consume_ec); > this->terminate(make_error_code(error::general)); > return; > } >@@ -1648,6 +1767,15 @@ void connection<config>::handle_read_htt > > this->handle_read_frame(lib::error_code(), m_buf_cursor); > } else { >+ // The HTTP parser reported that it was not ready and wants more data. >+ // Assert that it actually consumed all the data present before overwriting >+ // the buffer. This should always be the case. >+ if (bytes_transferred != bytes_processed) { >+ m_elog->write(log::elevel::fatal,"Assertion Failed: HTTP response parser failed to consume all bytes from a read request."); >+ this->terminate(make_error_code(error::general)); >+ return; >+ } >+ > transport_con_type::async_read_at_least( > 1, > m_buf, >@@ -1706,6 +1834,12 @@ void connection<config>::terminate(lib:: > m_handshake_timer.reset(); > } > >+ // Cancel ping timer >+ if (m_ping_timer) { >+ m_ping_timer->cancel(); >+ m_handshake_timer.reset(); >+ } >+ > terminate_status tstat = unknown; > if (ec) { > m_ec = ec; >@@ -1779,13 +1913,18 @@ void connection<config>::handle_terminat > // call the termination handler if it exists > // if it exists it might (but shouldn't) refer to a bad memory location. > // If it does, we don't care and should catch and ignore it. >+ // todo: there has to be a better way to do this. > if (m_termination_handler) { >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > try { > m_termination_handler(type::get_shared()); > } catch (std::exception const & e) { > m_elog->write(log::elevel::warn, > std::string("termination_handler call failed. Reason was: ")+e.what()); > } >+#else >+ m_termination_handler(type::get_shared()); >+#endif > } > } > >@@ -1968,12 +2107,12 @@ void connection<config>::process_control > } > } > } else if (op == frame::opcode::PONG) { >- if (m_pong_handler) { >- m_pong_handler(m_connection_hdl, msg->get_payload()); >- } > if (m_ping_timer) { > m_ping_timer->cancel(); > } >+ if (m_pong_handler) { >+ m_pong_handler(m_connection_hdl, msg->get_payload()); >+ } > } else if (op == frame::opcode::CLOSE) { > m_alog->write(log::alevel::devel,"got close frame"); > // record close code and reason somewhere >@@ -2123,6 +2262,13 @@ lib::error_code connection<config>::send > > m_state = session::state::closing; > >+ // Cancel any outstanding ping timers. Once we are in state closing the >+ // library no longer processes non-close frames, so any pongs will be >+ // dropped. >+ if (m_ping_timer) { >+ m_ping_timer->cancel(); >+ } >+ > if (ack) { > m_was_clean = true; > } >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/impl/endpoint_impl.hpp websocketpp-hingobway/websocketpp/impl/endpoint_impl.hpp >--- websocketpp-zaphoyd/websocketpp/impl/endpoint_impl.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/impl/endpoint_impl.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -34,7 +34,7 @@ namespace websocketpp { > > template <typename connection, typename config> > typename endpoint<connection,config>::connection_ptr >-endpoint<connection,config>::create_connection() { >+endpoint<connection,config>::create_connection(lib::error_code & ec) { > m_alog->write(log::alevel::devel,"create_connection"); > //scoped_lock_type lock(m_state_lock); > >@@ -81,8 +81,6 @@ endpoint<connection,config>::create_conn > } > con->set_max_http_body_size(m_max_http_body_size); > >- lib::error_code ec; >- > ec = transport_type::init(con); > if (ec) { > m_elog->write(log::elevel::fatal,ec.message()); >@@ -104,13 +102,6 @@ void endpoint<connection,config>::interr > } > > template <typename connection, typename config> >-void endpoint<connection,config>::interrupt(connection_hdl hdl) { >- lib::error_code ec; >- interrupt(hdl,ec); >- if (ec) { throw exception(ec); } >-} >- >-template <typename connection, typename config> > void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec) > { > connection_ptr con = get_con_from_hdl(hdl,ec); >@@ -120,13 +111,6 @@ void endpoint<connection,config>::pause_ > } > > template <typename connection, typename config> >-void endpoint<connection,config>::pause_reading(connection_hdl hdl) { >- lib::error_code ec; >- pause_reading(hdl,ec); >- if (ec) { throw exception(ec); } >-} >- >-template <typename connection, typename config> > void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec) > { > connection_ptr con = get_con_from_hdl(hdl,ec); >@@ -136,13 +120,6 @@ void endpoint<connection,config>::resume > } > > template <typename connection, typename config> >-void endpoint<connection,config>::resume_reading(connection_hdl hdl) { >- lib::error_code ec; >- resume_reading(hdl,ec); >- if (ec) { throw exception(ec); } >-} >- >-template <typename connection, typename config> > void endpoint<connection,config>::send_http_response(connection_hdl hdl, > lib::error_code & ec) > { >@@ -152,13 +129,6 @@ void endpoint<connection,config>::send_h > } > > template <typename connection, typename config> >-void endpoint<connection,config>::send_http_response(connection_hdl hdl) { >- lib::error_code ec; >- send_http_response(hdl,ec); >- if (ec) { throw exception(ec); } >-} >- >-template <typename connection, typename config> > void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload, > frame::opcode::value op, lib::error_code & ec) > { >@@ -169,15 +139,6 @@ void endpoint<connection,config>::send(c > } > > template <typename connection, typename config> >-void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload, >- frame::opcode::value op) >-{ >- lib::error_code ec; >- send(hdl,payload,op,ec); >- if (ec) { throw exception(ec); } >-} >- >-template <typename connection, typename config> > void endpoint<connection,config>::send(connection_hdl hdl, void const * payload, > size_t len, frame::opcode::value op, lib::error_code & ec) > { >@@ -187,73 +148,113 @@ void endpoint<connection,config>::send(c > } > > template <typename connection, typename config> >-void endpoint<connection,config>::send(connection_hdl hdl, void const * payload, >- size_t len, frame::opcode::value op) >+void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg, >+ lib::error_code & ec) > { >- lib::error_code ec; >- send(hdl,payload,len,op,ec); >- if (ec) { throw exception(ec); } >+ connection_ptr con = get_con_from_hdl(hdl,ec); >+ if (ec) {return;} >+ ec = con->send(msg); > } > > template <typename connection, typename config> >-void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg, >+void endpoint<connection,config>::close(connection_hdl hdl, close::status::value >+ const code, std::string const & reason, > lib::error_code & ec) > { > connection_ptr con = get_con_from_hdl(hdl,ec); > if (ec) {return;} >- ec = con->send(msg); >+ con->close(code,reason,ec); > } > > template <typename connection, typename config> >-void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) { >- lib::error_code ec; >- send(hdl,msg,ec); >- if (ec) { throw exception(ec); } >+void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & >+ payload, lib::error_code & ec) >+{ >+ connection_ptr con = get_con_from_hdl(hdl,ec); >+ if (ec) {return;} >+ con->ping(payload,ec); > } > > template <typename connection, typename config> >-void endpoint<connection,config>::close(connection_hdl hdl, close::status::value >- const code, std::string const & reason, >+void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload, > lib::error_code & ec) > { > connection_ptr con = get_con_from_hdl(hdl,ec); > if (ec) {return;} >- con->close(code,reason,ec); >+ con->pong(payload,ec); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+// If exceptions are enabled, define wrapper methods that throw exceptions >+ > template <typename connection, typename config> >-void endpoint<connection,config>::close(connection_hdl hdl, close::status::value >- const code, std::string const & reason) >+void endpoint<connection,config>::interrupt(connection_hdl hdl) { >+ lib::error_code ec; >+ interrupt(hdl,ec); >+ if (ec) { throw exception(ec); } >+} >+ >+template <typename connection, typename config> >+void endpoint<connection,config>::pause_reading(connection_hdl hdl) { >+ lib::error_code ec; >+ pause_reading(hdl,ec); >+ if (ec) { throw exception(ec); } >+} >+ >+template <typename connection, typename config> >+void endpoint<connection,config>::resume_reading(connection_hdl hdl) { >+ lib::error_code ec; >+ resume_reading(hdl,ec); >+ if (ec) { throw exception(ec); } >+} >+ >+template <typename connection, typename config> >+void endpoint<connection,config>::send_http_response(connection_hdl hdl) { >+ lib::error_code ec; >+ send_http_response(hdl,ec); >+ if (ec) { throw exception(ec); } >+} >+ >+template <typename connection, typename config> >+void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload, >+ frame::opcode::value op) > { > lib::error_code ec; >- close(hdl,code,reason,ec); >+ send(hdl,payload,op,ec); > if (ec) { throw exception(ec); } > } > > template <typename connection, typename config> >-void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & >- payload, lib::error_code & ec) >+void endpoint<connection,config>::send(connection_hdl hdl, void const * payload, >+ size_t len, frame::opcode::value op) > { >- connection_ptr con = get_con_from_hdl(hdl,ec); >- if (ec) {return;} >- con->ping(payload,ec); >+ lib::error_code ec; >+ send(hdl,payload,len,op,ec); >+ if (ec) { throw exception(ec); } > } > > template <typename connection, typename config> >-void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload) >+void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) { >+ lib::error_code ec; >+ send(hdl,msg,ec); >+ if (ec) { throw exception(ec); } >+} >+ >+template <typename connection, typename config> >+void endpoint<connection,config>::close(connection_hdl hdl, close::status::value >+ const code, std::string const & reason) > { > lib::error_code ec; >- ping(hdl,payload,ec); >+ close(hdl,code,reason,ec); > if (ec) { throw exception(ec); } > } > > template <typename connection, typename config> >-void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload, >- lib::error_code & ec) >+void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload) > { >- connection_ptr con = get_con_from_hdl(hdl,ec); >- if (ec) {return;} >- con->pong(payload,ec); >+ lib::error_code ec; >+ ping(hdl,payload,ec); >+ if (ec) { throw exception(ec); } > } > > template <typename connection, typename config> >@@ -263,6 +264,7 @@ void endpoint<connection,config>::pong(c > pong(hdl,payload,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > } // namespace websocketpp > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/impl/utilities_impl.hpp websocketpp-hingobway/websocketpp/impl/utilities_impl.hpp >--- websocketpp-zaphoyd/websocketpp/impl/utilities_impl.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/impl/utilities_impl.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -34,33 +34,19 @@ > namespace websocketpp { > namespace utility { > >-inline std::string to_lower(std::string const & in) { >- std::string out = in; >- std::transform(out.begin(),out.end(),out.begin(),::tolower); >- return out; >-} >- > inline std::string to_hex(std::string const & input) { >- std::string output; >- std::string hex = "0123456789ABCDEF"; >- >- for (size_t i = 0; i < input.size(); i++) { >- output += hex[(input[i] & 0xF0) >> 4]; >- output += hex[input[i] & 0x0F]; >- output += " "; >- } >- >- return output; >+ return to_hex(input.c_str(), input.size()); > } > > inline std::string to_hex(uint8_t const * input, size_t length) { > std::string output; >- std::string hex = "0123456789ABCDEF"; >+ output.reserve(length * 3); >+ char const * hex = "0123456789ABCDEF"; > > for (size_t i = 0; i < length; i++) { > output += hex[(input[i] & 0xF0) >> 4]; > output += hex[input[i] & 0x0F]; >- output += " "; >+ output += ' '; > } > > return output; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/logger/basic.hpp websocketpp-hingobway/websocketpp/logger/basic.hpp >--- websocketpp-zaphoyd/websocketpp/logger/basic.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/logger/basic.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -58,33 +58,33 @@ namespace log { > template <typename concurrency, typename names> > class basic { > public: >- basic<concurrency,names>(channel_type_hint::value h = >+ basic(channel_type_hint::value h = > channel_type_hint::access) > : m_static_channels(0xffffffff) > , m_dynamic_channels(0) > , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {} > >- basic<concurrency,names>(std::ostream * out) >+ basic(std::ostream * out) > : m_static_channels(0xffffffff) > , m_dynamic_channels(0) > , m_out(out) {} > >- basic<concurrency,names>(level c, channel_type_hint::value h = >+ basic(level c, channel_type_hint::value h = > channel_type_hint::access) > : m_static_channels(c) > , m_dynamic_channels(0) > , m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {} > >- basic<concurrency,names>(level c, std::ostream * out) >+ basic(level c, std::ostream * out) > : m_static_channels(c) > , m_dynamic_channels(0) > , m_out(out) {} > > /// Destructor >- ~basic<concurrency,names>() {} >+ ~basic() {} > > /// Copy constructor >- basic<concurrency,names>(basic<concurrency,names> const & other) >+ basic(basic<concurrency,names> const & other) > : m_static_channels(other.m_static_channels) > , m_dynamic_channels(other.m_dynamic_channels) > , m_out(other.m_out) >@@ -97,7 +97,7 @@ public: > > #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ > /// Move constructor >- basic<concurrency,names>(basic<concurrency,names> && other) >+ basic(basic<concurrency,names> && other) > : m_static_channels(other.m_static_channels) > , m_dynamic_channels(other.m_dynamic_channels) > , m_out(other.m_out) >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/processors/hybi00.hpp websocketpp-hingobway/websocketpp/processors/hybi00.hpp >--- websocketpp-zaphoyd/websocketpp/processors/hybi00.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/processors/hybi00.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -435,7 +435,7 @@ private: > reinterpret_cast<char*>(&num)+4, > result); > } else { >- std::fill(result,result+4,0); >+ std::fill(result,result+4,static_cast<char>(0)); > } > } > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/processors/hybi13.hpp websocketpp-hingobway/websocketpp/processors/hybi13.hpp >--- websocketpp-zaphoyd/websocketpp/processors/hybi13.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/processors/hybi13.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -555,7 +555,7 @@ public: > std::fill_n( > m_extended_header.bytes, > frame::MAX_EXTENDED_HEADER_LENGTH, >- 0x00 >+ static_cast<uint8_t>(0x00) > ); > } > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/roles/client_endpoint.hpp websocketpp-hingobway/websocketpp/roles/client_endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/roles/client_endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/roles/client_endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -92,10 +92,14 @@ public: > return connection_ptr(); > } > >- connection_ptr con = endpoint_type::create_connection(); >+ connection_ptr con = endpoint_type::create_connection(ec); > > if (!con) { >- ec = error::make_error_code(error::con_creation_failed); >+ // if the transport doesn't have a more specific error, set >+ // a generic one. >+ if (!ec) { >+ ec = error::make_error_code(error::con_creation_failed); >+ } > return con; > } > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/roles/server_endpoint.hpp websocketpp-hingobway/websocketpp/roles/server_endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/roles/server_endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/roles/server_endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -64,6 +64,9 @@ public: > /// Type of the endpoint component of this server > typedef endpoint<connection_type,config> endpoint_type; > >+ /// The type and signature of the callback passed to the start_accept method >+ typedef lib::function<void(lib::error_code const &, lib::error_code const &)> accept_loop_handler; >+ > friend class connection<config>; > > explicit server() : endpoint_type(true) >@@ -72,11 +75,11 @@ public: > } > > /// Destructor >- ~server<config>() {} >+ ~server() {} > > #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ > // no copy constructor because endpoints are not copyable >- server<config>(server<config> &) = delete; >+ server(server<config> &) = delete; > > // no copy assignment operator because endpoints are not copyable > server<config> & operator=(server<config> const &) = delete; >@@ -84,7 +87,7 @@ public: > > #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ > /// Move constructor >- server<config>(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {} >+ server(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {} > > #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ > // no move assignment operator because of const member variables >@@ -101,21 +104,55 @@ public: > * Note: The connection must either be started or terminated using > * connection::terminate in order to avoid memory leaks. > * >+ * @deprecated 0.9.0 use `get_connection(lib::error_code &)` instead. >+ * >+ * @see `get_connection(lib::error_code &)` for an alternative that >+ * returns a detailed error code on failure. >+ * > * @return A pointer to the new connection. > */ > connection_ptr get_connection() { >- return endpoint_type::create_connection(); >+ lib::error_code ec; >+ return endpoint_type::create_connection(ec); >+ } >+ >+ /// Create and initialize a new connection >+ /** >+ * The connection will be initialized and ready to begin. Call its start() >+ * method to begin the processing loop. >+ * >+ * Note: The connection must either be started or terminated using >+ * connection::terminate in order to avoid memory leaks. >+ * >+ * @since 0.9.0 >+ * >+ * @param [out] ec A status code that indicates why the failure occurred >+ * if the returned pointer is blank. >+ * @return A pointer to the new connection. >+ */ >+ connection_ptr get_connection(lib::error_code & ec) { >+ return endpoint_type::create_connection(ec); > } > > /// Starts the server's async connection acceptance loop (exception free) > /** > * Initiates the server connection acceptance loop. Must be called after >- * listen. This method will have no effect until the underlying io_service >- * starts running. It may be called after the io_service is already running. >+ * listen. This method will have no effect until the underlying io_context >+ * starts running. It may be called after the io_context is already running. > * > * Refer to documentation for the transport policy you are using for > * instructions on how to stop this acceptance loop. >+ * >+ * Error handling: >+ * start_accept will return an error via the `ec` parameter if there is a >+ * problem starting the accept loop. Once successfully started the loop will >+ * continue to renew itself after each connection. This method has no way of >+ * delivering that happen after the loop is started. Use >+ * `start_accept(accept_loop_handler)` instead to get full error information >+ * no matter when the async loop ends. > * >+ * @deprecated use `start_accept(accept_loop_handler) instead >+ * > * @param [out] ec A status code indicating an error, if any. > */ > void start_accept(lib::error_code & ec) { >@@ -125,7 +162,7 @@ public: > } > > ec = lib::error_code(); >- connection_ptr con = get_connection(); >+ connection_ptr con = get_connection(ec); > > if (!con) { > ec = error::make_error_code(error::con_creation_failed); >@@ -134,7 +171,7 @@ public: > > transport_type::async_accept( > lib::static_pointer_cast<transport_con_type>(con), >- lib::bind(&type::handle_accept,this,con,lib::placeholders::_1), >+ lib::bind(&type::handle_accept_legacy,this,con,lib::placeholders::_1), > ec > ); > >@@ -145,14 +182,95 @@ public: > } > } > >- /// Starts the server's async connection acceptance loop >+ /// Starts the server's async connection acceptance loop (exception free) > /** >- * Initiates the server connection acceptance loop. Must be called after >- * listen. This method will have no effect until the underlying io_service >- * starts running. It may be called after the io_service is already running. >+ * Initiates the server connection acceptance loop. Requires a transport >+ * policy that supports an asyncronous listen+accept loop. Must be called >+ * while the endpoint is listening (or start_accept will return immediately >+ * with an error that the server is not listening). >+ * >+ * Consult the documentation for the underlying transport for information >+ * about exactly when this code will start running, when in the transport >+ * event loop it makes sense to call it, and for instructions on how to >+ * stop this acceptance loop. > * >- * Refer to documentation for the transport policy you are using for >- * instructions on how to stop this acceptance loop. >+ * Error handling: >+ * start_accept will attempt to start an asyncronous acceptance loop that >+ * accepts a connection and then re-issues a new accept command. If this loop >+ * ends or fails for any reason (including immediately) the `completion_handler` >+ * will be called with two status codes. The first is the library level status >+ * code the second is the underlying transport status code (if any). >+ * >+ * @since 0.9.0 >+ * >+ * @param completion_handler A handler function to be called when the async >+ * accept loop ends. >+ */ >+ void start_accept(accept_loop_handler completion_handler) { >+ // This check will happen again in async_accept but if we do it here we can >+ // avoid setting up and tearing down a connection if we know that we can't >+ // actually accept a connection. >+ if (!transport_type::is_listening()) { >+ completion_handler(error::make_error_code(error::transport_error), >+ error::make_error_code(error::async_accept_not_listening)); >+ return; >+ } >+ >+ lib::error_code tec; >+ connection_ptr con = get_connection(tec); >+ >+ if (!con) { >+ completion_handler(error::make_error_code(error::con_creation_failed),tec); >+ return; >+ } >+ >+ transport_type::async_accept( >+ lib::static_pointer_cast<transport_con_type>(con), >+ lib::bind(&type::handle_accept,this, >+ con, >+ completion_handler, >+ lib::placeholders::_1), >+ tec >+ ); >+ >+ if (tec) { >+ if (con) { >+ // If the connection was constructed but the accept failed, >+ // terminate the connection to prevent memory leaks. >+ con->terminate(lib::error_code()); >+ } >+ >+ endpoint_type::m_elog->write(log::elevel::rerror, >+ "Async_accept failed: "+tec.message()); >+ >+ // let the end user know about the error >+ completion_handler(error::make_error_code(error::transport_error),tec); >+ } >+ } >+ >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// Starts the server's async connection acceptance loop (exception) >+ /** >+ * Initiates the server connection acceptance loop. Requires a transport >+ * policy that supports an asyncronous listen+accept loop. Must be called >+ * while the endpoint is listening (or start_accept will return immediately >+ * with an error that the server is not listening). >+ * >+ * Consult the documentation for the underlying transport for information >+ * about exactly when this code will start running, when in the transport >+ * event loop it makes sense to call it, and for instructions on how to >+ * stop this acceptance loop. >+ * >+ * Error handling: >+ * start_accept will throw an exception if there is a problem starting the >+ * accept loop. Once successfully started the loop will continue to renew >+ * itself after each connection. This method has no way of delivering that >+ * happen after the loop is started. Use `start_accept(accept_loop_handler)` >+ * instead to get full error information no matter when the async loop ends. >+ * >+ * @deprecated use `start_accept(accept_loop_handler)` instead >+ * >+ * @exception websocketpp::exception If the accept loop fails to be set up. > */ > void start_accept() { > lib::error_code ec; >@@ -161,9 +279,10 @@ public: > throw exception(ec); > } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > >- /// Handler callback for start_accept >- void handle_accept(connection_ptr con, lib::error_code const & ec) { >+ /// Handler callback for start_accept (deprecated) >+ void handle_accept_legacy(connection_ptr con, lib::error_code const & ec) { > if (ec) { > con->terminate(ec); > >@@ -188,6 +307,37 @@ public: > "Restarting async_accept loop failed: "+ec.message()); > } > } >+ >+ /// Handler callback for start_accept >+ void handle_accept(connection_ptr con, >+ accept_loop_handler completion_handler, >+ lib::error_code const & tec) >+ { >+ // deal with the newly accepted connection >+ if (tec) { >+ // terminate the connection and pass the transport error >+ // code along >+ con->terminate(tec); >+ >+ // log the transport error before restarting the loop >+ if (tec == error::operation_canceled) { >+ endpoint_type::m_elog->write(log::elevel::info, >+ "handle_accept error: "+tec.message()); >+ } else { >+ endpoint_type::m_elog->write(log::elevel::rerror, >+ "handle_accept error: "+tec.message()); >+ } >+ } else { >+ con->start(); >+ } >+ >+ // todo: are there any `tec` codes that should prompt us to end >+ // without restarting the loop? >+ >+ // attempt to restart the async accept loop for the next connection >+ // this method will deliver any errors via the completion_handler >+ start_accept(completion_handler); >+ } > }; > > } // namespace websocketpp >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/sha1/sha1.hpp websocketpp-hingobway/websocketpp/sha1/sha1.hpp >--- websocketpp-zaphoyd/websocketpp/sha1/sha1.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/sha1/sha1.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -36,6 +36,8 @@ under the same license as the original, > #ifndef SHA1_DEFINED > #define SHA1_DEFINED > >+#include <cstddef> >+ > namespace websocketpp { > namespace sha1 { > >@@ -173,7 +175,7 @@ inline void calc(void const * src, size_ > innerHash(result, w); > clearWBuffert(w); > } >- w[15] = bytelength << 3; >+ w[15] = static_cast<unsigned int>(bytelength << 3); > innerHash(result, w); > > // Store hash in result pointer, and make sure we get in in the correct >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/asio/base.hpp websocketpp-hingobway/websocketpp/transport/asio/base.hpp >--- websocketpp-zaphoyd/websocketpp/transport/asio/base.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/asio/base.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -40,7 +40,7 @@ namespace websocketpp { > namespace transport { > /// Transport policy that uses asio > /** >- * This policy uses a single asio io_service to provide transport >+ * This policy uses a single asio io_context to provide transport > * services to a WebSocket++ endpoint. > */ > namespace asio { >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/asio/connection.hpp websocketpp-hingobway/websocketpp/transport/asio/connection.hpp >--- websocketpp-zaphoyd/websocketpp/transport/asio/connection.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/asio/connection.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -85,10 +85,10 @@ public: > typedef typename config::response_type response_type; > typedef typename response_type::ptr response_ptr; > >- /// Type of a pointer to the Asio io_service being used >- typedef lib::asio::io_service * io_service_ptr; >- /// Type of a pointer to the Asio io_service::strand being used >- typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr; >+ /// Type of a pointer to the Asio io_context being used >+ typedef lib::asio::io_context * io_context_ptr; >+ /// Type of a pointer to the Asio io_context::strand being used >+ typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr; > /// Type of a pointer to the Asio timer class > typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr; > >@@ -97,7 +97,7 @@ public: > // to the public api. > friend class endpoint<config>; > >- // generate and manage our own io_service >+ // generate and manage our own io_context > explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & elog) > : m_is_server(is_server) > , m_alog(alog) >@@ -194,12 +194,14 @@ public: > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > /// Set the proxy to connect through (exception) > void set_proxy(std::string const & uri) { > lib::error_code ec; > set_proxy(uri,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > /// Set the basic auth credentials to use (exception free) > /** >@@ -228,6 +230,7 @@ public: > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > /// Set the basic auth credentials to use (exception) > void set_proxy_basic_auth(std::string const & username, std::string const & > password) >@@ -236,6 +239,7 @@ public: > set_proxy_basic_auth(username,password,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > /// Set the proxy timeout duration (exception free) > /** >@@ -257,12 +261,14 @@ public: > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > /// Set the proxy timeout duration (exception) > void set_proxy_timeout(long duration) { > lib::error_code ec; > set_proxy_timeout(duration,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > std::string const & get_proxy() const { > return m_proxy; >@@ -313,12 +319,12 @@ public: > timer_ptr set_timer(long duration, timer_handler callback) { > timer_ptr new_timer( > new lib::asio::steady_timer( >- *m_io_service, >+ *m_io_context, > lib::asio::milliseconds(duration)) > ); > > if (config::enable_multithreading) { >- new_timer->async_wait(m_strand->wrap(lib::bind( >+ new_timer->async_wait(lib::asio::bind_executor(*m_strand, lib::bind( > &type::handle_timer, get_shared(), > new_timer, > callback, >@@ -393,7 +399,7 @@ public: > /// Initialize transport for reading > /** > * init_asio is called once immediately after construction to initialize >- * Asio components to the io_service >+ * Asio components to the io_context > * > * The transport initialization sequence consists of the following steps: > * - Pre-init: the underlying socket is initialized to the point where >@@ -451,21 +457,21 @@ protected: > /// Finish constructing the transport > /** > * init_asio is called once immediately after construction to initialize >- * Asio components to the io_service. >+ * Asio components to the io_context. > * >- * @param io_service A pointer to the io_service to register with this >+ * @param io_context A pointer to the io_context to register with this > * connection > * > * @return Status code for the success or failure of the initialization > */ >- lib::error_code init_asio (io_service_ptr io_service) { >- m_io_service = io_service; >+ lib::error_code init_asio (io_context_ptr io_context) { >+ m_io_context = io_context; > > if (config::enable_multithreading) { >- m_strand.reset(new lib::asio::io_service::strand(*io_service)); >+ m_strand.reset(new lib::asio::io_context::strand(*io_context)); > } > >- lib::error_code ec = socket_con_type::init_asio(io_service, m_strand, >+ lib::error_code ec = socket_con_type::init_asio(io_context, m_strand, > m_is_server); > > return ec; >@@ -573,7 +579,7 @@ protected: > lib::error_code const & ec) > { > if (ec == transport::error::operation_aborted || >- (post_timer && lib::asio::is_neg(post_timer->expires_from_now()))) >+ (post_timer && lib::asio::is_neg(post_timer->expiry() - timer_ptr::element_type::clock_type::now()))) > { > m_alog->write(log::alevel::devel,"post_init cancelled"); > return; >@@ -629,7 +635,7 @@ protected: > lib::asio::async_write( > socket_con_type::get_next_layer(), > m_bufs, >- m_strand->wrap(lib::bind( >+ lib::asio::bind_executor(*m_strand, lib::bind( > &type::handle_proxy_write, get_shared(), > callback, > lib::placeholders::_1 >@@ -679,7 +685,7 @@ protected: > // Whatever aborted it will be issuing the callback so we are safe to > // return > if (ec == lib::asio::error::operation_aborted || >- lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) >+ lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) > { > m_elog->write(log::elevel::devel,"write operation aborted"); > return; >@@ -703,7 +709,6 @@ protected: > if (!m_proxy_data) { > m_elog->write(log::elevel::library, > "assertion failed: !m_proxy_data in asio::connection::proxy_read"); >- m_proxy_data->timer->cancel(); > callback(make_error_code(error::general)); > return; > } >@@ -713,7 +718,7 @@ protected: > socket_con_type::get_next_layer(), > m_proxy_data->read_buf, > "\r\n\r\n", >- m_strand->wrap(lib::bind( >+ lib::asio::bind_executor(*m_strand, lib::bind( > &type::handle_proxy_read, get_shared(), > callback, > lib::placeholders::_1, lib::placeholders::_2 >@@ -751,7 +756,7 @@ protected: > // Whatever aborted it will be issuing the callback so we are safe to > // return > if (ec == lib::asio::error::operation_aborted || >- lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) >+ lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) > { > m_elog->write(log::elevel::devel,"read operation aborted"); > return; >@@ -772,9 +777,19 @@ protected: > return; > } > >+ // todo: switch this to using non-istream based consume > std::istream input(&m_proxy_data->read_buf); > >- m_proxy_data->res.consume(input); >+ lib::error_code istream_ec; >+ m_proxy_data->res.consume(input, istream_ec); >+ if (istream_ec) { >+ // there was an error while reading from the proxy >+ m_elog->write(log::elevel::info, >+ "An HTTP handling error occurred while reading a response from the proxy server: "+istream_ec.message()); >+ // todo: do we need to translate this error? >+ callback(istream_ec); >+ return; >+ } > > if (!m_proxy_data->res.headers_ready()) { > // we read until the headers were done in theory but apparently >@@ -841,7 +856,7 @@ protected: > socket_con_type::get_socket(), > lib::asio::buffer(buf,len), > lib::asio::transfer_at_least(num_bytes), >- m_strand->wrap(make_custom_alloc_handler( >+ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( > m_read_handler_allocator, > lib::bind( > &type::handle_async_read, get_shared(), >@@ -910,7 +925,7 @@ protected: > lib::asio::async_write( > socket_con_type::get_socket(), > m_bufs, >- m_strand->wrap(make_custom_alloc_handler( >+ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( > m_write_handler_allocator, > lib::bind( > &type::handle_async_write, get_shared(), >@@ -939,6 +954,9 @@ protected: > void async_write(std::vector<buffer> const & bufs, write_handler handler) { > std::vector<buffer>::const_iterator it; > >+ // todo: check if this underlying socket supports efficient scatter/gather io >+ // if not, coalesce buffers before we send to the underlying transport. >+ > for (it = bufs.begin(); it != bufs.end(); ++it) { > m_bufs.push_back(lib::asio::buffer((*it).buf,(*it).len)); > } >@@ -947,7 +965,7 @@ protected: > lib::asio::async_write( > socket_con_type::get_socket(), > m_bufs, >- m_strand->wrap(make_custom_alloc_handler( >+ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( > m_write_handler_allocator, > lib::bind( > &type::handle_async_write, get_shared(), >@@ -1012,18 +1030,18 @@ protected: > */ > lib::error_code interrupt(interrupt_handler handler) { > if (config::enable_multithreading) { >- m_io_service->post(m_strand->wrap(handler)); >+ lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler)); > } else { >- m_io_service->post(handler); >+ lib::asio::post(m_io_context->get_executor(), handler); > } > return lib::error_code(); > } > > lib::error_code dispatch(dispatch_handler handler) { > if (config::enable_multithreading) { >- m_io_service->post(m_strand->wrap(handler)); >+ lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler)); > } else { >- m_io_service->post(handler); >+ lib::asio::post(m_io_context->get_executor(), handler); > } > return lib::error_code(); > } >@@ -1095,7 +1113,7 @@ protected: > callback, lib::asio::error_code const & ec) > { > if (ec == lib::asio::error::operation_aborted || >- lib::asio::is_neg(shutdown_timer->expires_from_now())) >+ lib::asio::is_neg(shutdown_timer->expiry() - timer_ptr::element_type::clock_type::now())) > { > m_alog->write(log::alevel::devel,"async_shutdown cancelled"); > return; >@@ -1172,7 +1190,7 @@ private: > lib::shared_ptr<proxy_data> m_proxy_data; > > // transport resources >- io_service_ptr m_io_service; >+ io_context_ptr m_io_context; > strand_ptr m_strand; > connection_hdl m_connection_hdl; > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/asio/endpoint.hpp websocketpp-hingobway/websocketpp/transport/asio/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/transport/asio/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/asio/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -77,25 +77,25 @@ public: > /// associated with this endpoint transport component > typedef typename transport_con_type::ptr transport_con_ptr; > >- /// Type of a pointer to the ASIO io_service being used >- typedef lib::asio::io_service * io_service_ptr; >+ /// Type of a pointer to the ASIO io_context being used >+ typedef lib::asio::io_context * io_context_ptr; > /// Type of a shared pointer to the acceptor being used > typedef lib::shared_ptr<lib::asio::ip::tcp::acceptor> acceptor_ptr; > /// Type of a shared pointer to the resolver being used > typedef lib::shared_ptr<lib::asio::ip::tcp::resolver> resolver_ptr; > /// Type of timer handle > typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr; >- /// Type of a shared pointer to an io_service work object >- typedef lib::shared_ptr<lib::asio::io_service::work> work_ptr; >+ /// Type of a shared pointer to an io_context work object >+ typedef lib::shared_ptr<lib::asio::executor_work_guard<lib::asio::io_context::executor_type>> work_guard_ptr; > > /// Type of socket pre-bind handler > typedef lib::function<lib::error_code(acceptor_ptr)> tcp_pre_bind_handler; > >- // generate and manage our own io_service >+ // generate and manage our own io_context > explicit endpoint() >- : m_io_service(NULL) >- , m_external_io_service(false) >- , m_listen_backlog(lib::asio::socket_base::max_connections) >+ : m_io_context(NULL) >+ , m_external_io_context(false) >+ , m_listen_backlog(lib::asio::socket_base::max_listen_connections) > , m_reuse_addr(false) > , m_state(UNINITIALIZED) > { >@@ -103,14 +103,14 @@ public: > } > > ~endpoint() { >- // clean up our io_service if we were initialized with an internal one. >+ // clean up our io_context if we were initialized with an internal one. > > // Explicitly destroy local objects > m_acceptor.reset(); > m_resolver.reset(); >- m_work.reset(); >- if (m_state != UNINITIALIZED && !m_external_io_service) { >- delete m_io_service; >+ m_work_guard.reset(); >+ if (m_state != UNINITIALIZED && !m_external_io_context) { >+ delete m_io_context; > } > } > >@@ -132,34 +132,34 @@ public: > : config::socket_type(std::move(src)) > , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler) > , m_tcp_post_init_handler(src.m_tcp_post_init_handler) >- , m_io_service(src.m_io_service) >- , m_external_io_service(src.m_external_io_service) >+ , m_io_context(src.m_io_context) >+ , m_external_io_context(src.m_external_io_context) > , m_acceptor(src.m_acceptor) >- , m_listen_backlog(lib::asio::socket_base::max_connections) >+ , m_listen_backlog(lib::asio::socket_base::max_listen_connections) > , m_reuse_addr(src.m_reuse_addr) > , m_elog(src.m_elog) > , m_alog(src.m_alog) > , m_state(src.m_state) > { >- src.m_io_service = NULL; >- src.m_external_io_service = false; >+ src.m_io_context = NULL; >+ src.m_external_io_context = false; > src.m_acceptor = NULL; > src.m_state = UNINITIALIZED; > } > > /*endpoint & operator= (const endpoint && rhs) { > if (this != &rhs) { >- m_io_service = rhs.m_io_service; >- m_external_io_service = rhs.m_external_io_service; >+ m_io_context = rhs.m_io_context; >+ m_external_io_context = rhs.m_external_io_context; > m_acceptor = rhs.m_acceptor; > m_listen_backlog = rhs.m_listen_backlog; > m_reuse_addr = rhs.m_reuse_addr; > m_state = rhs.m_state; > >- rhs.m_io_service = NULL; >- rhs.m_external_io_service = false; >+ rhs.m_io_context = NULL; >+ rhs.m_external_io_context = false; > rhs.m_acceptor = NULL; >- rhs.m_listen_backlog = lib::asio::socket_base::max_connections; >+ rhs.m_listen_backlog = lib::asio::socket_base::max_listen_connections; > rhs.m_state = UNINITIALIZED; > > // TODO: this needs to be updated >@@ -173,16 +173,16 @@ public: > return socket_type::is_secure(); > } > >- /// initialize asio transport with external io_service (exception free) >+ /// initialize asio transport with external io_context (exception free) > /** > * Initialize the ASIO transport policy for this endpoint using the provided >- * io_service object. asio_init must be called exactly once on any endpoint >+ * io_context object. asio_init must be called exactly once on any endpoint > * that uses transport::asio before it can be used. > * >- * @param ptr A pointer to the io_service to use for asio events >+ * @param ptr A pointer to the io_context to use for asio events > * @param ec Set to indicate what error occurred, if any. > */ >- void init_asio(io_service_ptr ptr, lib::error_code & ec) { >+ void init_asio(io_context_ptr ptr, lib::error_code & ec) { > if (m_state != UNINITIALIZED) { > m_elog->write(log::elevel::library, > "asio::init_asio called from the wrong state"); >@@ -193,34 +193,36 @@ public: > > m_alog->write(log::alevel::devel,"asio::init_asio"); > >- m_io_service = ptr; >- m_external_io_service = true; >- m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service)); >+ m_io_context = ptr; >+ m_external_io_context = true; >+ m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_context)); > > m_state = READY; > ec = lib::error_code(); > } > >- /// initialize asio transport with external io_service >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// initialize asio transport with external io_context > /** > * Initialize the ASIO transport policy for this endpoint using the provided >- * io_service object. asio_init must be called exactly once on any endpoint >+ * io_context object. asio_init must be called exactly once on any endpoint > * that uses transport::asio before it can be used. > * >- * @param ptr A pointer to the io_service to use for asio events >+ * @param ptr A pointer to the io_context to use for asio events > */ >- void init_asio(io_service_ptr ptr) { >+ void init_asio(io_context_ptr ptr) { > lib::error_code ec; > init_asio(ptr,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > >- /// Initialize asio transport with internal io_service (exception free) >+ /// Initialize asio transport with internal io_context (exception free) > /** > * This method of initialization will allocate and use an internally managed >- * io_service. >+ * io_context. > * >- * @see init_asio(io_service_ptr ptr) >+ * @see init_asio(io_context_ptr ptr) > * > * @param ec Set to indicate what error occurred, if any. > */ >@@ -230,21 +232,22 @@ public: > // TODO: remove the use of auto_ptr when C++98/03 support is no longer > // necessary. > #ifdef _WEBSOCKETPP_CPP11_MEMORY_ >- lib::unique_ptr<lib::asio::io_service> service(new lib::asio::io_service()); >+ lib::unique_ptr<lib::asio::io_context> context(new lib::asio::io_context()); > #else >- lib::auto_ptr<lib::asio::io_service> service(new lib::asio::io_service()); >+ lib::auto_ptr<lib::asio::io_context> context(new lib::asio::io_context()); > #endif >- init_asio(service.get(), ec); >- if( !ec ) service.release(); // Call was successful, transfer ownership >- m_external_io_service = false; >+ init_asio(context.get(), ec); >+ if( !ec ) context.release(); // Call was successful, transfer ownership >+ m_external_io_context = false; > } > >- /// Initialize asio transport with internal io_service >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ /// Initialize asio transport with internal io_context > /** > * This method of initialization will allocate and use an internally managed >- * io_service. >+ * io_context. > * >- * @see init_asio(io_service_ptr ptr) >+ * @see init_asio(io_context_ptr ptr) > */ > void init_asio() { > // Use a smart pointer until the call is successful and ownership has >@@ -252,15 +255,16 @@ public: > // TODO: remove the use of auto_ptr when C++98/03 support is no longer > // necessary. > #ifdef _WEBSOCKETPP_CPP11_MEMORY_ >- lib::unique_ptr<lib::asio::io_service> service(new lib::asio::io_service()); >+ lib::unique_ptr<lib::asio::io_context> context(new lib::asio::io_context()); > #else >- lib::auto_ptr<lib::asio::io_service> service(new lib::asio::io_service()); >+ lib::auto_ptr<lib::asio::io_context> context(new lib::asio::io_context()); > #endif >- init_asio( service.get() ); >+ init_asio( context.get() ); > // If control got this far without an exception, then ownership has successfully been taken >- service.release(); >- m_external_io_service = false; >+ context.release(); >+ m_external_io_context = false; > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > /// Sets the tcp pre bind handler > /** >@@ -330,7 +334,7 @@ public: > * > * New values affect future calls to listen only. > * >- * The default value is specified as *::asio::socket_base::max_connections >+ * The default value is specified as *::asio::socket_base::max_listen_connections > * which uses the operating system defined maximum queue length. Your OS > * may restrict or silently lower this value. A value of zero may cause > * all connections to be rejected. >@@ -364,19 +368,19 @@ public: > m_reuse_addr = value; > } > >- /// Retrieve a reference to the endpoint's io_service >+ /// Retrieve a reference to the endpoint's io_context > /** >- * The io_service may be an internal or external one. This may be used to >- * call methods of the io_service that are not explicitly wrapped by the >+ * The io_context may be an internal or external one. This may be used to >+ * call methods of the io_context that are not explicitly wrapped by the > * endpoint. > * > * This method is only valid after the endpoint has been initialized with > * `init_asio`. No error will be returned if it isn't. > * >- * @return A reference to the endpoint's io_service >+ * @return A reference to the endpoint's io_context > */ >- lib::asio::io_service & get_io_service() { >- return *m_io_service; >+ lib::asio::io_context & get_io_context() { >+ return *m_io_context; > } > > /// Get local TCP endpoint >@@ -449,20 +453,6 @@ public: > ec = lib::error_code(); > } > >- >- >- /// Set up endpoint for listening manually >- /** >- * Bind the internal acceptor using the settings specified by the endpoint e >- * >- * @param ep An endpoint to read settings from >- */ >- void listen(lib::asio::ip::tcp::endpoint const & ep) { >- lib::error_code ec; >- listen(ep,ec); >- if (ec) { throw exception(ec); } >- } >- > /// Set up endpoint for listening with protocol and port (exception free) > /** > * Bind the internal acceptor using the given internet protocol and port. >@@ -485,26 +475,6 @@ public: > listen(ep,ec); > } > >- /// Set up endpoint for listening with protocol and port >- /** >- * Bind the internal acceptor using the given internet protocol and port. >- * The endpoint must have been initialized by calling init_asio before >- * listening. >- * >- * Common options include: >- * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6() >- * - IPv4 only: lib::asio::ip::tcp::v4() >- * >- * @param internet_protocol The internet protocol to use. >- * @param port The port to listen on. >- */ >- template <typename InternetProtocol> >- void listen(InternetProtocol const & internet_protocol, uint16_t port) >- { >- lib::asio::ip::tcp::endpoint ep(internet_protocol, port); >- listen(ep); >- } >- > /// Set up endpoint for listening on a port (exception free) > /** > * Bind the internal acceptor using the given port. The IPv6 protocol with >@@ -521,32 +491,22 @@ public: > listen(lib::asio::ip::tcp::v6(), port, ec); > } > >- /// Set up endpoint for listening on a port >- /** >- * Bind the internal acceptor using the given port. The IPv6 protocol with >- * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use >- * the overload that allows specifying the protocol explicitly. >- * >- * The endpoint must have been initialized by calling init_asio before >- * listening. >- * >- * @param port The port to listen on. >- * @param ec Set to indicate what error occurred, if any. >- */ >- void listen(uint16_t port) { >- listen(lib::asio::ip::tcp::v6(), port); >- } >- > /// Set up endpoint for listening on a host and service (exception free) > /** > * Bind the internal acceptor using the given host and service. More details > * about what host and service can be are available in the Asio >- * documentation for ip::basic_resolver_query::basic_resolver_query's >- * constructors. >+ * documentation for the ip::basic_resolver::resolve function. > * > * The endpoint must have been initialized by calling init_asio before > * listening. > * >+ * Once listening the underlying io_context will be kept open indefinitely. >+ * Calling endpoint::stop_listening will stop the endpoint from accepting >+ * new connections. See the documentation for stop listening for more details >+ * about shutting down Asio Transport based endpoints. >+ * >+ * @see stop_listening(lib::error_code &) >+ * > * @param host A string identifying a location. May be a descriptive name or > * a numeric address string. > * @param service A string identifying the requested service. This may be a >@@ -557,46 +517,28 @@ public: > lib::error_code & ec) > { > using lib::asio::ip::tcp; >- tcp::resolver r(*m_io_service); >- tcp::resolver::query query(host, service); >- tcp::resolver::iterator endpoint_iterator = r.resolve(query); >- tcp::resolver::iterator end; >- if (endpoint_iterator == end) { >+ tcp::resolver r(*m_io_context); >+ tcp::resolver::results_type results = r.resolve(host, service); >+ if (results.empty()) { > m_elog->write(log::elevel::library, > "asio::listen could not resolve the supplied host or service"); > ec = make_error_code(error::invalid_host_service); > return; > } >- listen(*endpoint_iterator,ec); >+ listen(*(results.begin()),ec); > } > >- /// Set up endpoint for listening on a host and service >+ /// Stop listening (exception free) > /** >- * Bind the internal acceptor using the given host and service. More details >- * about what host and service can be are available in the Asio >- * documentation for ip::basic_resolver_query::basic_resolver_query's >- * constructors. >+ * Stop listening and accepting new connections. > * >- * The endpoint must have been initialized by calling init_asio before >- * listening. >+ * If the endpoint needs to shut down fully (i.e. close all connections) >+ * this member function is necessary but not sufficient. In addition to >+ * stopping listening, individual connections will need to be ended via >+ * their respective connection::close. > * >- * @param host A string identifying a location. May be a descriptive name or >- * a numeric address string. >- * @param service A string identifying the requested service. This may be a >- * descriptive name or a numeric string corresponding to a port number. >- * @param ec Set to indicate what error occurred, if any. >- */ >- void listen(std::string const & host, std::string const & service) >- { >- lib::error_code ec; >- listen(host,service,ec); >- if (ec) { throw exception(ec); } >- } >- >- /// Stop listening (exception free) >- /** >- * Stop listening and accepting new connections. This will not end any >- * existing connections. >+ * For more details on clean closing, please refer to @ref clean_close >+ * "Cleanly closing Asio Transport based endpoints" > * > * @since 0.3.0-alpha4 > * @param ec A status code indicating an error, if any. >@@ -615,6 +557,86 @@ public: > ec = lib::error_code(); > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ >+ // if exceptions are avaliable, define listen overloads that use them >+ >+ /// Set up endpoint for listening manually >+ /** >+ * Bind the internal acceptor using the settings specified by the endpoint e >+ * >+ * @param ep An endpoint to read settings from >+ */ >+ void listen(lib::asio::ip::tcp::endpoint const & ep) { >+ lib::error_code ec; >+ listen(ep,ec); >+ if (ec) { throw exception(ec); } >+ } >+ >+ /// Set up endpoint for listening with protocol and port >+ /** >+ * Bind the internal acceptor using the given internet protocol and port. >+ * The endpoint must have been initialized by calling init_asio before >+ * listening. >+ * >+ * Common options include: >+ * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6() >+ * - IPv4 only: lib::asio::ip::tcp::v4() >+ * >+ * @param internet_protocol The internet protocol to use. >+ * @param port The port to listen on. >+ */ >+ template <typename InternetProtocol> >+ void listen(InternetProtocol const & internet_protocol, uint16_t port) >+ { >+ lib::asio::ip::tcp::endpoint ep(internet_protocol, port); >+ listen(ep); >+ } >+ >+ /// Set up endpoint for listening on a port >+ /** >+ * Bind the internal acceptor using the given port. The IPv6 protocol with >+ * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use >+ * the overload that allows specifying the protocol explicitly. >+ * >+ * The endpoint must have been initialized by calling init_asio before >+ * listening. >+ * >+ * @param port The port to listen on. >+ * @param ec Set to indicate what error occurred, if any. >+ */ >+ void listen(uint16_t port) { >+ listen(lib::asio::ip::tcp::v6(), port); >+ } >+ >+ /// Set up endpoint for listening on a host and service >+ /** >+ * Bind the internal acceptor using the given host and service. More >+ * details about what host and service can be are available in the Asio >+ * documentation for the ip::basic_resolver::resolve function. >+ * >+ * The endpoint must have been initialized by calling init_asio before >+ * listening. >+ * >+ * Once listening the underlying io_context will be kept open indefinitely. >+ * Calling endpoint::stop_listening will stop the endpoint from accepting >+ * new connections. See the documentation for stop listening for more >+ * details about shutting down Asio Transport based endpoints. >+ * >+ * @see stop_listening() >+ * >+ * @param host A string identifying a location. May be a descriptive name >+ * or a numeric address string. >+ * @param service A string identifying the requested service. This may be a >+ * descriptive name or a numeric string corresponding to a port number. >+ * @param ec Set to indicate what error occurred, if any. >+ */ >+ void listen(std::string const & host, std::string const & service) >+ { >+ lib::error_code ec; >+ listen(host,service,ec); >+ if (ec) { throw exception(ec); } >+ } >+ > /// Stop listening > /** > * Stop listening and accepting new connections. This will not end any >@@ -627,6 +649,7 @@ public: > stop_listening(ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > > /// Check if the endpoint is listening > /** >@@ -636,42 +659,42 @@ public: > return (m_state == LISTENING); > } > >- /// wraps the run method of the internal io_service object >+ /// wraps the run method of the internal io_context object > std::size_t run() { >- return m_io_service->run(); >+ return m_io_context->run(); > } > >- /// wraps the run_one method of the internal io_service object >+ /// wraps the run_one method of the internal io_context object > /** > * @since 0.3.0-alpha4 > */ > std::size_t run_one() { >- return m_io_service->run_one(); >+ return m_io_context->run_one(); > } > >- /// wraps the stop method of the internal io_service object >+ /// wraps the stop method of the internal io_context object > void stop() { >- m_io_service->stop(); >+ m_io_context->stop(); > } > >- /// wraps the poll method of the internal io_service object >+ /// wraps the poll method of the internal io_context object > std::size_t poll() { >- return m_io_service->poll(); >+ return m_io_context->poll(); > } > >- /// wraps the poll_one method of the internal io_service object >+ /// wraps the poll_one method of the internal io_context object > std::size_t poll_one() { >- return m_io_service->poll_one(); >+ return m_io_context->poll_one(); > } > >- /// wraps the reset method of the internal io_service object >+ /// wraps the restart method of the internal io_context object > void reset() { >- m_io_service->reset(); >+ m_io_context->restart(); > } > >- /// wraps the stopped method of the internal io_service object >+ /// wraps the stopped method of the internal io_context object > bool stopped() const { >- return m_io_service->stopped(); >+ return m_io_context->stopped(); > } > > /// Marks the endpoint as perpetual, stopping it from exiting when empty >@@ -687,7 +710,7 @@ public: > * @since 0.3.0 > */ > void start_perpetual() { >- m_work.reset(new lib::asio::io_service::work(*m_io_service)); >+ m_work_guard.reset(new lib::asio::executor_work_guard<lib::asio::io_context::executor_type>(m_io_context->get_executor())); > } > > /// Clears the endpoint's perpetual flag, allowing it to exit when empty >@@ -699,7 +722,7 @@ public: > * @since 0.3.0 > */ > void stop_perpetual() { >- m_work.reset(); >+ m_work_guard.reset(); > } > > /// Call back a function after a period of time. >@@ -716,7 +739,7 @@ public: > */ > timer_ptr set_timer(long duration, timer_handler callback) { > timer_ptr new_timer = lib::make_shared<lib::asio::steady_timer>( >- *m_io_service, >+ *m_io_context, > lib::asio::milliseconds(duration) > ); > >@@ -779,7 +802,7 @@ public: > if (config::enable_multithreading) { > m_acceptor->async_accept( > tcon->get_raw_socket(), >- tcon->get_strand()->wrap(lib::bind( >+ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( > &type::handle_accept, > this, > callback, >@@ -799,6 +822,7 @@ public: > } > } > >+#ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ > /// Accept the next connection attempt and assign it to con. > /** > * @param tcon The connection to accept into. >@@ -809,6 +833,7 @@ public: > async_accept(tcon,callback,ec); > if (ec) { throw exception(ec); } > } >+#endif // _WEBSOCKETPP_NO_EXCEPTIONS_ > protected: > /// Initialize logging > /** >@@ -851,7 +876,7 @@ protected: > > // Create a resolver > if (!m_resolver) { >- m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service)); >+ m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_context)); > } > > tcon->set_uri(u); >@@ -883,8 +908,6 @@ protected: > port = pu->get_port_str(); > } > >- tcp::resolver::query query(host,port); >- > if (m_alog->static_test(log::alevel::devel)) { > m_alog->write(log::alevel::devel, > "starting async DNS resolve for "+host+":"+port); >@@ -905,8 +928,9 @@ protected: > > if (config::enable_multithreading) { > m_resolver->async_resolve( >- query, >- tcon->get_strand()->wrap(lib::bind( >+ host, >+ port, >+ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( > &type::handle_resolve, > this, > tcon, >@@ -918,7 +942,8 @@ protected: > ); > } else { > m_resolver->async_resolve( >- query, >+ host, >+ port, > lib::bind( > &type::handle_resolve, > this, >@@ -966,10 +991,10 @@ protected: > > void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, > connect_handler callback, lib::asio::error_code const & ec, >- lib::asio::ip::tcp::resolver::iterator iterator) >+ lib::asio::ip::tcp::resolver::results_type results) > { > if (ec == lib::asio::error::operation_aborted || >- lib::asio::is_neg(dns_timer->expires_from_now())) >+ lib::asio::is_neg(dns_timer->expiry() - timer_ptr::element_type::clock_type::now())) > { > m_alog->write(log::alevel::devel,"async_resolve cancelled"); > return; >@@ -987,8 +1012,8 @@ protected: > std::stringstream s; > s << "Async DNS resolve successful. Results: "; > >- lib::asio::ip::tcp::resolver::iterator it, end; >- for (it = iterator; it != end; ++it) { >+ lib::asio::ip::tcp::resolver::results_type::iterator it; >+ for (it = results.begin(); it != results.end(); ++it) { > s << (*it).endpoint() << " "; > } > >@@ -1014,8 +1039,8 @@ protected: > if (config::enable_multithreading) { > lib::asio::async_connect( > tcon->get_raw_socket(), >- iterator, >- tcon->get_strand()->wrap(lib::bind( >+ results, >+ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( > &type::handle_connect, > this, > tcon, >@@ -1027,7 +1052,7 @@ protected: > } else { > lib::asio::async_connect( > tcon->get_raw_socket(), >- iterator, >+ results, > lib::bind( > &type::handle_connect, > this, >@@ -1077,7 +1102,7 @@ protected: > connect_handler callback, lib::asio::error_code const & ec) > { > if (ec == lib::asio::error::operation_aborted || >- lib::asio::is_neg(con_timer->expires_from_now())) >+ lib::asio::is_neg(con_timer->expiry() - timer_ptr::element_type::clock_type::now())) > { > m_alog->write(log::alevel::devel,"async_connect cancelled"); > return; >@@ -1119,7 +1144,7 @@ protected: > > lib::error_code ec; > >- ec = tcon->init_asio(m_io_service); >+ ec = tcon->init_asio(m_io_context); > if (ec) {return ec;} > > tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler); >@@ -1158,11 +1183,11 @@ private: > tcp_init_handler m_tcp_post_init_handler; > > // Network Resources >- io_service_ptr m_io_service; >- bool m_external_io_service; >+ io_context_ptr m_io_context; >+ bool m_external_io_context; > acceptor_ptr m_acceptor; > resolver_ptr m_resolver; >- work_ptr m_work; >+ work_guard_ptr m_work_guard; > > // Network constants > int m_listen_backlog; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/asio/security/none.hpp websocketpp-hingobway/websocketpp/transport/asio/security/none.hpp >--- websocketpp-zaphoyd/websocketpp/transport/asio/security/none.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/asio/security/none.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -62,10 +62,10 @@ public: > /// Type of a shared pointer to this connection socket component > typedef lib::shared_ptr<type> ptr; > >- /// Type of a pointer to the Asio io_service being used >- typedef lib::asio::io_service* io_service_ptr; >- /// Type of a pointer to the Asio io_service strand being used >- typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr; >+ /// Type of a pointer to the Asio io_context being used >+ typedef lib::asio::io_context* io_context_ptr; >+ /// Type of a pointer to the Asio io_context strand being used >+ typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr; > /// Type of the ASIO socket being used > typedef lib::asio::ip::tcp::socket socket_type; > /// Type of a shared pointer to the socket being used. >@@ -156,23 +156,20 @@ protected: > /// Perform one time initializations > /** > * init_asio is called once immediately after construction to initialize >- * Asio components to the io_service >+ * Asio components to the io_context. At this stage the connection is >+ * speculative, the server may not have actually received a new connection. > * >- * @param service A pointer to the endpoint's io_service >+ * @param context A pointer to the endpoint's io_context > * @param strand A shared pointer to the connection's asio strand > * @param is_server Whether or not the endpoint is a server or not. > */ >- lib::error_code init_asio (io_service_ptr service, strand_ptr, bool) >+ lib::error_code init_asio (io_context_ptr context, strand_ptr, bool) > { > if (m_state != UNINITIALIZED) { > return socket::make_error_code(socket::error::invalid_state); > } > >- m_socket.reset(new lib::asio::ip::tcp::socket(*service)); >- >- if (m_socket_init_handler) { >- m_socket_init_handler(m_hdl, *m_socket); >- } >+ m_socket.reset(new lib::asio::ip::tcp::socket(*context)); > > m_state = READY; > >@@ -194,7 +191,7 @@ protected: > > /// Pre-initialize security policy > /** >- * Called by the transport after a new connection is created to initialize >+ * Called by the transport after a new connection is accepted to initialize > * the socket component of the connection. This method is not allowed to > * write any bytes to the wire. This initialization happens before any > * proxies or other intermediate wrappers are negotiated. >@@ -207,6 +204,10 @@ protected: > return; > } > >+ if (m_socket_init_handler) { >+ m_socket_init_handler(m_hdl, *m_socket); >+ } >+ > m_state = READING; > > callback(lib::error_code()); >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/asio/security/tls.hpp websocketpp-hingobway/websocketpp/transport/asio/security/tls.hpp >--- websocketpp-zaphoyd/websocketpp/transport/asio/security/tls.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/asio/security/tls.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -71,10 +71,10 @@ public: > typedef lib::asio::ssl::stream<lib::asio::ip::tcp::socket> socket_type; > /// Type of a shared pointer to the ASIO socket being used > typedef lib::shared_ptr<socket_type> socket_ptr; >- /// Type of a pointer to the ASIO io_service being used >- typedef lib::asio::io_service * io_service_ptr; >- /// Type of a pointer to the ASIO io_service strand being used >- typedef lib::shared_ptr<lib::asio::io_service::strand> strand_ptr; >+ /// Type of a pointer to the ASIO io_context being used >+ typedef lib::asio::io_context * io_context_ptr; >+ /// Type of a pointer to the ASIO io_context strand being used >+ typedef lib::shared_ptr<lib::asio::io_context::strand> strand_ptr; > /// Type of a shared pointer to the ASIO TLS context being used > typedef lib::shared_ptr<lib::asio::ssl::context> context_ptr; > >@@ -176,13 +176,13 @@ protected: > /// Perform one time initializations > /** > * init_asio is called once immediately after construction to initialize >- * Asio components to the io_service >+ * Asio components to the io_context > * >- * @param service A pointer to the endpoint's io_service >+ * @param context A pointer to the endpoint's io_context > * @param strand A pointer to the connection's strand > * @param is_server Whether or not the endpoint is a server or not. > */ >- lib::error_code init_asio (io_service_ptr service, strand_ptr strand, >+ lib::error_code init_asio (io_context_ptr context, strand_ptr strand, > bool is_server) > { > if (!m_tls_init_handler) { >@@ -193,13 +193,9 @@ protected: > if (!m_context) { > return socket::make_error_code(socket::error::invalid_tls_context); > } >- m_socket.reset(new socket_type(*service, *m_context)); >+ m_socket.reset(new socket_type(*context, *m_context)); > >- if (m_socket_init_handler) { >- m_socket_init_handler(m_hdl, get_socket()); >- } >- >- m_io_service = service; >+ m_io_context = context; > m_strand = strand; > m_is_server = is_server; > >@@ -234,19 +230,34 @@ protected: > void pre_init(init_handler callback) { > // TODO: is this the best way to check whether this function is > // available in the version of OpenSSL being used? >- // TODO: consider case where host is an IP address > #if OPENSSL_VERSION_NUMBER >= 0x90812f > if (!m_is_server) { > // For clients on systems with a suitable OpenSSL version, set the > // TLS SNI hostname header so connecting to TLS servers using SNI > // will work. >- long res = SSL_set_tlsext_host_name( >- get_socket().native_handle(), m_uri->get_host().c_str()); >- if (!(1 == res)) { >- callback(socket::make_error_code(socket::error::tls_failed_sni_hostname)); >+ std::string const & host = m_uri->get_host(); >+ lib::asio::error_code ec_addr; >+ >+ // run the hostname through make_address to check if it is a valid IP literal >+ lib::asio::ip::address addr = lib::asio::ip::make_address(host, ec_addr); >+ (void)addr; >+ >+ // If the parsing as an IP literal fails, proceed to register the hostname >+ // with the TLS handshake via SNI. >+ // The SNI applies only to DNS host names, not for IP addresses >+ // See RFC3546 Section 3.1 >+ if (ec_addr) { >+ long res = SSL_set_tlsext_host_name( >+ get_socket().native_handle(), host.c_str()); >+ if (!(1 == res)) { >+ callback(socket::make_error_code(socket::error::tls_failed_sni_hostname)); >+ } > } > } > #endif >+ if (m_socket_init_handler) { >+ m_socket_init_handler(m_hdl, get_socket()); >+ } > > callback(lib::error_code()); > } >@@ -266,7 +277,7 @@ protected: > if (m_strand) { > m_socket->async_handshake( > get_handshake_type(), >- m_strand->wrap(lib::bind( >+ lib::asio::bind_executor(*m_strand, lib::bind( > &type::handle_init, get_shared(), > callback, > lib::placeholders::_1 >@@ -326,7 +337,7 @@ protected: > > void async_shutdown(socket::shutdown_handler callback) { > if (m_strand) { >- m_socket->async_shutdown(m_strand->wrap(callback)); >+ m_socket->async_shutdown(lib::asio::bind_executor(*m_strand, callback)); > } else { > m_socket->async_shutdown(callback); > } >@@ -381,7 +392,7 @@ private: > } > } > >- io_service_ptr m_io_service; >+ io_context_ptr m_io_context; > strand_ptr m_strand; > context_ptr m_context; > socket_ptr m_socket; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/base/endpoint.hpp websocketpp-hingobway/websocketpp/transport/base/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/transport/base/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/base/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -57,11 +57,22 @@ namespace websocketpp { > * is a pointer to the transport connection component of the connection. When > * complete, `handler` should be called with the the connection's > * `connection_hdl` and any error that occurred. >+ * note: optional, client transports only > * >+ * **async_accept**\n >+ * todo: >+ * note: optional, server transports only >+ * > * **init_logging** > * `void init_logging(const lib::shared_ptr<alog_type>& a, const lib::shared_ptr<elog_type>& e)`\n > * Called once after construction to provide pointers to the endpoint's access > * and error loggers. These may be stored and used to log messages or ignored. >+ * >+ * >+ * **is_listening** >+ * `bool is_listening()` >+ * Server roles only. Called to determine if the server is listening and that calls to >+ * start_accept / async_accept are valid. > */ > namespace transport { > >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/debug/endpoint.hpp websocketpp-hingobway/websocketpp/transport/debug/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/transport/debug/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/debug/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -60,7 +60,7 @@ public: > /// associated connection transport component > typedef typename transport_con_type::ptr transport_con_ptr; > >- // generate and manage our own io_service >+ // generate and manage our own io_context > explicit endpoint() > { > //std::cout << "transport::iostream::endpoint constructor" << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/iostream/endpoint.hpp websocketpp-hingobway/websocketpp/transport/iostream/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/transport/iostream/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/iostream/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -64,7 +64,7 @@ public: > /// associated connection transport component > typedef typename transport_con_type::ptr transport_con_ptr; > >- // generate and manage our own io_service >+ // generate and manage our own io_context > explicit endpoint() : m_output_stream(NULL), m_is_secure(false) > { > //std::cout << "transport::iostream::endpoint constructor" << std::endl; >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/transport/stub/endpoint.hpp websocketpp-hingobway/websocketpp/transport/stub/endpoint.hpp >--- websocketpp-zaphoyd/websocketpp/transport/stub/endpoint.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/transport/stub/endpoint.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -60,7 +60,7 @@ public: > /// associated connection transport component > typedef typename transport_con_type::ptr transport_con_ptr; > >- // generate and manage our own io_service >+ // generate and manage our own io_context > explicit endpoint() > { > //std::cout << "transport::iostream::endpoint constructor" << std::endl; >@@ -89,6 +89,14 @@ public: > bool is_secure() const { > return false; > } >+ >+ /// Tests whether or not the transport is currently listening for new connections >+ /** >+ * Server roles only >+ */ >+ bool is_listening() const { >+ return false; >+ } > protected: > /// Initialize logging > /** >@@ -103,7 +111,7 @@ protected: > * @param a A pointer to the access logger to use. > * @param e A pointer to the error logger to use. > */ >- void init_logging(alog_type * a, elog_type * e) {} >+ void init_logging(lib::shared_ptr<alog_type>, lib::shared_ptr<elog_type>) {} > > /// Initiate a new connection > /** >@@ -116,6 +124,14 @@ protected: > cb(make_error_code(error::not_implemented)); > } > >+ /// Accept a new connection >+ /** >+ * Server roles only >+ */ >+ void async_accept(transport_con_ptr tcon, accept_handler cb, std::error_code & ec) { >+ ec = make_error_code(error::not_implemented); >+ } >+ > /// Initialize a connection > /** > * Init is called by an endpoint once for each newly created connection. >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/uri.hpp websocketpp-hingobway/websocketpp/uri.hpp >--- websocketpp-zaphoyd/websocketpp/uri.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/uri.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -46,9 +46,357 @@ static uint16_t const uri_default_port = > /// Default port for wss:// > static uint16_t const uri_default_secure_port = 443; > >+ >+ >+/// A group of helper methods for parsing and validating URIs against RFC 3986 >+namespace uri_helper { >+ >+/// RFC3986 unreserved character test >+/** >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered `unreserved` >+ */ >+inline bool unreserved(char c) { >+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { >+ return true; >+ } else if (c >= '0' && c <= '9') { >+ return true; >+ } else if (c == '-' || c == '.' || c == '_' || c == '~') { >+ return true; >+ } else { >+ return false; >+ } >+} >+ >+/// RFC3986 generic delimiter character test >+/** >+ * @param c the char to test >+ * @return True if the character is considered a generic delimiter >+ */ >+inline bool gen_delim(char c) { >+ switch(c) { >+ case ':': >+ case '/': >+ case '?': >+ case '#': >+ case '[': >+ case ']': >+ case '@': >+ return true; >+ default: >+ return false; >+ } >+} >+ >+/// RFC3986 subcomponent delimiter character test >+/** >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered a subcomponent delimiter >+ */ >+inline bool sub_delim(char c) { >+ switch(c) { >+ case '!': >+ case '$': >+ case '&': >+ case '\'': >+ case '(': >+ case ')': >+ case '*': >+ case '+': >+ case ',': >+ case ';': >+ case '=': >+ return true; >+ default: >+ return false; >+ } >+} >+ >+/// RFC3986 hex digit character test >+/** >+ * Case insensitive >+ * >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered a hexadecimal digit >+ */ >+inline bool hexdigit(char c) { >+ switch(c) { >+ case '0': >+ case '1': >+ case '2': >+ case '3': >+ case '4': >+ case '5': >+ case '6': >+ case '7': >+ case '8': >+ case '9': >+ case 'A': >+ case 'B': >+ case 'C': >+ case 'D': >+ case 'E': >+ case 'F': >+ case 'a': >+ case 'b': >+ case 'c': >+ case 'd': >+ case 'e': >+ case 'f': >+ return true; >+ default: >+ return false; >+ } >+} >+ >+/// RFC3986 scheme character test >+/** >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered a valid character for a uri scheme >+ */ >+inline bool scheme(char c) { >+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { >+ return true; >+ } else if (c >= '0' && c <= '9') { >+ return true; >+ } else if (c == '+' || c == '-' || c == '.') { >+ return true; >+ } else { >+ return false; >+ } >+} >+ >+/// RFC3986 digit character test >+/** >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered a digit (0-9) >+ */ >+inline bool digit(char c) { >+ return c >= '0' && c <= '9'; >+} >+ >+/// RFC3986 digit character test (iterator version) >+/** >+ * @since 0.8.3 >+ * >+ * @param c the char to test >+ * @return True if the character is considered a digit (0-9) >+ */ >+inline bool digit(std::string::const_iterator it) { >+ return digit(*it); >+} >+ >+ >+/// RFC3986 per cent encoded character test >+/** >+ * caller must range check (only caller knows the actual range) >+ * caller must check for leading % >+ * >+ * @since 0.8.3 >+ * >+ * @param it An iterator to the first character after the % sign >+ * @return True if both the character pointed at by the iterator and >+ * the next one represent a valid RFC3986 percent encoding >+ */ >+inline bool pct_encoded(std::string::const_iterator it) { >+ return hexdigit(*it) && hexdigit(*(it + 1)); >+} >+ >+/// Tests a range for a valid IPv4 decimal octet >+/** >+ * @since 0.8.3 >+ * >+ * @param start An iterator to the first character of the range to check (inclusive) >+ * @param start An iterator to the last character of the range to check (exclusive) >+ * @return True if the range represents a valid IPv4 decimal octet (0-255) >+ */ >+inline bool dec_octet(std::string::const_iterator start, std::string::const_iterator end) { >+ if (end-start == 1) { >+ return digit(start); >+ } else if (end-start == 2) { >+ return ((*start >= '1' && *start <= '9') && digit(start+1)); >+ } else if (end-start == 3) { >+ if (*start == '1') { >+ return digit(start+1) && digit(start+2); >+ } else if (*start == '2') { >+ if (*(start+1) >= '0' && *(start+1) <= '4') { >+ return digit(start+2); >+ } else if (*(start+1) == '5') { >+ return *(start+2) >= '0' && *(start+2) <= '5'; >+ } >+ } >+ } >+ return false; >+} >+ >+/// Tests a range for a valid IPv4 literal >+/** >+ * @since 0.8.3 >+ * >+ * @param start An iterator to the first character of the range to check (inclusive) >+ * @param start An iterator to the last character of the range to check (exclusive) >+ * @return True if the range represents a valid IPv4 literal address >+ */ >+inline bool ipv4_literal(std::string::const_iterator start, std::string::const_iterator end) { >+ std::string::const_iterator cursor = start; >+ size_t counter = 0; >+ for (std::string::const_iterator it = start; it != end; ++it) { >+ if (*it == '.') { >+ if (dec_octet(cursor,it)) { >+ cursor = it+1; >+ counter++; >+ if (counter > 3) { >+ return false; >+ } >+ } else { >+ return false; >+ } >+ } >+ } >+ >+ // check final octet >+ return (counter == 3 && dec_octet(cursor,end)); >+} >+ >+/// Tests a range for a valid IPv6 hex quad >+/** >+ * @since 0.8.3 >+ * >+ * @param start An iterator to the first character of the range to check (inclusive) >+ * @param start An iterator to the last character of the range to check (exclusive) >+ * @return True if the range represents a valid IPv6 hex quad >+ */ >+inline bool hex4(std::string::const_iterator start, std::string::const_iterator end) { >+ if (end-start == 0 || end-start >4) { >+ return false; >+ } >+ for (std::string::const_iterator it = start; it != end; ++it) { >+ if (!hexdigit(*it)) { >+ return false; >+ } >+ } >+ return true; >+} >+ >+/// Tests a range for a valid IPv6 literal >+/** >+ * @since 0.8.3 >+ * >+ * @param start An iterator to the first character of the range to check (inclusive) >+ * @param start An iterator to the last character of the range to check (exclusive) >+ * @return True if the range represents a valid IPv6 literal >+ */ >+inline bool ipv6_literal(std::string::const_iterator start, std::string::const_iterator end) { >+ // initial range check >+ if (end-start > 45 && end-start >= 2) { >+ return false; >+ } >+ >+ // peal off and count hex4s until we run out of colons, >+ // note the abbreviation marker if we see one. >+ std::string::const_iterator cursor = start; >+ std::string::const_iterator it = start; >+ size_t count = 0; >+ size_t abbr = 0; >+ while (it != end) { >+ if (*it == ':') { >+ if (it == start) { >+ // if a : happens at the beginning, don't check for a hex quad, just advance >+ // the cursor. The abbreviation marker will be counted on the next pass >+ cursor++; >+ } else if (it-cursor == 0) { >+ // this is a double colon abbreviation marker >+ cursor++; >+ abbr++; >+ } else if (hex4(cursor,it)) { >+ cursor = it+1; >+ count++; >+ } else { >+ return false; >+ } >+ } >+ it++; >+ } >+ >+ // final bit either needs to be a hex4 or an IPv4 literal >+ if (cursor == end) { >+ // fine >+ } else if (hex4(cursor,end)) { >+ count++; >+ } else if (ipv4_literal(cursor, end)) { >+ count += 2; >+ } else { >+ return false; >+ } >+ >+ if ((abbr == 0 && count != 8) || (abbr == 1 && count > 7) || abbr > 1) { >+ return false; >+ } >+ >+ return true; >+} >+ >+/// Tests a character for validity for a registry name >+/** >+ * will fail on %, which is valid, but only when used as a part of a multiple >+ * character escape sequence. Since this test checks a single character it >+ * can't tell whether a % character is valid so it returns false. The caller >+ * needs to catch and handle %s in another way. >+ * >+ * @since 0.8.3 >+ * >+ * @param c The character to test >+ * @return True if the range represents a valid IPv6 literal >+ */ >+inline bool reg_name(char c) { >+ return unreserved(c) || sub_delim(c); >+} >+ >+/// Tests a range for validity for a registry name >+/** >+ * @since 0.8.3 >+ * >+ * @param start An iterator to the first character of the range to check (inclusive) >+ * @param start An iterator to the last character of the range to check (exclusive) >+ * @return True if the range represents a valid registry name >+ */ >+inline bool reg_name(std::string::const_iterator start, std::string::const_iterator end) { >+ std::string::const_iterator it = start; >+ while (it != end) { >+ if (*it == '%') { >+ // check for valid % encoded char >+ if (it+2 < end && uri_helper::pct_encoded(it+1)) { >+ it += 3; >+ continue; >+ } else { >+ return false; >+ } >+ } else if (!uri_helper::reg_name(*it)) { >+ return false; >+ } >+ ++it; >+ } >+ return true; >+} >+ >+} // end namespace uri_helper >+ >+ >+ >+ > class uri { > public: >- explicit uri(std::string const & uri_string) : m_valid(false) { >+ explicit uri(std::string const & uri_string) : m_valid(false), m_ipv6_literal(false) { > std::string::const_iterator it; > std::string::const_iterator temp; > >@@ -57,6 +405,7 @@ public: > it = uri_string.begin(); > size_t uri_len = uri_string.length(); > >+ // extract scheme. We only consider Websocket and HTTP URI schemes as valid > if (uri_len >= 7 && std::equal(it,it+6,"wss://")) { > m_secure = true; > m_scheme = "wss"; >@@ -101,17 +450,26 @@ public: > return; > } else { > // validate IPv6 literal parts >- // can contain numbers, a-f and A-F >+ if (!uri_helper::ipv6_literal(it,temp)) { >+ return; >+ } else { >+ m_ipv6_literal = true; >+ } > m_host.append(it,temp); > } > it = temp+1; > if (it == uri_string.end()) { > state = 2; >- } else if (*it == '/') { >+ } else if (*it == '/' || *it == '?' || *it == '#') { >+ // todo: better path parsing > state = 2; >- ++it; >+ >+ // we don't increment the iterator here because we want the >+ // delimiter to be read again as a part of the path > } else if (*it == ':') { > state = 1; >+ >+ // start reading port after the delimiter > ++it; > } else { > // problem >@@ -119,20 +477,44 @@ public: > } > } else { > // IPv4 or hostname >- // extract until : or / >+ // extract until : or first path component > while (state == 0) { > if (it == uri_string.end()) { > state = 2; > break; >- } else if (*it == '/') { >- state = 2; >- } else if (*it == ':') { >- // end hostname start port >- state = 1; >+ } else if (*it == '%') { >+ // check for valid % encoded char >+ if (it+2 < uri_string.end() && uri_helper::pct_encoded(it+1)) { >+ m_host.append(it,it+2); >+ it += 3; >+ } >+ } else if (!uri_helper::reg_name(*it)) { >+ // we hit one of the general delimiters >+ if (*it == ':') { >+ // got host vs port delimiter >+ // end hostname start port >+ state = 1; >+ >+ // start reading port after the delimiter >+ ++it; >+ } else if (*it == '/' || *it == '#' || *it == '?') { >+ // one of the normal authority vs path delimiters >+ // end hostname and start parsing path >+ state = 2; >+ >+ // we don't increment the iterator here because we want the >+ // delimiter to be read again as a part of the path >+ } else { >+ // either @, [, or ] >+ // @ = userinfo fragment >+ // [ and ] = illegal, basically >+ return; >+ } > } else { > m_host += *it; >+ ++it; > } >- ++it; >+ > } > } > >@@ -140,17 +522,27 @@ public: > std::string port; > while (state == 1) { > if (it == uri_string.end()) { >- // state is not used after this point presently. >- // this should be re-enabled if it ever is needed in a future >- // refactoring >- //state = 3; >- break; >- } else if (*it == '/') { >+ // if we stop parsing the port and there wasn't actually a port >+ // we have an invalid URI >+ if (port.empty()) { >+ return; >+ } > state = 3; >- } else { >+ } else if (uri_helper::digit(it)) { > port += *it; >+ ++it; >+ } else { >+ // if we stop parsing the port and there wasn't actually a port >+ // we have an invalid URI >+ if (port.empty()) { >+ return; >+ } >+ state = 3; >+ >+ // we don't increment the iterator here because we want the >+ // delimiter to be read again as a part of the path > } >- ++it; >+ > } > > lib::error_code ec; >@@ -160,8 +552,14 @@ public: > return; > } > >- m_resource = "/"; >+ // step back one so the first char of the path delimiter doesn't get eaten > m_resource.append(it,uri_string.end()); >+ >+ if (m_resource.empty()) { >+ m_resource = "/"; >+ } >+ >+ // todo: validate path component > > > m_valid = true; >@@ -174,7 +572,10 @@ public: > , m_resource(resource.empty() ? "/" : resource) > , m_port(port) > , m_secure(secure) >- , m_valid(true) {} >+ { >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()); >+ } > > uri(bool secure, std::string const & host, std::string const & resource) > : m_scheme(secure ? "wss" : "ws") >@@ -182,7 +583,10 @@ public: > , m_resource(resource.empty() ? "/" : resource) > , m_port(secure ? uri_default_secure_port : uri_default_port) > , m_secure(secure) >- , m_valid(true) {} >+ { >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()); >+ } > > uri(bool secure, std::string const & host, std::string const & port, > std::string const & resource) >@@ -193,7 +597,9 @@ public: > { > lib::error_code ec; > m_port = get_port_from_string(port,ec); >- m_valid = !ec; >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ >+ m_valid = !ec && (m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end())); > } > > uri(std::string const & scheme, std::string const & host, uint16_t port, >@@ -203,7 +609,10 @@ public: > , m_resource(resource.empty() ? "/" : resource) > , m_port(port) > , m_secure(scheme == "wss" || scheme == "https") >- , m_valid(true) {} >+ { >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()); >+ } > > uri(std::string scheme, std::string const & host, std::string const & resource) > : m_scheme(scheme) >@@ -211,7 +620,10 @@ public: > , m_resource(resource.empty() ? "/" : resource) > , m_port((scheme == "wss" || scheme == "https") ? uri_default_secure_port : uri_default_port) > , m_secure(scheme == "wss" || scheme == "https") >- , m_valid(true) {} >+ { >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ m_valid = m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end()); >+ } > > uri(std::string const & scheme, std::string const & host, > std::string const & port, std::string const & resource) >@@ -222,13 +634,24 @@ public: > { > lib::error_code ec; > m_port = get_port_from_string(port,ec); >- m_valid = !ec; >+ m_ipv6_literal = uri_helper::ipv6_literal(host.begin(), host.end()); >+ >+ m_valid = !ec && (m_ipv6_literal || uri_helper::reg_name(host.begin(), host.end())); > } > > bool get_valid() const { > return m_valid; > } > >+ // Check whether the host of this URI is an IPv6 literal address >+ /** >+ * @since 0.8.3 >+ * @return True if the host of this URI is an IPv6 literal address >+ */ >+ bool is_ipv6_literal() const { >+ return m_ipv6_literal; >+ } >+ > bool get_secure() const { > return m_secure; > } >@@ -243,17 +666,27 @@ public: > > std::string get_host_port() const { > if (m_port == (m_secure ? uri_default_secure_port : uri_default_port)) { >+ // todo: should this have brackets for v6? > return m_host; > } else { > std::stringstream p; >- p << m_host << ":" << m_port; >+ if (m_ipv6_literal) { >+ p << "[" << m_host << "]:" << m_port; >+ } else { >+ p << m_host << ":" << m_port; >+ } >+ > return p.str(); > } > } > > std::string get_authority() const { > std::stringstream p; >- p << m_host << ":" << m_port; >+ if (m_ipv6_literal) { >+ p << "[" << m_host << "]:" << m_port; >+ } else { >+ p << m_host << ":" << m_port; >+ } > return p.str(); > } > >@@ -274,7 +707,12 @@ public: > std::string str() const { > std::stringstream s; > >- s << m_scheme << "://" << m_host; >+ s << m_scheme << "://"; >+ if (m_ipv6_literal) { >+ s << "[" << m_host << "]"; >+ } else { >+ s << m_host; >+ } > > if (m_port != (m_secure ? uri_default_secure_port : uri_default_port)) { > s << ":" << m_port; >@@ -346,6 +784,7 @@ private: > uint16_t m_port; > bool m_secure; > bool m_valid; >+ bool m_ipv6_literal; > }; > > /// Pointer to a URI >diff '--color=auto' -urNp websocketpp-zaphoyd/websocketpp/utilities.hpp websocketpp-hingobway/websocketpp/utilities.hpp >--- websocketpp-zaphoyd/websocketpp/utilities.hpp 2020-04-27 17:25:11.000000000 +0200 >+++ websocketpp-hingobway/websocketpp/utilities.hpp 2025-03-10 21:33:06.000000000 +0100 >@@ -128,13 +128,6 @@ typename T::const_iterator ci_find_subst > needle, needle+size, my_equal<typename T::value_type>(loc) ); > } > >-/// Convert a string to lowercase >-/** >- * @param [in] in The string to convert >- * @return The converted string >- */ >-std::string to_lower(std::string const & in); >- > /// Replace all occurrances of a substring with another > /** > * @param [in] subject The string to search in
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 946365
:
913920
| 921340