diff --git a/src/3rdparty/include/websocketpp/CMakeLists.txt b/src/3rdparty/include/websocketpp/CMakeLists.txt new file mode 100644 index 000000000..3ea8cc1c4 --- /dev/null +++ b/src/3rdparty/include/websocketpp/CMakeLists.txt @@ -0,0 +1,2 @@ +init_target("websocketpp") +final_target () diff --git a/src/3rdparty/include/websocketpp/COPYING b/src/3rdparty/include/websocketpp/COPYING new file mode 100644 index 000000000..f8cc5ba1b --- /dev/null +++ b/src/3rdparty/include/websocketpp/COPYING @@ -0,0 +1,145 @@ +Main Library: + +Copyright (c) 2014, Peter Thorson. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * 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. + +Bundled Libraries: + +****** Base 64 Library (base64/base64.hpp) ****** +base64.hpp is a repackaging of the base64.cpp and base64.h files into a +single header suitable for use as a header only library. This conversion was +done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to +the code are redistributed under the same license as the original, which is +listed below. + +base64.cpp and base64.h + +Copyright (C) 2004-2008 René Nyffenegger + +This source code is provided 'as-is', without any express or implied +warranty. In no event will the author be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + +3. This notice may not be removed or altered from any source distribution. + +René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +****** SHA1 Library (sha1/sha1.hpp) ****** +sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the shallsha1 +library (http://code.google.com/p/smallsha1/) into a single header suitable for +use as a header only library. This conversion was done by Peter Thorson +(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed +under the same license as the original, which is listed below. + + Copyright (c) 2011, Micael Hildenborg + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Micael Hildenborg nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****** MD5 Library (common/md5.hpp) ****** +md5.hpp is a reformulation of the md5.h and md5.c code from +http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to +function as a component of a header only library. This conversion was done by +Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The +changes are released under the same license as the original (listed below) + +Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +L. Peter Deutsch +ghost@aladdin.com + +****** UTF8 Validation logic (utf8_validation.hpp) ****** +utf8_validation.hpp is adapted from code originally written by Bjoern Hoehrmann +. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for +details. + +The original license: + +Copyright (c) 2008-2009 Bjoern Hoehrmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/plugins/server/3rdparty/include/websocketpp/base64/base64.hpp b/src/3rdparty/include/websocketpp/base64/base64.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/base64/base64.hpp rename to src/3rdparty/include/websocketpp/base64/base64.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/client.hpp b/src/3rdparty/include/websocketpp/client.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/client.hpp rename to src/3rdparty/include/websocketpp/client.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/close.hpp b/src/3rdparty/include/websocketpp/close.hpp similarity index 96% rename from src/plugins/server/3rdparty/include/websocketpp/close.hpp rename to src/3rdparty/include/websocketpp/close.hpp index ded776575..276498e6e 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/close.hpp +++ b/src/3rdparty/include/websocketpp/close.hpp @@ -142,6 +142,11 @@ namespace status { /// or reconnect to the same IP upon user action. static value const try_again_later = 1013; + /// Indicates that the server was acting as a gateway or proxy and received + /// an invalid response from the upstream server. This is similar to 502 + /// HTTP Status Code. + static value const bad_gateway = 1014; + /// An endpoint failed to perform a TLS handshake /** * Designated for use in applications expecting a status code to indicate @@ -178,7 +183,7 @@ namespace status { */ inline bool reserved(value code) { return ((code >= rsv_start && code <= rsv_end) || - code == 1004 || code == 1014); + code == 1004); } /// First value in range that is always invalid on the wire @@ -248,6 +253,12 @@ namespace status { return "Extension required"; case internal_endpoint_error: return "Internal endpoint error"; + case service_restart: + return "Service restart"; + case try_again_later: + return "Try again later"; + case bad_gateway: + return "Bad gateway"; case tls_handshake: return "TLS handshake failure"; case subprotocol_error: diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/asio.hpp b/src/3rdparty/include/websocketpp/common/asio.hpp similarity index 89% rename from src/plugins/server/3rdparty/include/websocketpp/common/asio.hpp rename to src/3rdparty/include/websocketpp/common/asio.hpp index ca4835939..3c8fa13e9 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/common/asio.hpp +++ b/src/3rdparty/include/websocketpp/common/asio.hpp @@ -101,9 +101,19 @@ namespace lib { bool is_neg(T duration) { return duration.count() < 0; } - inline lib::chrono::milliseconds milliseconds(long duration) { - return lib::chrono::milliseconds(duration); - } + + // If boost believes it has std::chrono available it will use it + // so we should also use it for things that relate to boost, even + // if the library would otherwise use boost::chrono. + #if defined(BOOST_ASIO_HAS_STD_CHRONO) + inline std::chrono::milliseconds milliseconds(long duration) { + return std::chrono::milliseconds(duration); + } + #else + inline lib::chrono::milliseconds milliseconds(long duration) { + return lib::chrono::milliseconds(duration); + } + #endif #else // Using boost::asio <1.49 we pretend a deadline timer is a steady // timer and wrap the negative detection and duration conversion diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/asio_ssl.hpp b/src/3rdparty/include/websocketpp/common/asio_ssl.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/asio_ssl.hpp rename to src/3rdparty/include/websocketpp/common/asio_ssl.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/chrono.hpp b/src/3rdparty/include/websocketpp/common/chrono.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/chrono.hpp rename to src/3rdparty/include/websocketpp/common/chrono.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/connection_hdl.hpp b/src/3rdparty/include/websocketpp/common/connection_hdl.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/connection_hdl.hpp rename to src/3rdparty/include/websocketpp/common/connection_hdl.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/cpp11.hpp b/src/3rdparty/include/websocketpp/common/cpp11.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/cpp11.hpp rename to src/3rdparty/include/websocketpp/common/cpp11.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/functional.hpp b/src/3rdparty/include/websocketpp/common/functional.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/functional.hpp rename to src/3rdparty/include/websocketpp/common/functional.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/md5.hpp b/src/3rdparty/include/websocketpp/common/md5.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/md5.hpp rename to src/3rdparty/include/websocketpp/common/md5.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/memory.hpp b/src/3rdparty/include/websocketpp/common/memory.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/common/memory.hpp rename to src/3rdparty/include/websocketpp/common/memory.hpp index 581aa5597..42048e337 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/common/memory.hpp +++ b/src/3rdparty/include/websocketpp/common/memory.hpp @@ -65,7 +65,6 @@ namespace lib { #ifdef _WEBSOCKETPP_CPP11_MEMORY_ using std::shared_ptr; using std::weak_ptr; - using std::auto_ptr; using std::enable_shared_from_this; using std::static_pointer_cast; using std::make_shared; diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/network.hpp b/src/3rdparty/include/websocketpp/common/network.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/network.hpp rename to src/3rdparty/include/websocketpp/common/network.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/platforms.hpp b/src/3rdparty/include/websocketpp/common/platforms.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/platforms.hpp rename to src/3rdparty/include/websocketpp/common/platforms.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/random.hpp b/src/3rdparty/include/websocketpp/common/random.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/random.hpp rename to src/3rdparty/include/websocketpp/common/random.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/regex.hpp b/src/3rdparty/include/websocketpp/common/regex.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/regex.hpp rename to src/3rdparty/include/websocketpp/common/regex.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/stdint.hpp b/src/3rdparty/include/websocketpp/common/stdint.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/stdint.hpp rename to src/3rdparty/include/websocketpp/common/stdint.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/system_error.hpp b/src/3rdparty/include/websocketpp/common/system_error.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/system_error.hpp rename to src/3rdparty/include/websocketpp/common/system_error.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/thread.hpp b/src/3rdparty/include/websocketpp/common/thread.hpp similarity index 91% rename from src/plugins/server/3rdparty/include/websocketpp/common/thread.hpp rename to src/3rdparty/include/websocketpp/common/thread.hpp index 09f6b3c51..1b0472aa6 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/common/thread.hpp +++ b/src/3rdparty/include/websocketpp/common/thread.hpp @@ -51,7 +51,11 @@ #endif #endif -#ifdef _WEBSOCKETPP_CPP11_THREAD_ +#if defined(_WEBSOCKETPP_MINGW_THREAD_) + #include + #include + #include +#elif defined(_WEBSOCKETPP_CPP11_THREAD_) #include #include #include @@ -64,7 +68,7 @@ namespace websocketpp { namespace lib { -#ifdef _WEBSOCKETPP_CPP11_THREAD_ +#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_) using std::mutex; using std::lock_guard; using std::thread; diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/time.hpp b/src/3rdparty/include/websocketpp/common/time.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/time.hpp rename to src/3rdparty/include/websocketpp/common/time.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/common/type_traits.hpp b/src/3rdparty/include/websocketpp/common/type_traits.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/common/type_traits.hpp rename to src/3rdparty/include/websocketpp/common/type_traits.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/concurrency/basic.hpp b/src/3rdparty/include/websocketpp/concurrency/basic.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/concurrency/basic.hpp rename to src/3rdparty/include/websocketpp/concurrency/basic.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/concurrency/none.hpp b/src/3rdparty/include/websocketpp/concurrency/none.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/concurrency/none.hpp rename to src/3rdparty/include/websocketpp/concurrency/none.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/asio.hpp b/src/3rdparty/include/websocketpp/config/asio.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/asio.hpp rename to src/3rdparty/include/websocketpp/config/asio.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/asio_client.hpp b/src/3rdparty/include/websocketpp/config/asio_client.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/asio_client.hpp rename to src/3rdparty/include/websocketpp/config/asio_client.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/asio_no_tls.hpp b/src/3rdparty/include/websocketpp/config/asio_no_tls.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/asio_no_tls.hpp rename to src/3rdparty/include/websocketpp/config/asio_no_tls.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/asio_no_tls_client.hpp b/src/3rdparty/include/websocketpp/config/asio_no_tls_client.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/asio_no_tls_client.hpp rename to src/3rdparty/include/websocketpp/config/asio_no_tls_client.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/boost_config.hpp b/src/3rdparty/include/websocketpp/config/boost_config.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/boost_config.hpp rename to src/3rdparty/include/websocketpp/config/boost_config.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/core.hpp b/src/3rdparty/include/websocketpp/config/core.hpp similarity index 94% rename from src/plugins/server/3rdparty/include/websocketpp/config/core.hpp rename to src/3rdparty/include/websocketpp/config/core.hpp index a95b4021d..93981aa0e 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/config/core.hpp +++ b/src/3rdparty/include/websocketpp/config/core.hpp @@ -49,6 +49,7 @@ // Loggers #include +#include // RNG #include @@ -188,7 +189,18 @@ struct core { static const websocketpp::log::level alog_level = websocketpp::log::alevel::all ^ websocketpp::log::alevel::devel; - /// + /// Size of the per-connection read buffer + /** + * Each connection has an internal buffer of this size. A larger value will + * result in fewer trips through the library and less CPU overhead at the + * expense of increased memory usage per connection. + * + * If your application primarily deals in very large messages you may want + * to try setting this value higher. + * + * If your application has a lot of connections or primarily deals in small + * messages you may want to try setting this smaller. + */ static const size_t connection_read_buffer_size = 16384; /// Drop connections immediately on protocol error. diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/core_client.hpp b/src/3rdparty/include/websocketpp/config/core_client.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/core_client.hpp rename to src/3rdparty/include/websocketpp/config/core_client.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/debug.hpp b/src/3rdparty/include/websocketpp/config/debug.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/debug.hpp rename to src/3rdparty/include/websocketpp/config/debug.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/debug_asio.hpp b/src/3rdparty/include/websocketpp/config/debug_asio.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/debug_asio.hpp rename to src/3rdparty/include/websocketpp/config/debug_asio.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/debug_asio_no_tls.hpp b/src/3rdparty/include/websocketpp/config/debug_asio_no_tls.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/debug_asio_no_tls.hpp rename to src/3rdparty/include/websocketpp/config/debug_asio_no_tls.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/minimal_client.hpp b/src/3rdparty/include/websocketpp/config/minimal_client.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/minimal_client.hpp rename to src/3rdparty/include/websocketpp/config/minimal_client.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/config/minimal_server.hpp b/src/3rdparty/include/websocketpp/config/minimal_server.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/config/minimal_server.hpp rename to src/3rdparty/include/websocketpp/config/minimal_server.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/connection.hpp b/src/3rdparty/include/websocketpp/connection.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/connection.hpp rename to src/3rdparty/include/websocketpp/connection.hpp index 3bbbbb31e..d019fce33 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/connection.hpp +++ b/src/3rdparty/include/websocketpp/connection.hpp @@ -294,8 +294,8 @@ private: }; public: - explicit connection(bool p_is_server, std::string const & ua, alog_type& alog, - elog_type& elog, rng_type & rng) + explicit connection(bool p_is_server, std::string const & ua, const lib::shared_ptr& alog, + const lib::shared_ptr& elog, rng_type & rng) : transport_con_type(p_is_server, alog, elog) , m_handle_read_frame(lib::bind( &type::handle_read_frame, @@ -329,7 +329,7 @@ public: , m_http_state(session::http_state::init) , m_was_clean(false) { - m_alog.write(log::alevel::devel,"connection constructor"); + m_alog->write(log::alevel::devel,"connection constructor"); } /// Get a shared pointer to this component @@ -1486,7 +1486,7 @@ private: void log_err(log::level l, char const * msg, error_type const & ec) { std::stringstream s; s << msg << " error: " << ec << " (" << ec.message() << ")"; - m_elog.write(l, s.str()); + m_elog->write(l, s.str()); } // internal handler functions @@ -1603,8 +1603,8 @@ private: std::vector m_requested_subprotocols; bool const m_is_server; - alog_type& m_alog; - elog_type& m_elog; + const lib::shared_ptr m_alog; + const lib::shared_ptr m_elog; rng_type & m_rng; @@ -1633,15 +1633,6 @@ private: session::http_state::value m_http_state; bool m_was_clean; - - /// Whether or not this endpoint initiated the closing handshake. - bool m_closed_by_me; - - /// ??? - bool m_failed_by_me; - - /// Whether or not this endpoint initiated the drop of the TCP connection - bool m_dropped_by_me; }; } // namespace websocketpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/connection_base.hpp b/src/3rdparty/include/websocketpp/connection_base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/connection_base.hpp rename to src/3rdparty/include/websocketpp/connection_base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/endpoint.hpp b/src/3rdparty/include/websocketpp/endpoint.hpp similarity index 95% rename from src/plugins/server/3rdparty/include/websocketpp/endpoint.hpp rename to src/3rdparty/include/websocketpp/endpoint.hpp index 65584d8a7..c124b1d9a 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/endpoint.hpp +++ b/src/3rdparty/include/websocketpp/endpoint.hpp @@ -89,8 +89,8 @@ public: //friend connection; explicit endpoint(bool p_is_server) - : m_alog(config::alog_level, log::channel_type_hint::access) - , m_elog(config::elog_level, log::channel_type_hint::error) + : m_alog(new alog_type(config::alog_level, log::channel_type_hint::access)) + , m_elog(new elog_type(config::elog_level, log::channel_type_hint::error)) , m_user_agent(::websocketpp::user_agent) , m_open_handshake_timeout_dur(config::timeout_open_handshake) , m_close_handshake_timeout_dur(config::timeout_close_handshake) @@ -99,12 +99,12 @@ public: , m_max_http_body_size(config::max_http_body_size) , m_is_server(p_is_server) { - m_alog.set_channels(config::alog_level); - m_elog.set_channels(config::elog_level); + m_alog->set_channels(config::alog_level); + m_elog->set_channels(config::elog_level); - m_alog.write(log::alevel::devel, "endpoint constructor"); + m_alog->write(log::alevel::devel, "endpoint constructor"); - transport_type::init_logging(&m_alog, &m_elog); + transport_type::init_logging(m_alog, m_elog); } @@ -218,7 +218,7 @@ public: * @param channels The channel value(s) to set */ void set_access_channels(log::level channels) { - m_alog.set_channels(channels); + m_alog->set_channels(channels); } /// Clear Access logging channels @@ -229,7 +229,7 @@ public: * @param channels The channel value(s) to clear */ void clear_access_channels(log::level channels) { - m_alog.clear_channels(channels); + m_alog->clear_channels(channels); } /// Set Error logging channel @@ -240,7 +240,7 @@ public: * @param channels The channel value(s) to set */ void set_error_channels(log::level channels) { - m_elog.set_channels(channels); + m_elog->set_channels(channels); } /// Clear Error logging channels @@ -251,7 +251,7 @@ public: * @param channels The channel value(s) to clear */ void clear_error_channels(log::level channels) { - m_elog.clear_channels(channels); + m_elog->clear_channels(channels); } /// Get reference to access logger @@ -259,7 +259,7 @@ public: * @return A reference to the access logger */ alog_type & get_alog() { - return m_alog; + return *m_alog; } /// Get reference to error logger @@ -267,7 +267,7 @@ public: * @return A reference to the error logger */ elog_type & get_elog() { - return m_elog; + return *m_elog; } /*************************/ @@ -275,52 +275,52 @@ public: /*************************/ void set_open_handler(open_handler h) { - m_alog.write(log::alevel::devel,"set_open_handler"); + m_alog->write(log::alevel::devel,"set_open_handler"); scoped_lock_type guard(m_mutex); m_open_handler = h; } void set_close_handler(close_handler h) { - m_alog.write(log::alevel::devel,"set_close_handler"); + m_alog->write(log::alevel::devel,"set_close_handler"); scoped_lock_type guard(m_mutex); m_close_handler = h; } void set_fail_handler(fail_handler h) { - m_alog.write(log::alevel::devel,"set_fail_handler"); + m_alog->write(log::alevel::devel,"set_fail_handler"); scoped_lock_type guard(m_mutex); m_fail_handler = h; } void set_ping_handler(ping_handler h) { - m_alog.write(log::alevel::devel,"set_ping_handler"); + m_alog->write(log::alevel::devel,"set_ping_handler"); scoped_lock_type guard(m_mutex); m_ping_handler = h; } void set_pong_handler(pong_handler h) { - m_alog.write(log::alevel::devel,"set_pong_handler"); + m_alog->write(log::alevel::devel,"set_pong_handler"); scoped_lock_type guard(m_mutex); m_pong_handler = h; } void set_pong_timeout_handler(pong_timeout_handler h) { - m_alog.write(log::alevel::devel,"set_pong_timeout_handler"); + m_alog->write(log::alevel::devel,"set_pong_timeout_handler"); scoped_lock_type guard(m_mutex); m_pong_timeout_handler = h; } void set_interrupt_handler(interrupt_handler h) { - m_alog.write(log::alevel::devel,"set_interrupt_handler"); + m_alog->write(log::alevel::devel,"set_interrupt_handler"); scoped_lock_type guard(m_mutex); m_interrupt_handler = h; } void set_http_handler(http_handler h) { - m_alog.write(log::alevel::devel,"set_http_handler"); + m_alog->write(log::alevel::devel,"set_http_handler"); scoped_lock_type guard(m_mutex); m_http_handler = h; } void set_validate_handler(validate_handler h) { - m_alog.write(log::alevel::devel,"set_validate_handler"); + m_alog->write(log::alevel::devel,"set_validate_handler"); scoped_lock_type guard(m_mutex); m_validate_handler = h; } void set_message_handler(message_handler h) { - m_alog.write(log::alevel::devel,"set_message_handler"); + m_alog->write(log::alevel::devel,"set_message_handler"); scoped_lock_type guard(m_mutex); m_message_handler = h; } @@ -661,8 +661,8 @@ public: protected: connection_ptr create_connection(); - alog_type m_alog; - elog_type m_elog; + lib::shared_ptr m_alog; + lib::shared_ptr m_elog; private: // dynamic settings std::string m_user_agent; diff --git a/src/plugins/server/3rdparty/include/websocketpp/endpoint_base.hpp b/src/3rdparty/include/websocketpp/endpoint_base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/endpoint_base.hpp rename to src/3rdparty/include/websocketpp/endpoint_base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/error.hpp b/src/3rdparty/include/websocketpp/error.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/error.hpp rename to src/3rdparty/include/websocketpp/error.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/extensions/extension.hpp b/src/3rdparty/include/websocketpp/extensions/extension.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/extensions/extension.hpp rename to src/3rdparty/include/websocketpp/extensions/extension.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp b/src/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp rename to src/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp index 49c0e1dcf..657309520 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp +++ b/src/3rdparty/include/websocketpp/extensions/permessage_deflate/disabled.hpp @@ -29,6 +29,7 @@ #define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP #include +#include #include #include diff --git a/src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp b/src/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp similarity index 85% rename from src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp rename to src/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp index 4ebf30c67..d05403a8a 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp +++ b/src/3rdparty/include/websocketpp/extensions/permessage_deflate/enabled.hpp @@ -32,12 +32,13 @@ #include #include #include +#include #include #include #include -#include +#include "zlib.h" #include #include @@ -46,7 +47,7 @@ namespace websocketpp { namespace extensions { -/// Implementation of the draft permessage-deflate WebSocket extension +/// Implementation of RFC 7692, the permessage-deflate WebSocket extension /** * ### permessage-deflate interface * @@ -174,18 +175,30 @@ namespace websocketpp { namespace extensions { namespace permessage_deflate { -/// Default value for server_max_window_bits as defined by draft 17 +/// Default value for server_max_window_bits as defined by RFC 7692 static uint8_t const default_server_max_window_bits = 15; -/// Minimum value for server_max_window_bits as defined by draft 17 +/// Minimum value for server_max_window_bits as defined by RFC 7692 +/** + * NOTE: A value of 8 is not actually supported by zlib, the deflate + * library that WebSocket++ uses. To preserve backwards compatibility + * with RFC 7692 and previous versions of the library a value of 8 + * is accepted by the library but will always be negotiated as 9. + */ static uint8_t const min_server_max_window_bits = 8; -/// Maximum value for server_max_window_bits as defined by draft 17 +/// Maximum value for server_max_window_bits as defined by RFC 7692 static uint8_t const max_server_max_window_bits = 15; -/// Default value for client_max_window_bits as defined by draft 17 +/// Default value for client_max_window_bits as defined by RFC 7692 static uint8_t const default_client_max_window_bits = 15; -/// Minimum value for client_max_window_bits as defined by draft 17 +/// Minimum value for client_max_window_bits as defined by RFC 7692 +/** + * NOTE: A value of 8 is not actually supported by zlib, the deflate + * library that WebSocket++ uses. To preserve backwards compatibility + * with RFC 7692 and previous versions of the library a value of 8 + * is accepted by the library but will always be negotiated as 9. + */ static uint8_t const min_client_max_window_bits = 8; -/// Maximum value for client_max_window_bits as defined by draft 17 +/// Maximum value for client_max_window_bits as defined by RFC 7692 static uint8_t const max_client_max_window_bits = 15; namespace mode { @@ -213,7 +226,7 @@ public: , m_server_max_window_bits_mode(mode::accept) , m_client_max_window_bits_mode(mode::accept) , m_initialized(false) - , m_compress_buffer_size(16384) + , m_compress_buffer_size(8192) { m_dstate.zalloc = Z_NULL; m_dstate.zfree = Z_NULL; @@ -292,6 +305,7 @@ public: } m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]); + m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]); if ((m_server_no_context_takeover && is_server) || (m_client_no_context_takeover && !is_server)) { @@ -372,7 +386,7 @@ public: /** * The bits setting is the base 2 logarithm of the maximum window size that * the server must use to compress outgoing messages. The permitted range - * is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB + * is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB * window. The default setting is 15. * * Mode Options: @@ -386,6 +400,14 @@ public: * adjusted by the server. A server may unilaterally set this value without * client support. * + * NOTE: The permessage-deflate spec specifies that a value of 8 is allowed. + * Prior to version 0.8.0 a value of 8 was also allowed by this library. + * zlib, the deflate compression library that WebSocket++ uses has always + * silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9 + * and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0 + * continues to perform the 8->9 conversion for backwards compatibility + * purposes but this should be considered deprecated functionality. + * * @param bits The size to request for the outgoing window size * @param mode The mode to use for negotiating this parameter * @return A status code @@ -394,6 +416,12 @@ public: if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) { return error::make_error_code(error::invalid_max_window_bits); } + + // See note in doc comment above about what is happening here + if (bits == 8) { + bits = 9; + } + m_server_max_window_bits = bits; m_server_max_window_bits_mode = mode; @@ -403,8 +431,8 @@ public: /// Limit client LZ77 sliding window size /** * The bits setting is the base 2 logarithm of the window size that the - * client must use to compress outgoing messages. The permitted range is 8 - * to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window. + * client must use to compress outgoing messages. The permitted range is 9 + * to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window. * The default setting is 15. * * Mode Options: @@ -417,6 +445,14 @@ public: * outgoing window size unilaterally. A server may only limit the client's * window size if the remote client supports that feature. * + * NOTE: The permessage-deflate spec specifies that a value of 8 is allowed. + * Prior to version 0.8.0 a value of 8 was also allowed by this library. + * zlib, the deflate compression library that WebSocket++ uses has always + * silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9 + * and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0 + * continues to perform the 8->9 conversion for backwards compatibility + * purposes but this should be considered deprecated functionality. + * * @param bits The size to request for the outgoing window size * @param mode The mode to use for negotiating this parameter * @return A status code @@ -425,6 +461,12 @@ public: if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) { return error::make_error_code(error::invalid_max_window_bits); } + + // See note in doc comment above about what is happening here + if (bits == 8) { + bits = 9; + } + m_client_max_window_bits = bits; m_client_max_window_bits_mode = mode; @@ -555,7 +597,7 @@ public: do { m_istate.avail_out = m_compress_buffer_size; - m_istate.next_out = m_compress_buffer.get(); + m_istate.next_out = m_decompress_buffer.get(); ret = inflate(&m_istate, Z_SYNC_FLUSH); @@ -564,7 +606,7 @@ public: } out.append( - reinterpret_cast(m_compress_buffer.get()), + reinterpret_cast(m_decompress_buffer.get()), m_compress_buffer_size - m_istate.avail_out ); } while (m_istate.avail_out == 0); @@ -642,11 +684,17 @@ private: * client requested that we use. * * options: - * - decline (refuse to use the attribute) - * - accept (use whatever the client says) - * - largest (use largest possible value) + * - decline (ignore value, offer our default instead) + * - accept (use the value requested by the client) + * - largest (use largest value acceptable to both) * - smallest (use smallest possible value) * + * NOTE: As a value of 8 is no longer explicitly supported by zlib but might + * be requested for negotiation by an older client/server, if the result of + * the negotiation would be to send a value of 8, a value of 9 is offered + * instead. This ensures that WebSocket++ will only ever negotiate connections + * with compression settings explicitly supported by zlib. + * * @param [in] value The value of the attribute from the offer * @param [out] ec A reference to the error code to return errors via */ @@ -678,6 +726,11 @@ private: ec = make_error_code(error::invalid_mode); m_server_max_window_bits = default_server_max_window_bits; } + + // See note in doc comment + if (m_server_max_window_bits == 8) { + m_server_max_window_bits = 9; + } } /// Negotiate client_max_window_bits attribute @@ -687,11 +740,17 @@ private: * negotiation mode. * * options: - * - decline (refuse to use the attribute) - * - accept (use whatever the client says) - * - largest (use largest possible value) + * - decline (ignore value, offer our default instead) + * - accept (use the value requested by the client) + * - largest (use largest value acceptable to both) * - smallest (use smallest possible value) * + * NOTE: As a value of 8 is no longer explicitly supported by zlib but might + * be requested for negotiation by an older client/server, if the result of + * the negotiation would be to send a value of 8, a value of 9 is offered + * instead. This ensures that WebSocket++ will only ever negotiate connections + * with compression settings explicitly supported by zlib. + * * @param [in] value The value of the attribute from the offer * @param [out] ec A reference to the error code to return errors via */ @@ -727,6 +786,11 @@ private: ec = make_error_code(error::invalid_mode); m_client_max_window_bits = default_client_max_window_bits; } + + // See note in doc comment + if (m_client_max_window_bits == 8) { + m_client_max_window_bits = 9; + } } bool m_enabled; @@ -741,6 +805,7 @@ private: int m_flush; size_t m_compress_buffer_size; lib::unique_ptr_uchar_array m_compress_buffer; + lib::unique_ptr_uchar_array m_decompress_buffer; z_stream m_dstate; z_stream m_istate; }; diff --git a/src/plugins/server/3rdparty/include/websocketpp/frame.hpp b/src/3rdparty/include/websocketpp/frame.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/frame.hpp rename to src/3rdparty/include/websocketpp/frame.hpp index 8a173375a..18a990b36 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/frame.hpp +++ b/src/3rdparty/include/websocketpp/frame.hpp @@ -610,6 +610,9 @@ inline size_t prepare_masking_key(const masking_key_type& key) { * to zero and less than sizeof(size_t). */ inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) { + if (offset == 0) { + return prepared_key; + } if (lib::net::is_little_endian()) { size_t temp = prepared_key << (sizeof(size_t)-offset)*8; return (prepared_key >> offset*8) | temp; diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/constants.hpp b/src/3rdparty/include/websocketpp/http/constants.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/http/constants.hpp rename to src/3rdparty/include/websocketpp/http/constants.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/impl/parser.hpp b/src/3rdparty/include/websocketpp/http/impl/parser.hpp similarity index 98% rename from src/plugins/server/3rdparty/include/websocketpp/http/impl/parser.hpp rename to src/3rdparty/include/websocketpp/http/impl/parser.hpp index 1d59b938e..fd24adb5d 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/http/impl/parser.hpp +++ b/src/3rdparty/include/websocketpp/http/impl/parser.hpp @@ -176,6 +176,10 @@ inline void parser::process_header(std::string::iterator begin, strip_lws(std::string(cursor+sizeof(header_separator)-1,end))); } +inline header_list const & parser::get_headers() const { + return m_headers; +} + inline std::string parser::raw_headers() const { std::stringstream raw; diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/impl/request.hpp b/src/3rdparty/include/websocketpp/http/impl/request.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/http/impl/request.hpp rename to src/3rdparty/include/websocketpp/http/impl/request.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/impl/response.hpp b/src/3rdparty/include/websocketpp/http/impl/response.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/http/impl/response.hpp rename to src/3rdparty/include/websocketpp/http/impl/response.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/parser.hpp b/src/3rdparty/include/websocketpp/http/parser.hpp similarity index 98% rename from src/plugins/server/3rdparty/include/websocketpp/http/parser.hpp rename to src/3rdparty/include/websocketpp/http/parser.hpp index 90f49ebe5..9d309ec91 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/http/parser.hpp +++ b/src/3rdparty/include/websocketpp/http/parser.hpp @@ -441,6 +441,16 @@ public: bool get_header_as_plist(std::string const & key, parameter_list & out) const; + /// Return a list of all HTTP headers + /** + * Return a list of all HTTP headers + * + * @since 0.8.0 + * + * @return A list of all HTTP headers + */ + header_list const & get_headers() const; + /// Append a value to an existing HTTP header /** * This method will set the value of the HTTP header `key` with the diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/request.hpp b/src/3rdparty/include/websocketpp/http/request.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/http/request.hpp rename to src/3rdparty/include/websocketpp/http/request.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/http/response.hpp b/src/3rdparty/include/websocketpp/http/response.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/http/response.hpp rename to src/3rdparty/include/websocketpp/http/response.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/impl/connection_impl.hpp b/src/3rdparty/include/websocketpp/impl/connection_impl.hpp similarity index 87% rename from src/plugins/server/3rdparty/include/websocketpp/impl/connection_impl.hpp rename to src/3rdparty/include/websocketpp/impl/connection_impl.hpp index af9b799b0..bf88c9552 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/impl/connection_impl.hpp +++ b/src/3rdparty/include/websocketpp/impl/connection_impl.hpp @@ -53,7 +53,7 @@ template void connection::set_termination_handler( termination_handler new_handler) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "connection set_termination_handler"); //scoped_lock_type lock(m_connection_state_lock); @@ -103,8 +103,8 @@ lib::error_code connection::send(void const * payload, size_t len, template lib::error_code connection::send(typename config::message_type::ptr msg) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection send"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection send"); } { @@ -153,8 +153,8 @@ lib::error_code connection::send(typename config::message_type::ptr msg) template void connection::ping(std::string const& payload, lib::error_code& ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection ping"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection ping"); } { @@ -162,7 +162,7 @@ void connection::ping(std::string const& payload, lib::error_code& ec) { if (m_state != session::state::open) { std::stringstream ss; ss << "connection::ping called from invalid state " << m_state; - m_alog.write(log::alevel::devel,ss.str()); + m_alog->write(log::alevel::devel,ss.str()); ec = error::make_error_code(error::invalid_state); return; } @@ -198,7 +198,7 @@ void connection::ping(std::string const& payload, lib::error_code& ec) { if (!m_ping_timer) { // Our transport doesn't support timers - m_elog.write(log::elevel::warn,"Warning: a pong_timeout_handler is \ + m_elog->write(log::elevel::warn,"Warning: a pong_timeout_handler is \ set but the transport in use does not support timeouts."); } } @@ -234,12 +234,12 @@ void connection::handle_pong_timeout(std::string payload, lib::error_code const & ec) { if (ec) { - if (ec.value() == (int) transport::error::operation_aborted) { + if (ec == transport::error::operation_aborted) { // ignore, this is expected return; } - m_elog.write(log::elevel::devel,"pong_timeout error: "+ec.message()); + m_elog->write(log::elevel::devel,"pong_timeout error: "+ec.message()); return; } @@ -250,8 +250,8 @@ void connection::handle_pong_timeout(std::string payload, template void connection::pong(std::string const& payload, lib::error_code& ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection pong"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection pong"); } { @@ -259,7 +259,7 @@ void connection::pong(std::string const& payload, lib::error_code& ec) { if (m_state != session::state::open) { std::stringstream ss; ss << "connection::pong called from invalid state " << m_state; - m_alog.write(log::alevel::devel,ss.str()); + m_alog->write(log::alevel::devel,ss.str()); ec = error::make_error_code(error::invalid_state); return; } @@ -304,8 +304,8 @@ template void connection::close(close::status::value const code, std::string const & reason, lib::error_code & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection close"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection close"); } // Truncate reason to maximum size allowable in a close frame. @@ -339,7 +339,7 @@ void connection::close(close::status::value const code, */ template lib::error_code connection::interrupt() { - m_alog.write(log::alevel::devel,"connection connection::interrupt"); + m_alog->write(log::alevel::devel,"connection connection::interrupt"); return transport_con_type::interrupt( lib::bind( &type::handle_interrupt, @@ -358,7 +358,7 @@ void connection::handle_interrupt() { template lib::error_code connection::pause_reading() { - m_alog.write(log::alevel::devel,"connection connection::pause_reading"); + m_alog->write(log::alevel::devel,"connection connection::pause_reading"); return transport_con_type::dispatch( lib::bind( &type::handle_pause_reading, @@ -370,13 +370,13 @@ lib::error_code connection::pause_reading() { /// Pause reading handler. Not safe to call directly template void connection::handle_pause_reading() { - m_alog.write(log::alevel::devel,"connection connection::handle_pause_reading"); + m_alog->write(log::alevel::devel,"connection connection::handle_pause_reading"); m_read_flag = false; } template lib::error_code connection::resume_reading() { - m_alog.write(log::alevel::devel,"connection connection::resume_reading"); + m_alog->write(log::alevel::devel,"connection connection::resume_reading"); return transport_con_type::dispatch( lib::bind( &type::handle_resume_reading, @@ -714,10 +714,10 @@ void connection::send_http_response() { template void connection::start() { - m_alog.write(log::alevel::devel,"connection start"); + m_alog->write(log::alevel::devel,"connection start"); if (m_internal_state != istate::USER_INIT) { - m_alog.write(log::alevel::devel,"Start called in invalid state"); + m_alog->write(log::alevel::devel,"Start called in invalid state"); this->terminate(error::make_error_code(error::invalid_state)); return; } @@ -738,12 +738,12 @@ void connection::start() { template void connection::handle_transport_init(lib::error_code const & ec) { - m_alog.write(log::alevel::devel,"connection handle_transport_init"); + m_alog->write(log::alevel::devel,"connection handle_transport_init"); lib::error_code ecm = ec; if (m_internal_state != istate::TRANSPORT_INIT) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_transport_init must be called from transport init state"); ecm = error::make_error_code(error::invalid_state); } @@ -751,7 +751,7 @@ void connection::handle_transport_init(lib::error_code const & ec) { if (ecm) { std::stringstream s; s << "handle_transport_init received error: "<< ecm.message(); - m_elog.write(log::elevel::rerror,s.str()); + m_elog->write(log::elevel::rerror,s.str()); this->terminate(ecm); return; @@ -772,7 +772,7 @@ void connection::handle_transport_init(lib::error_code const & ec) { template void connection::read_handshake(size_t num_bytes) { - m_alog.write(log::alevel::devel,"connection read_handshake"); + m_alog->write(log::alevel::devel,"connection read_handshake"); if (m_open_handshake_timeout_dur > 0) { m_handshake_timer = transport_con_type::set_timer( @@ -804,7 +804,7 @@ template void connection::handle_read_handshake(lib::error_code const & ec, size_t bytes_transferred) { - m_alog.write(log::alevel::devel,"connection handle_read_handshake"); + m_alog->write(log::alevel::devel,"connection handle_read_handshake"); lib::error_code ecm = ec; @@ -819,7 +819,7 @@ void connection::handle_read_handshake(lib::error_code const & ec, // The connection was canceled while the response was being sent, // usually by the handshake timer. This is basically expected // (though hopefully rare) and there is nothing we can do so ignore. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_read_handshake invoked after connection was closed"); return; } else { @@ -828,9 +828,9 @@ void connection::handle_read_handshake(lib::error_code const & ec, } if (ecm) { - if (ecm.value() == (int) transport::error::eof && m_state == session::state::closed) { + if (ecm == transport::error::eof && m_state == session::state::closed) { // we expect to get eof if the connection is closed already - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "got (expected) eof/state error from closed con"); return; } @@ -842,7 +842,7 @@ void connection::handle_read_handshake(lib::error_code const & ec, // Boundaries checking. TODO: How much of this should be done? if (bytes_transferred > config::connection_read_buffer_size) { - m_elog.write(log::elevel::fatal,"Fatal boundaries checking error."); + m_elog->write(log::elevel::fatal,"Fatal boundaries checking error."); this->terminate(make_error_code(error::general)); return; } @@ -861,16 +861,16 @@ void connection::handle_read_handshake(lib::error_code const & ec, // More paranoid boundaries checking. // TODO: Is this overkill? if (bytes_processed > bytes_transferred) { - m_elog.write(log::elevel::fatal,"Fatal boundaries checking error."); + m_elog->write(log::elevel::fatal,"Fatal boundaries checking error."); this->terminate(make_error_code(error::general)); return; } - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "bytes_transferred: " << bytes_transferred << " bytes, bytes processed: " << bytes_processed << " bytes"; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } if (m_request.ready()) { @@ -891,17 +891,17 @@ void connection::handle_read_handshake(lib::error_code const & ec, bytes_processed += 8; } else { // TODO: need more bytes - m_alog.write(log::alevel::devel,"short key3 read"); + m_alog->write(log::alevel::devel,"short key3 read"); m_response.set_status(http::status_code::internal_server_error); this->write_http_response_error(processor::error::make_error_code(processor::error::short_key3)); return; } } - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,m_request.raw()); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,m_request.raw()); if (!m_request.get_header("Sec-WebSocket-Key3").empty()) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, utility::to_hex(m_request.get_header("Sec-WebSocket-Key3"))); } } @@ -948,7 +948,7 @@ void connection::handle_read_handshake(lib::error_code const & ec, template void connection::write_http_response_error(lib::error_code const & ec) { if (m_internal_state != istate::READ_HTTP_REQUEST) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "write_http_response_error called in invalid state"); this->terminate(error::make_error_code(error::invalid_state)); return; @@ -965,7 +965,7 @@ template void connection::handle_read_frame(lib::error_code const & ec, size_t bytes_transferred) { - //m_alog.write(log::alevel::devel,"connection handle_read_frame"); + //m_alog->write(log::alevel::devel,"connection handle_read_frame"); lib::error_code ecm = ec; @@ -976,11 +976,11 @@ void connection::handle_read_frame(lib::error_code const & ec, if (ecm) { log::level echannel = log::elevel::rerror; - if (ecm.value() == (int) transport::error::eof) { + if (ecm == transport::error::eof) { if (m_state == session::state::closed) { // we expect to get eof if the connection is closed already // just ignore it - m_alog.write(log::alevel::devel,"got eof from closed con"); + m_alog->write(log::alevel::devel,"got eof from closed con"); return; } else if (m_state == session::state::closing && !m_is_server) { // If we are a client we expect to get eof in the closing state, @@ -989,29 +989,26 @@ void connection::handle_read_frame(lib::error_code const & ec, terminate(lib::error_code()); return; } - } else if (ecm.value() == (int) error::invalid_state) { + } else if (ecm == error::invalid_state) { // In general, invalid state errors in the closed state are the // result of handlers that were in the system already when the state // changed and should be ignored as they pose no problems and there // is nothing useful that we can do about them. if (m_state == session::state::closed) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_read_frame: got invalid istate in closed state"); return; } - } else if (ecm.value() == (int) transport::error::tls_short_read) { - if (m_state == session::state::closed) { - // We expect to get a TLS short read if we try to read after the - // connection is closed. If this happens ignore and exit the - // read frame path. - terminate(lib::error_code()); - return; - } - echannel = log::elevel::rerror; - } else if (ecm.value() == (int) transport::error::action_after_shutdown) { + } else if (ecm == transport::error::action_after_shutdown) { echannel = log::elevel::info; + } else { + // TODO: more generally should we do something different here in the + // case that m_state is cosed? Are errors after the connection is + // already closed really an rerror? } + + log_err(echannel, "handle_read_frame", ecm); this->terminate(ecm); return; @@ -1019,32 +1016,32 @@ void connection::handle_read_frame(lib::error_code const & ec, // Boundaries checking. TODO: How much of this should be done? /*if (bytes_transferred > config::connection_read_buffer_size) { - m_elog.write(log::elevel::fatal,"Fatal boundaries checking error"); + m_elog->write(log::elevel::fatal,"Fatal boundaries checking error"); this->terminate(make_error_code(error::general)); return; }*/ size_t p = 0; - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "p = " << p << " bytes transferred = " << bytes_transferred; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } while (p < bytes_transferred) { - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "calling consume with " << bytes_transferred-p << " bytes"; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } lib::error_code consume_ec; - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "Processing Bytes: " << utility::to_hex(reinterpret_cast(m_buf)+p,bytes_transferred-p); - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } p += m_processor->consume( @@ -1053,10 +1050,10 @@ void connection::handle_read_frame(lib::error_code const & ec, consume_ec ); - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "bytes left after consume: " << bytes_transferred-p; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } if (consume_ec) { log_err(log::elevel::rerror, "consume", consume_ec); @@ -1082,20 +1079,20 @@ void connection::handle_read_frame(lib::error_code const & ec, } if (m_processor->ready()) { - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "Complete message received. Dispatching"; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } message_ptr msg = m_processor->get_message(); if (!msg) { - m_alog.write(log::alevel::devel, "null message from m_processor"); + m_alog->write(log::alevel::devel, "null message from m_processor"); } else if (!is_control(msg->get_opcode())) { // data message, dispatch to user if (m_state != session::state::open) { - m_elog.write(log::elevel::warn, "got non-close frame while closing"); + m_elog->write(log::elevel::warn, "got non-close frame while closing"); } else if (m_message_handler) { m_message_handler(m_connection_hdl, msg); } @@ -1132,7 +1129,7 @@ void connection::read_frame() { template lib::error_code connection::initialize_processor() { - m_alog.write(log::alevel::devel,"initialize_processor"); + m_alog->write(log::alevel::devel,"initialize_processor"); // if it isn't a websocket handshake nothing to do. if (!processor::is_websocket_handshake(m_request)) { @@ -1142,7 +1139,7 @@ lib::error_code connection::initialize_processor() { int version = processor::get_websocket_version(m_request); if (version < 0) { - m_alog.write(log::alevel::devel, "BAD REQUEST: can't determine version"); + m_alog->write(log::alevel::devel, "BAD REQUEST: can't determine version"); m_response.set_status(http::status_code::bad_request); return error::make_error_code(error::invalid_version); } @@ -1156,7 +1153,7 @@ lib::error_code connection::initialize_processor() { // We don't have a processor for this version. Return bad request // with Sec-WebSocket-Version header filled with values we do accept - m_alog.write(log::alevel::devel, "BAD REQUEST: no processor for version"); + m_alog->write(log::alevel::devel, "BAD REQUEST: no processor for version"); m_response.set_status(http::status_code::bad_request); std::stringstream ss; @@ -1174,11 +1171,11 @@ lib::error_code connection::initialize_processor() { template lib::error_code connection::process_handshake_request() { - m_alog.write(log::alevel::devel,"process handshake request"); + m_alog->write(log::alevel::devel,"process handshake request"); if (!processor::is_websocket_handshake(m_request)) { // this is not a websocket handshake. Process as plain HTTP - m_alog.write(log::alevel::devel,"HTTP REQUEST"); + m_alog->write(log::alevel::devel,"HTTP REQUEST"); // extract URI from request m_uri = processor::get_uri_from_host( @@ -1187,7 +1184,7 @@ lib::error_code connection::process_handshake_request() { ); if (!m_uri->get_valid()) { - m_alog.write(log::alevel::devel, "Bad request: failed to parse uri"); + m_alog->write(log::alevel::devel, "Bad request: failed to parse uri"); m_response.set_status(http::status_code::bad_request); return error::make_error_code(error::invalid_uri); } @@ -1212,7 +1209,7 @@ lib::error_code connection::process_handshake_request() { // Validate: make sure all required elements are present. if (ec){ // Not a valid handshake request - m_alog.write(log::alevel::devel, "Bad request " + ec.message()); + m_alog->write(log::alevel::devel, "Bad request " + ec.message()); m_response.set_status(http::status_code::bad_request); return ec; } @@ -1222,12 +1219,18 @@ lib::error_code connection::process_handshake_request() { std::pair neg_results; neg_results = m_processor->negotiate_extensions(m_request); - if (neg_results.first) { + if (neg_results.first == processor::error::make_error_code(processor::error::extension_parse_error)) { // There was a fatal error in extension parsing that should result in // a failed connection attempt. - m_alog.write(log::alevel::devel, "Bad request: " + neg_results.first.message()); + m_elog->write(log::elevel::info, "Bad request: " + neg_results.first.message()); m_response.set_status(http::status_code::bad_request); return neg_results.first; + } else if (neg_results.first) { + // There was a fatal error in extension processing that is probably our + // fault. Consider extension negotiation to have failed and continue as + // if extensions were not supported + m_elog->write(log::elevel::info, + "Extension negotiation failed: " + neg_results.first.message()); } else { // extension negotiation succeeded, set response header accordingly // we don't send an empty extensions header because it breaks many @@ -1243,7 +1246,7 @@ lib::error_code connection::process_handshake_request() { if (!m_uri->get_valid()) { - m_alog.write(log::alevel::devel, "Bad request: failed to parse uri"); + m_alog->write(log::alevel::devel, "Bad request: failed to parse uri"); m_response.set_status(http::status_code::bad_request); return error::make_error_code(error::invalid_uri); } @@ -1267,14 +1270,14 @@ lib::error_code connection::process_handshake_request() { if (ec) { std::stringstream s; s << "Processing error: " << ec << "(" << ec.message() << ")"; - m_alog.write(log::alevel::devel, s.str()); + m_alog->write(log::alevel::devel, s.str()); m_response.set_status(http::status_code::internal_server_error); return ec; } } else { // User application has rejected the handshake - m_alog.write(log::alevel::devel, "USER REJECT"); + m_alog->write(log::alevel::devel, "USER REJECT"); // Use Bad Request if the user handler did not provide a more // specific http response error code. @@ -1291,10 +1294,10 @@ lib::error_code connection::process_handshake_request() { template void connection::write_http_response(lib::error_code const & ec) { - m_alog.write(log::alevel::devel,"connection write_http_response"); + m_alog->write(log::alevel::devel,"connection write_http_response"); if (ec == error::make_error_code(error::http_connection_ended)) { - m_alog.write(log::alevel::http,"An HTTP handler took over the connection."); + m_alog->write(log::alevel::http,"An HTTP handler took over the connection."); return; } @@ -1324,10 +1327,10 @@ void connection::write_http_response(lib::error_code const & ec) { m_handshake_buffer = m_response.raw(); } - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"Raw Handshake response:\n"+m_handshake_buffer); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"Raw Handshake response:\n"+m_handshake_buffer); if (!m_response.get_header("Sec-WebSocket-Key3").empty()) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, utility::to_hex(m_response.get_header("Sec-WebSocket-Key3"))); } } @@ -1346,7 +1349,7 @@ void connection::write_http_response(lib::error_code const & ec) { template void connection::handle_write_http_response(lib::error_code const & ec) { - m_alog.write(log::alevel::devel,"handle_write_http_response"); + m_alog->write(log::alevel::devel,"handle_write_http_response"); lib::error_code ecm = ec; @@ -1361,7 +1364,7 @@ void connection::handle_write_http_response(lib::error_code const & ec) // The connection was canceled while the response was being sent, // usually by the handshake timer. This is basically expected // (though hopefully rare) and there is nothing we can do so ignore. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_write_http_response invoked after connection was closed"); return; } else { @@ -1370,9 +1373,9 @@ void connection::handle_write_http_response(lib::error_code const & ec) } if (ecm) { - if (ecm.value() == (int) transport::error::eof && m_state == session::state::closed) { + if (ecm == transport::error::eof && m_state == session::state::closed) { // we expect to get eof if the connection is closed already - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "got (expected) eof/state error from closed con"); return; } @@ -1397,7 +1400,7 @@ void connection::handle_write_http_response(lib::error_code const & ec) std::stringstream s; s << "Handshake ended with HTTP error: " << m_response.get_status_code(); - m_elog.write(log::elevel::rerror,s.str()); + m_elog->write(log::elevel::rerror,s.str()); } else { // if this was not a websocket connection, we have written // the expected response and the connection can be closed. @@ -1405,7 +1408,7 @@ void connection::handle_write_http_response(lib::error_code const & ec) this->log_http_result(); if (m_ec) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "got to writing HTTP results with m_ec set: "+m_ec.message()); } m_ec = make_error_code(error::http_connection_ended); @@ -1429,7 +1432,7 @@ void connection::handle_write_http_response(lib::error_code const & ec) template void connection::send_http_request() { - m_alog.write(log::alevel::devel,"connection send_http_request"); + m_alog->write(log::alevel::devel,"connection send_http_request"); // TODO: origin header? @@ -1445,7 +1448,7 @@ void connection::send_http_request() { return; } } else { - m_elog.write(log::elevel::fatal,"Internal library error: missing processor"); + m_elog->write(log::elevel::fatal,"Internal library error: missing processor"); return; } @@ -1460,8 +1463,8 @@ void connection::send_http_request() { m_handshake_buffer = m_request.raw(); - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"Raw Handshake request:\n"+m_handshake_buffer); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"Raw Handshake request:\n"+m_handshake_buffer); } if (m_open_handshake_timeout_dur > 0) { @@ -1488,7 +1491,7 @@ void connection::send_http_request() { template void connection::handle_send_http_request(lib::error_code const & ec) { - m_alog.write(log::alevel::devel,"handle_send_http_request"); + m_alog->write(log::alevel::devel,"handle_send_http_request"); lib::error_code ecm = ec; @@ -1505,7 +1508,7 @@ void connection::handle_send_http_request(lib::error_code const & ec) { // The connection was canceled while the response was being sent, // usually by the handshake timer. This is basically expected // (though hopefully rare) and there is nothing we can do so ignore. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_send_http_request invoked after connection was closed"); return; } else { @@ -1514,9 +1517,9 @@ void connection::handle_send_http_request(lib::error_code const & ec) { } if (ecm) { - if (ecm.value() == (int) transport::error::eof && m_state == session::state::closed) { + if (ecm == transport::error::eof && m_state == session::state::closed) { // we expect to get eof if the connection is closed already - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "got (expected) eof/state error from closed con"); return; } @@ -1543,7 +1546,7 @@ template void connection::handle_read_http_response(lib::error_code const & ec, size_t bytes_transferred) { - m_alog.write(log::alevel::devel,"handle_read_http_response"); + m_alog->write(log::alevel::devel,"handle_read_http_response"); lib::error_code ecm = ec; @@ -1558,7 +1561,7 @@ void connection::handle_read_http_response(lib::error_code const & ec, // The connection was canceled while the response was being sent, // usually by the handshake timer. This is basically expected // (though hopefully rare) and there is nothing we can do so ignore. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_read_http_response invoked after connection was closed"); return; } else { @@ -1567,9 +1570,9 @@ void connection::handle_read_http_response(lib::error_code const & ec, } if (ecm) { - if (ecm.value() == (int) transport::error::eof && m_state == session::state::closed) { + if (ecm == transport::error::eof && m_state == session::state::closed) { // we expect to get eof if the connection is closed already - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "got (expected) eof/state error from closed con"); return; } @@ -1584,13 +1587,13 @@ void connection::handle_read_http_response(lib::error_code const & ec, try { bytes_processed = m_response.consume(m_buf,bytes_transferred); } catch (http::exception & e) { - m_elog.write(log::elevel::rerror, + m_elog->write(log::elevel::rerror, std::string("error in handle_read_http_response: ")+e.what()); this->terminate(make_error_code(error::general)); return; } - m_alog.write(log::alevel::devel,std::string("Raw response: ")+m_response.raw()); + m_alog->write(log::alevel::devel,std::string("Raw response: ")+m_response.raw()); if (m_response.headers_ready()) { if (m_handshake_timer) { @@ -1621,7 +1624,7 @@ void connection::handle_read_http_response(lib::error_code const & ec, // doesn't match the options requested by the client. Its possible // that the best behavior in this cases is to log and continue with // an unextended connection. - m_alog.write(log::alevel::devel, "Extension negotiation failed: " + m_alog->write(log::alevel::devel, "Extension negotiation failed: " + neg_results.first.message()); this->terminate(make_error_code(error::extension_neg_failed)); // TODO: close connection with reason 1010 (and list extensions) @@ -1663,14 +1666,14 @@ template void connection::handle_open_handshake_timeout( lib::error_code const & ec) { - if (ec.value() == (int) transport::error::operation_aborted) { - m_alog.write(log::alevel::devel,"open handshake timer cancelled"); + if (ec == transport::error::operation_aborted) { + m_alog->write(log::alevel::devel,"open handshake timer cancelled"); } else if (ec) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "open handle_open_handshake_timeout error: "+ec.message()); // TODO: ignore or fail here? } else { - m_alog.write(log::alevel::devel,"open handshake timer expired"); + m_alog->write(log::alevel::devel,"open handshake timer expired"); terminate(make_error_code(error::open_handshake_timeout)); } } @@ -1679,22 +1682,22 @@ template void connection::handle_close_handshake_timeout( lib::error_code const & ec) { - if (ec.value() == (int) transport::error::operation_aborted) { - m_alog.write(log::alevel::devel,"asio close handshake timer cancelled"); + if (ec == transport::error::operation_aborted) { + m_alog->write(log::alevel::devel,"asio close handshake timer cancelled"); } else if (ec) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "asio open handle_close_handshake_timeout error: "+ec.message()); // TODO: ignore or fail here? } else { - m_alog.write(log::alevel::devel, "asio close handshake timer expired"); + m_alog->write(log::alevel::devel, "asio close handshake timer expired"); terminate(make_error_code(error::close_handshake_timeout)); } } template void connection::terminate(lib::error_code const & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection terminate"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection terminate"); } // Cancel close handshake timer @@ -1720,14 +1723,14 @@ void connection::terminate(lib::error_code const & ec) { // Log fail result here before socket is shut down and we can't get // the remote address, etc anymore - if (m_ec.value() != (int) error::http_connection_ended) { + if (m_ec != error::http_connection_ended) { log_fail_result(); } } else if (m_state != session::state::closed) { m_state = session::state::closed; tstat = closed; } else { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "terminate called on connection that was already terminated"); return; } @@ -1748,8 +1751,8 @@ template void connection::handle_terminate(terminate_status tstat, lib::error_code const & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection handle_terminate"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection handle_terminate"); } if (ec) { @@ -1759,7 +1762,7 @@ void connection::handle_terminate(terminate_status tstat, // clean shutdown if (tstat == failed) { - if (m_ec.value() != (int) error::http_connection_ended) { + if (m_ec != error::http_connection_ended) { if (m_fail_handler) { m_fail_handler(m_connection_hdl); } @@ -1770,7 +1773,7 @@ void connection::handle_terminate(terminate_status tstat, } log_close_result(); } else { - m_elog.write(log::elevel::rerror,"Unknown terminate_status"); + m_elog->write(log::elevel::rerror,"Unknown terminate_status"); } // call the termination handler if it exists @@ -1780,7 +1783,7 @@ void connection::handle_terminate(terminate_status tstat, try { m_termination_handler(type::get_shared()); } catch (std::exception const & e) { - m_elog.write(log::elevel::warn, + m_elog->write(log::elevel::warn, std::string("termination_handler call failed. Reason was: ")+e.what()); } } @@ -1788,7 +1791,7 @@ void connection::handle_terminate(terminate_status tstat, template void connection::write_frame() { - //m_alog.write(log::alevel::devel,"connection write_frame"); + //m_alog->write(log::alevel::devel,"connection write_frame"); { scoped_lock_type lock(m_write_lock); @@ -1834,8 +1837,8 @@ void connection::write_frame() { } // Print detailed send stats if those log levels are enabled - if (m_alog.static_test(log::alevel::frame_header)) { - if (m_alog.dynamic_test(log::alevel::frame_header)) { + if (m_alog->static_test(log::alevel::frame_header)) { + if (m_alog->dynamic_test(log::alevel::frame_header)) { std::stringstream general,header,payload; general << "Dispatching write containing " << m_current_msgs.size() @@ -1855,8 +1858,8 @@ void connection::write_frame() { << m_current_msgs[i]->get_header().size() << ") " << utility::to_hex(m_current_msgs[i]->get_header()) << "\n"; - if (m_alog.static_test(log::alevel::frame_payload)) { - if (m_alog.dynamic_test(log::alevel::frame_payload)) { + if (m_alog->static_test(log::alevel::frame_payload)) { + if (m_alog->dynamic_test(log::alevel::frame_payload)) { payload << "[" << i << "] (" << m_current_msgs[i]->get_payload().size() << ") ["<get_opcode()<<"] " << (m_current_msgs[i]->get_opcode() == frame::opcode::text ? @@ -1870,9 +1873,9 @@ void connection::write_frame() { general << hbytes << " header bytes and " << pbytes << " payload bytes"; - m_alog.write(log::alevel::frame_header,general.str()); - m_alog.write(log::alevel::frame_header,header.str()); - m_alog.write(log::alevel::frame_payload,payload.str()); + m_alog->write(log::alevel::frame_header,general.str()); + m_alog->write(log::alevel::frame_header,header.str()); + m_alog->write(log::alevel::frame_payload,payload.str()); } } @@ -1885,8 +1888,8 @@ void connection::write_frame() { template void connection::handle_write_frame(lib::error_code const & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"connection handle_write_frame"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"connection handle_write_frame"); } bool terminal = m_current_msgs.back()->get_terminal(); @@ -1933,21 +1936,21 @@ std::vector const & connection::get_supported_versions() const template void connection::process_control_frame(typename config::message_type::ptr msg) { - m_alog.write(log::alevel::devel,"process_control_frame"); + m_alog->write(log::alevel::devel,"process_control_frame"); frame::opcode::value op = msg->get_opcode(); lib::error_code ec; std::stringstream s; s << "Control frame received with opcode " << op; - m_alog.write(log::alevel::control,s.str()); + m_alog->write(log::alevel::control,s.str()); if (m_state == session::state::closed) { - m_elog.write(log::elevel::warn,"got frame in state closed"); + m_elog->write(log::elevel::warn,"got frame in state closed"); return; } if (op != frame::opcode::CLOSE && m_state != session::state::open) { - m_elog.write(log::elevel::warn,"got non-close frame in state closing"); + m_elog->write(log::elevel::warn,"got non-close frame in state closing"); return; } @@ -1972,7 +1975,7 @@ void connection::process_control_frame(typename config::message_type::pt m_ping_timer->cancel(); } } else if (op == frame::opcode::CLOSE) { - m_alog.write(log::alevel::devel,"got close frame"); + m_alog->write(log::alevel::devel,"got close frame"); // record close code and reason somewhere m_remote_close_code = close::extract_code(msg->get_payload(),ec); @@ -1981,12 +1984,12 @@ void connection::process_control_frame(typename config::message_type::pt if (config::drop_on_protocol_error) { s << "Received invalid close code " << m_remote_close_code << " dropping connection per config."; - m_elog.write(log::elevel::devel,s.str()); + m_elog->write(log::elevel::devel,s.str()); this->terminate(ec); } else { s << "Received invalid close code " << m_remote_close_code << " sending acknowledgement and closing"; - m_elog.write(log::elevel::devel,s.str()); + m_elog->write(log::elevel::devel,s.str()); ec = send_close_ack(close::status::protocol_error, "Invalid close code"); if (ec) { @@ -1999,11 +2002,11 @@ void connection::process_control_frame(typename config::message_type::pt m_remote_close_reason = close::extract_reason(msg->get_payload(),ec); if (ec) { if (config::drop_on_protocol_error) { - m_elog.write(log::elevel::devel, + m_elog->write(log::elevel::devel, "Received invalid close reason. Dropping connection per config"); this->terminate(ec); } else { - m_elog.write(log::elevel::devel, + m_elog->write(log::elevel::devel, "Received invalid close reason. Sending acknowledgement and closing"); ec = send_close_ack(close::status::protocol_error, "Invalid close reason"); @@ -2018,7 +2021,7 @@ void connection::process_control_frame(typename config::message_type::pt s.str(""); s << "Received close frame with code " << m_remote_close_code << " and reason " << m_remote_close_reason; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); ec = send_close_ack(); if (ec) { @@ -2026,7 +2029,7 @@ void connection::process_control_frame(typename config::message_type::pt } } else if (m_state == session::state::closing && !m_was_clean) { // ack of our close - m_alog.write(log::alevel::devel, "Got acknowledgement of close"); + m_alog->write(log::alevel::devel, "Got acknowledgement of close"); m_was_clean = true; @@ -2042,11 +2045,11 @@ void connection::process_control_frame(typename config::message_type::pt } } else { // spurious, ignore - m_elog.write(log::elevel::devel, "Got close frame in wrong state"); + m_elog->write(log::elevel::devel, "Got close frame in wrong state"); } } else { // got an invalid control opcode - m_elog.write(log::elevel::devel, "Got control frame with invalid opcode"); + m_elog->write(log::elevel::devel, "Got control frame with invalid opcode"); // initiate protocol error shutdown } } @@ -2062,7 +2065,7 @@ template lib::error_code connection::send_close_frame(close::status::value code, std::string const & reason, bool ack, bool terminal) { - m_alog.write(log::alevel::devel,"send_close_frame"); + m_alog->write(log::alevel::devel,"send_close_frame"); // check for special codes @@ -2073,24 +2076,24 @@ lib::error_code connection::send_close_frame(close::status::value code, // send blank info. If it is an ack then echo the close information from // the remote endpoint. if (config::silent_close) { - m_alog.write(log::alevel::devel,"closing silently"); + m_alog->write(log::alevel::devel,"closing silently"); m_local_close_code = close::status::no_status; m_local_close_reason.clear(); } else if (code != close::status::blank) { - m_alog.write(log::alevel::devel,"closing with specified codes"); + m_alog->write(log::alevel::devel,"closing with specified codes"); m_local_close_code = code; m_local_close_reason = reason; } else if (!ack) { - m_alog.write(log::alevel::devel,"closing with no status code"); + m_alog->write(log::alevel::devel,"closing with no status code"); m_local_close_code = close::status::no_status; m_local_close_reason.clear(); } else if (m_remote_close_code == close::status::no_status) { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "acknowledging a no-status close with normal code"); m_local_close_code = close::status::normal; m_local_close_reason.clear(); } else { - m_alog.write(log::alevel::devel,"acknowledging with remote codes"); + m_alog->write(log::alevel::devel,"acknowledging with remote codes"); m_local_close_code = m_remote_close_code; m_local_close_reason = m_remote_close_reason; } @@ -2098,7 +2101,7 @@ lib::error_code connection::send_close_frame(close::status::value code, std::stringstream s; s << "Closing with code: " << m_local_close_code << ", and reason: " << m_local_close_reason; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); message_ptr msg = m_msg_manager->get_message(); if (!msg) { @@ -2213,11 +2216,11 @@ void connection::write_push(typename config::message_type::ptr msg) m_send_buffer_size += msg->get_payload().size(); m_send_queue.push(msg); - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "write_push: message count: " << m_send_queue.size() << " buffer size: " << m_send_buffer_size; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } } @@ -2235,11 +2238,11 @@ typename config::message_type::ptr connection::write_pop() m_send_buffer_size -= msg->get_payload().size(); m_send_queue.pop(); - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "write_pop: message count: " << m_send_queue.size() << " buffer size: " << m_send_buffer_size; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } return msg; } @@ -2282,7 +2285,7 @@ void connection::log_open_result() // Status code s << m_response.get_status_code(); - m_alog.write(log::alevel::connect,s.str()); + m_alog->write(log::alevel::connect,s.str()); } template @@ -2296,7 +2299,7 @@ void connection::log_close_result() << "] remote:[" << m_remote_close_code << (m_remote_close_reason.empty() ? "" : ","+m_remote_close_reason) << "]"; - m_alog.write(log::alevel::disconnect,s.str()); + m_alog->write(log::alevel::disconnect,s.str()); } template @@ -2335,7 +2338,7 @@ void connection::log_fail_result() // WebSocket++ error code & reason s << " " << m_ec << " " << m_ec.message(); - m_alog.write(log::alevel::fail,s.str()); + m_alog->write(log::alevel::fail,s.str()); } template @@ -2343,7 +2346,7 @@ void connection::log_http_result() { std::stringstream s; if (processor::is_websocket_handshake(m_request)) { - m_alog.write(log::alevel::devel,"Call to log_http_result for WebSocket"); + m_alog->write(log::alevel::devel,"Call to log_http_result for WebSocket"); return; } @@ -2364,7 +2367,7 @@ void connection::log_http_result() { s << " \"" << utility::string_replace_all(ua,"\"","\\\"") << "\" "; } - m_alog.write(log::alevel::http,s.str()); + m_alog->write(log::alevel::http,s.str()); } } // namespace websocketpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/impl/endpoint_impl.hpp b/src/3rdparty/include/websocketpp/impl/endpoint_impl.hpp similarity index 97% rename from src/plugins/server/3rdparty/include/websocketpp/impl/endpoint_impl.hpp rename to src/3rdparty/include/websocketpp/impl/endpoint_impl.hpp index e09cda95e..2aac1d9da 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/impl/endpoint_impl.hpp +++ b/src/3rdparty/include/websocketpp/impl/endpoint_impl.hpp @@ -35,7 +35,7 @@ namespace websocketpp { template typename endpoint::connection_ptr endpoint::create_connection() { - m_alog.write(log::alevel::devel,"create_connection"); + m_alog->write(log::alevel::devel,"create_connection"); //scoped_lock_type lock(m_state_lock); /*if (m_state == STOPPING || m_state == STOPPED) { @@ -45,7 +45,7 @@ endpoint::create_connection() { //scoped_lock_type guard(m_mutex); // Create a connection on the heap and manage it using a shared pointer connection_ptr con = lib::make_shared(m_is_server, - m_user_agent, lib::ref(m_alog), lib::ref(m_elog), lib::ref(m_rng)); + m_user_agent, m_alog, m_elog, lib::ref(m_rng)); connection_weak_ptr w(con); @@ -85,7 +85,7 @@ endpoint::create_connection() { ec = transport_type::init(con); if (ec) { - m_elog.write(log::elevel::fatal,ec.message()); + m_elog->write(log::elevel::fatal,ec.message()); return connection_ptr(); } @@ -98,7 +98,7 @@ void endpoint::interrupt(connection_hdl hdl, lib::error_code connection_ptr con = get_con_from_hdl(hdl,ec); if (ec) {return;} - m_alog.write(log::alevel::devel,"Interrupting connection"); + m_alog->write(log::alevel::devel,"Interrupting connection"); ec = con->interrupt(); } diff --git a/src/plugins/server/3rdparty/include/websocketpp/impl/utilities_impl.hpp b/src/3rdparty/include/websocketpp/impl/utilities_impl.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/impl/utilities_impl.hpp rename to src/3rdparty/include/websocketpp/impl/utilities_impl.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/logger/basic.hpp b/src/3rdparty/include/websocketpp/logger/basic.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/logger/basic.hpp rename to src/3rdparty/include/websocketpp/logger/basic.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/logger/levels.hpp b/src/3rdparty/include/websocketpp/logger/levels.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/logger/levels.hpp rename to src/3rdparty/include/websocketpp/logger/levels.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/logger/stub.hpp b/src/3rdparty/include/websocketpp/logger/stub.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/logger/stub.hpp rename to src/3rdparty/include/websocketpp/logger/stub.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/logger/syslog.hpp b/src/3rdparty/include/websocketpp/logger/syslog.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/logger/syslog.hpp rename to src/3rdparty/include/websocketpp/logger/syslog.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/message_buffer/alloc.hpp b/src/3rdparty/include/websocketpp/message_buffer/alloc.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/message_buffer/alloc.hpp rename to src/3rdparty/include/websocketpp/message_buffer/alloc.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/message_buffer/message.hpp b/src/3rdparty/include/websocketpp/message_buffer/message.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/message_buffer/message.hpp rename to src/3rdparty/include/websocketpp/message_buffer/message.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/message_buffer/pool.hpp b/src/3rdparty/include/websocketpp/message_buffer/pool.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/message_buffer/pool.hpp rename to src/3rdparty/include/websocketpp/message_buffer/pool.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/base.hpp b/src/3rdparty/include/websocketpp/processors/base.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/processors/base.hpp rename to src/3rdparty/include/websocketpp/processors/base.hpp index ddb8b81a4..4c123dfab 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/processors/base.hpp +++ b/src/3rdparty/include/websocketpp/processors/base.hpp @@ -44,7 +44,7 @@ namespace processor { namespace constants { static char const upgrade_token[] = "websocket"; -static char const connection_token[] = "upgrade"; +static char const connection_token[] = "Upgrade"; static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; } // namespace constants diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/hybi00.hpp b/src/3rdparty/include/websocketpp/processors/hybi00.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/processors/hybi00.hpp rename to src/3rdparty/include/websocketpp/processors/hybi00.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/hybi07.hpp b/src/3rdparty/include/websocketpp/processors/hybi07.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/processors/hybi07.hpp rename to src/3rdparty/include/websocketpp/processors/hybi07.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/hybi08.hpp b/src/3rdparty/include/websocketpp/processors/hybi08.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/processors/hybi08.hpp rename to src/3rdparty/include/websocketpp/processors/hybi08.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/hybi13.hpp b/src/3rdparty/include/websocketpp/processors/hybi13.hpp similarity index 94% rename from src/plugins/server/3rdparty/include/websocketpp/processors/hybi13.hpp rename to src/3rdparty/include/websocketpp/processors/hybi13.hpp index 79486654a..ca1243926 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/processors/hybi13.hpp +++ b/src/3rdparty/include/websocketpp/processors/hybi13.hpp @@ -125,38 +125,60 @@ public: http::parameter_list::const_iterator it; + // look through the list of extension requests to find the first + // one that we can accept. if (m_permessage_deflate.is_implemented()) { err_str_pair neg_ret; for (it = p.begin(); it != p.end(); ++it) { - // look through each extension, if the key is permessage-deflate - if (it->first == "permessage-deflate") { - // if we have already successfully negotiated this extension - // then skip any other requests to negotiate the same one - // with different parameters - if (m_permessage_deflate.is_enabled()) { - continue; - } - - - neg_ret = m_permessage_deflate.negotiate(it->second); + // not a permessage-deflate extension request, ignore + if (it->first != "permessage-deflate") { + continue; + } - if (neg_ret.first) { - // Figure out if this is an error that should halt all - // extension negotiations or simply cause negotiation of - // this specific extension to fail. - //std::cout << "permessage-compress negotiation failed: " - // << neg_ret.first.message() << std::endl; - } else { - // Note: this list will need commas if WebSocket++ ever - // supports more than one extension - ret.second += neg_ret.second; - m_permessage_deflate.init(base::m_server); - continue; - } + // if we have already successfully negotiated this extension + // then skip any other requests to negotiate the same one + // with different parameters + if (m_permessage_deflate.is_enabled()) { + continue; + } + + // attempt to negotiate this offer + neg_ret = m_permessage_deflate.negotiate(it->second); + + if (neg_ret.first) { + // negotiation offer failed. Do nothing. We will continue + // searching for a permessage-deflate config that succeeds + continue; + } + + // Negotiation tentatively succeeded + + // Actually try to initialize the extension before we + // deem negotiation complete + lib::error_code ec = m_permessage_deflate.init(base::m_server); + + if (ec) { + // Negotiation succeeded but initialization failed this is + // an error that should stop negotiation of permessage + // deflate. Return the reason for the init failure + + ret.first = ec; + break; + } else { + // Successfully initialized, push the negotiated response into + // the reply and stop looking for additional permessage-deflate + // extensions + ret.second += neg_ret.second; + break; } } } + // support for future extensions would go here. Should check the value of + // ret.first before continuing. Might need to consider whether failure of + // negotiation of an earlier extension should stop negotiation of subsequent + // ones + return ret; } diff --git a/src/plugins/server/3rdparty/include/websocketpp/processors/processor.hpp b/src/3rdparty/include/websocketpp/processors/processor.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/processors/processor.hpp rename to src/3rdparty/include/websocketpp/processors/processor.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/random/none.hpp b/src/3rdparty/include/websocketpp/random/none.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/random/none.hpp rename to src/3rdparty/include/websocketpp/random/none.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/random/random_device.hpp b/src/3rdparty/include/websocketpp/random/random_device.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/random/random_device.hpp rename to src/3rdparty/include/websocketpp/random/random_device.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/roles/client_endpoint.hpp b/src/3rdparty/include/websocketpp/roles/client_endpoint.hpp similarity index 96% rename from src/plugins/server/3rdparty/include/websocketpp/roles/client_endpoint.hpp rename to src/3rdparty/include/websocketpp/roles/client_endpoint.hpp index 2de1a10ac..4d0c433b0 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/roles/client_endpoint.hpp +++ b/src/3rdparty/include/websocketpp/roles/client_endpoint.hpp @@ -71,7 +71,7 @@ public: explicit client() : endpoint_type(false) { - endpoint_type::m_alog.write(log::alevel::devel, "client constructor"); + endpoint_type::m_alog->write(log::alevel::devel, "client constructor"); } /// Get a new connection @@ -157,10 +157,10 @@ private: if (ec) { con->terminate(ec); - endpoint_type::m_elog.write(log::elevel::rerror, + endpoint_type::m_elog->write(log::elevel::rerror, "handle_connect error: "+ec.message()); } else { - endpoint_type::m_alog.write(log::alevel::connect, + endpoint_type::m_alog->write(log::alevel::connect, "Successful connection"); con->start(); diff --git a/src/plugins/server/3rdparty/include/websocketpp/roles/server_endpoint.hpp b/src/3rdparty/include/websocketpp/roles/server_endpoint.hpp similarity index 92% rename from src/plugins/server/3rdparty/include/websocketpp/roles/server_endpoint.hpp rename to src/3rdparty/include/websocketpp/roles/server_endpoint.hpp index 25b9d6771..9cc652f75 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/roles/server_endpoint.hpp +++ b/src/3rdparty/include/websocketpp/roles/server_endpoint.hpp @@ -68,7 +68,7 @@ public: explicit server() : endpoint_type(true) { - endpoint_type::m_alog.write(log::alevel::devel, "server constructor"); + endpoint_type::m_alog->write(log::alevel::devel, "server constructor"); } /// Destructor @@ -77,7 +77,7 @@ public: #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ // no copy constructor because endpoints are not copyable server(server &) = delete; - + // no copy assignment operator because endpoints are not copyable server & operator=(server const &) = delete; #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ @@ -115,7 +115,7 @@ public: * * Refer to documentation for the transport policy you are using for * instructions on how to stop this acceptance loop. - * + * * @param [out] ec A status code indicating an error, if any. */ void start_accept(lib::error_code & ec) { @@ -126,13 +126,18 @@ public: ec = lib::error_code(); connection_ptr con = get_connection(); - + + if (!con) { + ec = error::make_error_code(error::con_creation_failed); + return; + } + transport_type::async_accept( lib::static_pointer_cast(con), lib::bind(&type::handle_accept,this,con,lib::placeholders::_1), ec ); - + if (ec && con) { // If the connection was constructed but the accept failed, // terminate the connection to prevent memory leaks @@ -162,11 +167,11 @@ public: if (ec) { con->terminate(ec); - if (ec.value() == (int) error::operation_canceled) { - endpoint_type::m_elog.write(log::elevel::info, + if (ec == error::operation_canceled) { + endpoint_type::m_elog->write(log::elevel::info, "handle_accept error: "+ec.message()); } else { - endpoint_type::m_elog.write(log::elevel::rerror, + endpoint_type::m_elog->write(log::elevel::rerror, "handle_accept error: "+ec.message()); } } else { @@ -175,11 +180,11 @@ public: lib::error_code start_ec; start_accept(start_ec); - if (start_ec.value() == (int) error::async_accept_not_listening) { - endpoint_type::m_elog.write(log::elevel::info, + if (start_ec == error::async_accept_not_listening) { + endpoint_type::m_elog->write(log::elevel::info, "Stopping acceptance of new connections because the underlying transport is no longer listening."); } else if (start_ec) { - endpoint_type::m_elog.write(log::elevel::rerror, + endpoint_type::m_elog->write(log::elevel::rerror, "Restarting async_accept loop failed: "+ec.message()); } } diff --git a/src/plugins/server/3rdparty/include/websocketpp/server.hpp b/src/3rdparty/include/websocketpp/server.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/server.hpp rename to src/3rdparty/include/websocketpp/server.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/sha1/sha1.hpp b/src/3rdparty/include/websocketpp/sha1/sha1.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/sha1/sha1.hpp rename to src/3rdparty/include/websocketpp/sha1/sha1.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/base.hpp b/src/3rdparty/include/websocketpp/transport/asio/base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/base.hpp rename to src/3rdparty/include/websocketpp/transport/asio/base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/connection.hpp b/src/3rdparty/include/websocketpp/transport/asio/connection.hpp similarity index 88% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/connection.hpp rename to src/3rdparty/include/websocketpp/transport/asio/connection.hpp index 36c1cafcf..57dda74a2 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/connection.hpp +++ b/src/3rdparty/include/websocketpp/transport/asio/connection.hpp @@ -98,12 +98,12 @@ public: friend class endpoint; // generate and manage our own io_service - explicit connection(bool is_server, alog_type & alog, elog_type & elog) + explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) : m_is_server(is_server) , m_alog(alog) , m_elog(elog) { - m_alog.write(log::alevel::devel,"asio con transport constructor"); + m_alog->write(log::alevel::devel,"asio con transport constructor"); } /// Get a shared pointer to this component @@ -120,7 +120,7 @@ public: * Called by the endpoint as a connection is being established to provide * the uri being connected to to the transport layer. * - * This transport policy doesn't use the uri except to forward it to the + * This transport policy doesn't use the uri except to forward it to the * socket layer. * * @since 0.6.0 @@ -284,7 +284,7 @@ public: std::string ret = socket_con_type::get_remote_endpoint(ec); if (ec) { - m_elog.write(log::elevel::info,ret); + m_elog->write(log::elevel::info,ret); return "Unknown"; } else { return ret; @@ -314,7 +314,8 @@ public: timer_ptr new_timer( new lib::asio::steady_timer( *m_io_service, - lib::asio::milliseconds(duration))); + lib::asio::milliseconds(duration)) + ); if (config::enable_multithreading) { new_timer->async_wait(m_strand->wrap(lib::bind( @@ -350,7 +351,7 @@ public: lib::asio::error_code const & ec) { if (ec) { - if (ec.value() == (int) lib::asio::error::operation_aborted) { + if (ec == lib::asio::error::operation_aborted) { callback(make_error_code(transport::error::operation_aborted)); } else { log_err(log::elevel::info,"asio handle_timer",ec); @@ -375,14 +376,14 @@ public: * Primarily used if you are using mismatched asio / system_error * implementations such as `boost::asio` with `std::system_error`. In these * cases the transport error type is different than the library error type - * and some WebSocket++ functions that return transport errors via the + * and some WebSocket++ functions that return transport errors via the * library error code type will be coerced into a catch all `pass_through` - * or `tls_error` error. This method will return the original machine + * or `tls_error` error. This method will return the original machine * readable transport error in the native type. * * @since 0.7.0 * - * @return Error code indicating the reason the connection was closed or + * @return Error code indicating the reason the connection was closed or * failed */ lib::asio::error_code get_transport_ec() const { @@ -408,8 +409,8 @@ public: */ protected: void init(init_handler callback) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection init"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection init"); } // TODO: pre-init timeout. Right now no implemented socket policies @@ -471,8 +472,8 @@ protected: } void handle_pre_init(init_handler callback, lib::error_code const & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection handle pre_init"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection handle pre_init"); } if (m_tcp_pre_init_handler) { @@ -493,12 +494,12 @@ protected: } void post_init(init_handler callback) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection post_init"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection post_init"); } timer_ptr post_timer; - + if (config::timeout_socket_post_init > 0) { post_timer = set_timer( config::timeout_socket_post_init, @@ -538,8 +539,8 @@ protected: lib::error_code ret_ec; if (ec) { - if (ec.value() == (int) transport::error::operation_aborted) { - m_alog.write(log::alevel::devel, + if (ec == transport::error::operation_aborted) { + m_alog->write(log::alevel::devel, "asio post init timer cancelled"); return; } @@ -554,7 +555,7 @@ protected: } } - m_alog.write(log::alevel::devel, "Asio transport post-init timed out"); + m_alog->write(log::alevel::devel, "Asio transport post-init timed out"); cancel_socket_checked(); callback(ret_ec); } @@ -571,10 +572,10 @@ protected: void handle_post_init(timer_ptr post_timer, init_handler callback, lib::error_code const & ec) { - if (ec.value() == (int) transport::error::operation_aborted || + if (ec == transport::error::operation_aborted || (post_timer && lib::asio::is_neg(post_timer->expires_from_now()))) { - m_alog.write(log::alevel::devel,"post_init cancelled"); + m_alog->write(log::alevel::devel,"post_init cancelled"); return; } @@ -582,8 +583,8 @@ protected: post_timer->cancel(); } - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection handle_post_init"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection handle_post_init"); } if (m_tcp_post_init_handler) { @@ -594,12 +595,12 @@ protected: } void proxy_write(init_handler callback) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection proxy_write"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection proxy_write"); } if (!m_proxy_data) { - m_elog.write(log::elevel::library, + m_elog->write(log::elevel::library, "assertion failed: !m_proxy_data in asio::connection::proxy_write"); callback(make_error_code(error::general)); return; @@ -610,7 +611,7 @@ protected: m_bufs.push_back(lib::asio::buffer(m_proxy_data->write_buf.data(), m_proxy_data->write_buf.size())); - m_alog.write(log::alevel::devel,m_proxy_data->write_buf); + m_alog->write(log::alevel::devel,m_proxy_data->write_buf); // Set a timer so we don't wait forever for the proxy to respond m_proxy_data->timer = this->set_timer( @@ -649,15 +650,15 @@ protected: void handle_proxy_timeout(init_handler callback, lib::error_code const & ec) { - if (ec.value() == (int) transport::error::operation_aborted) { - m_alog.write(log::alevel::devel, + if (ec == transport::error::operation_aborted) { + m_alog->write(log::alevel::devel, "asio handle_proxy_write timer cancelled"); return; } else if (ec) { log_err(log::elevel::devel,"asio handle_proxy_write",ec); callback(ec); } else { - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "asio handle_proxy_write timer expired"); cancel_socket_checked(); callback(make_error_code(transport::error::timeout)); @@ -667,8 +668,8 @@ protected: void handle_proxy_write(init_handler callback, lib::asio::error_code const & ec) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel, + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel, "asio connection handle_proxy_write"); } @@ -677,10 +678,10 @@ protected: // Timer expired or the operation was aborted for some reason. // Whatever aborted it will be issuing the callback so we are safe to // return - if (ec.value() == (int) lib::asio::error::operation_aborted || + if (ec == lib::asio::error::operation_aborted || lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) { - m_elog.write(log::elevel::devel,"write operation aborted"); + m_elog->write(log::elevel::devel,"write operation aborted"); return; } @@ -695,12 +696,12 @@ protected: } void proxy_read(init_handler callback) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection proxy_read"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection proxy_read"); } if (!m_proxy_data) { - m_elog.write(log::elevel::library, + 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)); @@ -741,18 +742,18 @@ protected: void handle_proxy_read(init_handler callback, lib::asio::error_code const & ec, size_t) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel, + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel, "asio connection handle_proxy_read"); } // Timer expired or the operation was aborted for some reason. // Whatever aborted it will be issuing the callback so we are safe to // return - if (ec.value() == (int) lib::asio::error::operation_aborted || + if (ec == lib::asio::error::operation_aborted || lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) { - m_elog.write(log::elevel::devel,"read operation aborted"); + m_elog->write(log::elevel::devel,"read operation aborted"); return; } @@ -760,12 +761,12 @@ protected: m_proxy_data->timer->cancel(); if (ec) { - m_elog.write(log::elevel::info, + m_elog->write(log::elevel::info, "asio handle_proxy_read error: "+ec.message()); callback(make_error_code(error::pass_through)); } else { if (!m_proxy_data) { - m_elog.write(log::elevel::library, + m_elog->write(log::elevel::library, "assertion failed: !m_proxy_data in asio::connection::handle_proxy_read"); callback(make_error_code(error::general)); return; @@ -782,7 +783,7 @@ protected: return; } - m_alog.write(log::alevel::devel,m_proxy_data->res.raw()); + m_alog->write(log::alevel::devel,m_proxy_data->res.raw()); if (m_proxy_data->res.get_status_code() != http::status_code::ok) { // got an error response back @@ -794,7 +795,7 @@ protected: << " (" << m_proxy_data->res.get_status_msg() << ")"; - m_elog.write(log::elevel::info,s.str()); + m_elog->write(log::elevel::info,s.str()); callback(make_error_code(error::proxy_failed)); return; } @@ -819,16 +820,16 @@ protected: void async_read_at_least(size_t num_bytes, char *buf, size_t len, read_handler handler) { - if (m_alog.static_test(log::alevel::devel)) { + if (m_alog->static_test(log::alevel::devel)) { std::stringstream s; s << "asio async_read_at_least: " << num_bytes; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); } // TODO: safety vs speed ? // maybe move into an if devel block /*if (num_bytes > len) { - m_elog.write(log::elevel::devel, + m_elog->write(log::elevel::devel, "asio async_read_at_least error::invalid_num_bytes"); handler(make_error_code(transport::error::invalid_num_bytes), size_t(0)); @@ -862,19 +863,19 @@ protected: lib::placeholders::_1, lib::placeholders::_2 ) ) - ); + ); } - + } void handle_async_read(read_handler handler, lib::asio::error_code const & ec, size_t bytes_transferred) { - m_alog.write(log::alevel::devel, "asio con handle_async_read"); + m_alog->write(log::alevel::devel, "asio con handle_async_read"); // translate asio error codes into more lib::error_codes lib::error_code tec; - if (ec.value() == (int) lib::asio::error::eof) { + if (ec == lib::asio::error::eof) { tec = make_error_code(transport::error::eof); } else if (ec) { // We don't know much more about the error at this point. As our @@ -882,8 +883,8 @@ protected: tec = socket_con_type::translate_ec(ec); m_tec = ec; - if (tec.value() == (int) transport::error::tls_error || - tec.value() == (int) transport::error::pass_through) + if (tec == transport::error::tls_error || + tec == transport::error::pass_through) { // These are aggregate/catch all errors. Log some human readable // information to the info channel to give library users some @@ -896,7 +897,7 @@ protected: } else { // This can happen in cases where the connection is terminated while // the transport is waiting on a read. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_async_read called with null read handler"); } } @@ -988,7 +989,7 @@ protected: } else { // This can happen in cases where the connection is terminated while // the transport is waiting on a read. - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "handle_async_write called with null write handler"); } } @@ -1033,8 +1034,8 @@ protected: /// close and clean up the underlying socket void async_shutdown(shutdown_handler callback) { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel,"asio connection async_shutdown"); + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel,"asio connection async_shutdown"); } timer_ptr shutdown_timer; @@ -1066,14 +1067,14 @@ protected: * @param callback The function to call back * @param ec The status code */ - void handle_async_shutdown_timeout(timer_ptr, init_handler callback, + void handle_async_shutdown_timeout(timer_ptr, init_handler callback, lib::error_code const & ec) { lib::error_code ret_ec; if (ec) { - if (ec.value() == (int) transport::error::operation_aborted) { - m_alog.write(log::alevel::devel, + if (ec == transport::error::operation_aborted) { + m_alog->write(log::alevel::devel, "asio socket shutdown timer cancelled"); return; } @@ -1084,7 +1085,7 @@ protected: ret_ec = make_error_code(transport::error::timeout); } - m_alog.write(log::alevel::devel, + m_alog->write(log::alevel::devel, "Asio transport socket shutdown timed out"); cancel_socket_checked(); callback(ret_ec); @@ -1093,10 +1094,10 @@ protected: void handle_async_shutdown(timer_ptr shutdown_timer, shutdown_handler callback, lib::asio::error_code const & ec) { - if (ec.value() == (int) lib::asio::error::operation_aborted || + if (ec == lib::asio::error::operation_aborted || lib::asio::is_neg(shutdown_timer->expires_from_now())) { - m_alog.write(log::alevel::devel,"async_shutdown cancelled"); + m_alog->write(log::alevel::devel,"async_shutdown cancelled"); return; } @@ -1104,7 +1105,7 @@ protected: lib::error_code tec; if (ec) { - if (ec.value() == (int) lib::asio::error::not_connected) { + if (ec == lib::asio::error::not_connected) { // The socket was already closed when we tried to close it. This // happens periodically (usually if a read or write fails // earlier and if it is a real error will be caught at another @@ -1115,21 +1116,14 @@ protected: tec = socket_con_type::translate_ec(ec); m_tec = ec; - if (tec.value() == (int) transport::error::tls_short_read) { - // TLS short read at this point is somewhat expected if both - // sides try and end the connection at the same time or if - // SSLv2 is being used. In general there is nothing that can - // be done here other than a low level development log. - } else { - // all other errors are effectively pass through errors of - // some sort so print some detail on the info channel for - // library users to look up if needed. - log_err(log::elevel::info,"asio async_shutdown",ec); - } + // all other errors are effectively pass through errors of + // some sort so print some detail on the info channel for + // library users to look up if needed. + log_err(log::elevel::info,"asio async_shutdown",ec); } } else { - if (m_alog.static_test(log::alevel::devel)) { - m_alog.write(log::alevel::devel, + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel, "asio con handle_async_shutdown"); } } @@ -1140,9 +1134,9 @@ protected: void cancel_socket_checked() { lib::asio::error_code cec = socket_con_type::cancel_socket(); if (cec) { - if (cec.value() == (int) lib::asio::error::operation_not_supported) { + if (cec == lib::asio::error::operation_not_supported) { // cancel not supported on this OS, ignore and log at dev level - m_alog.write(log::alevel::devel, "socket cancel not supported"); + m_alog->write(log::alevel::devel, "socket cancel not supported"); } else { log_err(log::elevel::warn, "socket cancel failed", cec); } @@ -1155,13 +1149,13 @@ private: void log_err(log::level l, const char * msg, const error_type & ec) { std::stringstream s; s << msg << " error: " << ec << " (" << ec.message() << ")"; - m_elog.write(l,s.str()); + m_elog->write(l,s.str()); } // static settings const bool m_is_server; - alog_type& m_alog; - elog_type& m_elog; + lib::shared_ptr m_alog; + lib::shared_ptr m_elog; struct proxy_data { proxy_data() : timeout_proxy(config::timeout_proxy) {} diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/endpoint.hpp b/src/3rdparty/include/websocketpp/transport/asio/endpoint.hpp similarity index 92% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/endpoint.hpp rename to src/3rdparty/include/websocketpp/transport/asio/endpoint.hpp index f3d2d30c0..94509adb3 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/endpoint.hpp +++ b/src/3rdparty/include/websocketpp/transport/asio/endpoint.hpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -87,11 +88,14 @@ public: /// Type of a shared pointer to an io_service work object typedef lib::shared_ptr work_ptr; + /// Type of socket pre-bind handler + typedef lib::function tcp_pre_bind_handler; + // generate and manage our own io_service explicit endpoint() : m_io_service(NULL) , m_external_io_service(false) - , m_listen_backlog(0) + , m_listen_backlog(lib::asio::socket_base::max_connections) , m_reuse_addr(false) , m_state(UNINITIALIZED) { @@ -157,7 +161,7 @@ public: rhs.m_acceptor = NULL; rhs.m_listen_backlog = lib::asio::socket_base::max_connections; rhs.m_state = UNINITIALIZED; - + // TODO: this needs to be updated } return *this; @@ -221,7 +225,7 @@ public: * @param ec Set to indicate what error occurred, if any. */ void init_asio(lib::error_code & ec) { - // Use a smart pointer until the call is successful and ownership has + // Use a smart pointer until the call is successful and ownership has // successfully been taken. Use unique_ptr when available. // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. @@ -243,7 +247,7 @@ public: * @see init_asio(io_service_ptr ptr) */ void init_asio() { - // Use a smart pointer until the call is successful and ownership has + // Use a smart pointer until the call is successful and ownership has // successfully been taken. Use unique_ptr when available. // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. @@ -258,6 +262,19 @@ public: m_external_io_service = false; } + /// Sets the tcp pre bind handler + /** + * The tcp pre bind handler is called after the listen acceptor has + * been created but before the socket bind is performed. + * + * @since 0.8.0 + * + * @param h The handler to call on tcp pre bind init. + */ + void set_tcp_pre_bind_handler(tcp_pre_bind_handler h) { + m_tcp_pre_bind_handler = h; + } + /// Sets the tcp pre init handler /** * The tcp pre init handler is called after the raw tcp connection has been @@ -313,8 +330,10 @@ public: * * New values affect future calls to listen only. * - * A value of zero will use the operating system default. This is the - * default value. + * The default value is specified as *::asio::socket_base::max_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. * * @since 0.3.0 * @@ -327,10 +346,13 @@ public: /// Sets whether to use the SO_REUSEADDR flag when opening listening sockets /** * Specifies whether or not to use the SO_REUSEADDR TCP socket option. What - * this flag does depends on your operating system. Please consult operating - * system documentation for more details. + * this flag does depends on your operating system. * - * New values affect future calls to listen only. + * Please consult operating system documentation for more details. There + * may be security consequences to enabling this option. + * + * New values affect future calls to listen only so set this value prior to + * calling listen. * * The default is false. * @@ -356,7 +378,7 @@ public: lib::asio::io_service & get_io_service() { return *m_io_service; } - + /// Get local TCP endpoint /** * Extracts the local endpoint from the acceptor. This represents the @@ -364,7 +386,7 @@ public: * * Sets a bad_descriptor error if the acceptor is not currently listening * or otherwise unavailable. - * + * * @since 0.7.0 * * @param ec Set to indicate what error occurred, if any. @@ -402,27 +424,33 @@ public: lib::asio::error_code bec; m_acceptor->open(ep.protocol(),bec); - if (!bec) { - m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec); - } - if (!bec) { - m_acceptor->bind(ep,bec); - } - if (!bec) { - m_acceptor->listen(m_listen_backlog,bec); - } - if (bec) { - if (m_acceptor->is_open()) { - m_acceptor->close(); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + m_acceptor->set_option(lib::asio::socket_base::reuse_address(m_reuse_addr),bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + // if a TCP pre-bind handler is present, run it + if (m_tcp_pre_bind_handler) { + ec = m_tcp_pre_bind_handler(m_acceptor); + if (ec) { + ec = clean_up_listen_after_error(ec); + return; } - log_err(log::elevel::info,"asio listen",bec); - ec = make_error_code(error::pass_through); - } else { - m_state = LISTENING; - ec = lib::error_code(); } + + m_acceptor->bind(ep,bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + m_acceptor->listen(m_listen_backlog,bec); + if (bec) {ec = clean_up_listen_after_error(bec);return;} + + // Success + m_state = LISTENING; + ec = lib::error_code(); } + + /// Set up endpoint for listening manually /** * Bind the internal acceptor using the settings specified by the endpoint e @@ -724,7 +752,7 @@ public: m_elog->write(log::elevel::info, "asio handle_timer error: "+ec.message()); log_err(log::elevel::info,"asio handle_timer",ec); - callback(make_error_code(error::pass_through)); + callback(socket_con_type::translate_ec(ec)); } } else { callback(lib::error_code()); @@ -740,7 +768,7 @@ public: void async_accept(transport_con_ptr tcon, accept_handler callback, lib::error_code & ec) { - if (m_state != LISTENING) { + if (m_state != LISTENING || !m_acceptor) { using websocketpp::error::make_error_code; ec = make_error_code(websocketpp::error::async_accept_not_listening); return; @@ -792,12 +820,12 @@ protected: * haven't been constructed yet, and cannot be used in the transport * destructor as they will have been destroyed by then. */ - void init_logging(alog_type* a, elog_type* e) { + void init_logging(const lib::shared_ptr& a, const lib::shared_ptr& e) { m_alog = a; m_elog = e; } - void handle_accept(accept_handler callback, lib::asio::error_code const & + void handle_accept(accept_handler callback, lib::asio::error_code const & asio_ec) { lib::error_code ret_ec; @@ -805,11 +833,11 @@ protected: m_alog->write(log::alevel::devel, "asio::handle_accept"); if (asio_ec) { - if (asio_ec.value() == (int) lib::asio::errc::operation_canceled) { + if (asio_ec == lib::asio::errc::operation_canceled) { ret_ec = make_error_code(websocketpp::error::operation_canceled); } else { log_err(log::elevel::info,"asio handle_accept",asio_ec); - ret_ec = make_error_code(error::pass_through); + ret_ec = socket_con_type::translate_ec(asio_ec); } } @@ -951,7 +979,7 @@ protected: if (ec) { log_err(log::elevel::info,"asio async_resolve",ec); - callback(make_error_code(error::pass_through)); + callback(socket_con_type::translate_ec(ec)); return; } @@ -1059,7 +1087,7 @@ protected: if (ec) { log_err(log::elevel::info,"asio async_connect",ec); - callback(make_error_code(error::pass_through)); + callback(socket_con_type::translate_ec(ec)); return; } @@ -1108,6 +1136,16 @@ private: m_elog->write(l,s.str()); } + /// Helper for cleaning up in the listen method after an error + template + lib::error_code clean_up_listen_after_error(error_type const & ec) { + if (m_acceptor->is_open()) { + m_acceptor->close(); + } + log_err(log::elevel::info,"asio listen",ec); + return socket_con_type::translate_ec(ec); + } + enum state { UNINITIALIZED = 0, READY = 1, @@ -1115,6 +1153,7 @@ private: }; // Handlers + tcp_pre_bind_handler m_tcp_pre_bind_handler; tcp_init_handler m_tcp_pre_init_handler; tcp_init_handler m_tcp_post_init_handler; @@ -1129,8 +1168,8 @@ private: int m_listen_backlog; bool m_reuse_addr; - elog_type* m_elog; - alog_type* m_alog; + lib::shared_ptr m_elog; + lib::shared_ptr m_alog; // Transport state state m_state; diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/base.hpp b/src/3rdparty/include/websocketpp/transport/asio/security/base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/base.hpp rename to src/3rdparty/include/websocketpp/transport/asio/security/base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/none.hpp b/src/3rdparty/include/websocketpp/transport/asio/security/none.hpp similarity index 98% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/none.hpp rename to src/3rdparty/include/websocketpp/transport/asio/security/none.hpp index 73c03fdbd..6c7d35241 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/none.hpp +++ b/src/3rdparty/include/websocketpp/transport/asio/security/none.hpp @@ -170,6 +170,10 @@ protected: m_socket.reset(new lib::asio::ip::tcp::socket(*service)); + if (m_socket_init_handler) { + m_socket_init_handler(m_hdl, *m_socket); + } + m_state = READY; return lib::error_code(); @@ -203,10 +207,6 @@ protected: return; } - if (m_socket_init_handler) { - m_socket_init_handler(m_hdl,*m_socket); - } - m_state = READING; callback(lib::error_code()); @@ -260,16 +260,17 @@ protected: return lib::error_code(); } +public: /// Translate any security policy specific information about an error code /** - * Translate_ec takes an Asio error code and attempts to convert its value + * Translate_ec takes an Asio error code and attempts to convert its value * to an appropriate websocketpp error code. In the case that the Asio and * Websocketpp error types are the same (such as using boost::asio and * boost::system_error or using standalone asio and std::system_error the * code will be passed through natively. * * In the case of a mismatch (boost::asio with std::system_error) a - * translated code will be returned. The plain socket policy does not have + * translated code will be returned. The plain socket policy does not have * any additional information so all such errors will be reported as the * generic transport pass_through error. * @@ -279,12 +280,14 @@ protected: * @return The translated error code */ template + static lib::error_code translate_ec(ErrorCodeType) { // We don't know any more information about this error so pass through return make_error_code(transport::error::pass_through); } - /// Overload of translate_ec to catch cases where lib::error_code is the + static + /// Overload of translate_ec to catch cases where lib::error_code is the /// same type as lib::asio::error_code lib::error_code translate_ec(lib::error_code ec) { // We don't know any more information about this error, but the error is diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/tls.hpp b/src/3rdparty/include/websocketpp/transport/asio/security/tls.hpp similarity index 94% rename from src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/tls.hpp rename to src/3rdparty/include/websocketpp/transport/asio/security/tls.hpp index 40e52f328..04ac37903 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/asio/security/tls.hpp +++ b/src/3rdparty/include/websocketpp/transport/asio/security/tls.hpp @@ -195,6 +195,10 @@ protected: } m_socket.reset(new socket_type(*service, *m_context)); + if (m_socket_init_handler) { + m_socket_init_handler(m_hdl, get_socket()); + } + m_io_service = service; m_strand = strand; m_is_server = is_server; @@ -228,7 +232,7 @@ protected: * @param callback Handler to call back with completion information */ void pre_init(init_handler callback) { - // TODO: is this the best way to check whether this function is + // 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 @@ -244,10 +248,6 @@ protected: } #endif - if (m_socket_init_handler) { - m_socket_init_handler(m_hdl,get_socket()); - } - callback(lib::error_code()); } @@ -332,6 +332,7 @@ protected: } } +public: /// Translate any security policy specific information about an error code /** * Translate_ec takes an Asio error code and attempts to convert its value @@ -352,15 +353,12 @@ protected: * @return The translated error code */ template + static lib::error_code translate_ec(ErrorCodeType ec) { if (ec.category() == lib::asio::error::get_ssl_category()) { - if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) { - return make_error_code(transport::error::tls_short_read); - } else { - // We know it is a TLS related error, but otherwise don't know - // more. Pass through as TLS generic. - return make_error_code(transport::error::tls_error); - } + // We know it is a TLS related error, but otherwise don't know more. + // Pass through as TLS generic. + return make_error_code(transport::error::tls_error); } else { // We don't know any more information about this error so pass // through @@ -368,17 +366,10 @@ protected: } } + static /// Overload of translate_ec to catch cases where lib::error_code is the /// same type as lib::asio::error_code lib::error_code translate_ec(lib::error_code ec) { - // Normalize the tls_short_read error as it is used by the library and - // needs a consistent value. All other errors pass through natively. - // TODO: how to get the SSL category from std::error? - /*if (ec.category() == lib::asio::error::get_ssl_category()) { - if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) { - return make_error_code(transport::error::tls_short_read); - } - }*/ return ec; } private: diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/base/connection.hpp b/src/3rdparty/include/websocketpp/transport/base/connection.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/base/connection.hpp rename to src/3rdparty/include/websocketpp/transport/base/connection.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/base/endpoint.hpp b/src/3rdparty/include/websocketpp/transport/base/endpoint.hpp similarity index 97% rename from src/plugins/server/3rdparty/include/websocketpp/transport/base/endpoint.hpp rename to src/3rdparty/include/websocketpp/transport/base/endpoint.hpp index 3b4b0d6db..4ed3e70fa 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/base/endpoint.hpp +++ b/src/3rdparty/include/websocketpp/transport/base/endpoint.hpp @@ -59,7 +59,7 @@ namespace websocketpp { * `connection_hdl` and any error that occurred. * * **init_logging** - * `void init_logging(alog_type * a, elog_type * e)`\n + * `void init_logging(const lib::shared_ptr& a, const lib::shared_ptr& 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. */ diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/iostream/base.hpp b/src/3rdparty/include/websocketpp/transport/iostream/base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/iostream/base.hpp rename to src/3rdparty/include/websocketpp/transport/iostream/base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/iostream/connection.hpp b/src/3rdparty/include/websocketpp/transport/iostream/connection.hpp similarity index 96% rename from src/plugins/server/3rdparty/include/websocketpp/transport/iostream/connection.hpp rename to src/3rdparty/include/websocketpp/transport/iostream/connection.hpp index 81c4f4113..899a3e256 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/iostream/connection.hpp +++ b/src/3rdparty/include/websocketpp/transport/iostream/connection.hpp @@ -77,7 +77,7 @@ public: typedef lib::shared_ptr timer_ptr; - explicit connection(bool is_server, alog_type & alog, elog_type & elog) + explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) : m_output_stream(NULL) , m_reading(false) , m_is_server(is_server) @@ -86,7 +86,7 @@ public: , m_elog(elog) , m_remote_endpoint("iostream transport") { - m_alog.write(log::alevel::devel,"iostream con transport constructor"); + m_alog->write(log::alevel::devel,"iostream con transport constructor"); } /// Get a shared pointer to this component @@ -408,7 +408,7 @@ protected: * @param handler The `init_handler` to call when initialization is done */ void init(init_handler handler) { - m_alog.write(log::alevel::devel,"iostream connection init"); + m_alog->write(log::alevel::devel,"iostream connection init"); handler(lib::error_code()); } @@ -441,7 +441,7 @@ protected: { std::stringstream s; s << "iostream_con async_read_at_least: " << num_bytes; - m_alog.write(log::alevel::devel,s.str()); + m_alog->write(log::alevel::devel,s.str()); if (num_bytes > len) { handler(make_error_code(error::invalid_num_bytes),size_t(0)); @@ -487,7 +487,7 @@ protected: void async_write(char const * buf, size_t len, transport::write_handler handler) { - m_alog.write(log::alevel::devel,"iostream_con async_write"); + m_alog->write(log::alevel::devel,"iostream_con async_write"); // TODO: lock transport state? lib::error_code ec; @@ -527,7 +527,7 @@ protected: void async_write(std::vector const & bufs, transport::write_handler handler) { - m_alog.write(log::alevel::devel,"iostream_con async_write buffer list"); + m_alog->write(log::alevel::devel,"iostream_con async_write buffer list"); // TODO: lock transport state? lib::error_code ec; @@ -601,18 +601,18 @@ protected: } private: void read(std::istream &in) { - m_alog.write(log::alevel::devel,"iostream_con read"); + m_alog->write(log::alevel::devel,"iostream_con read"); while (in.good()) { if (!m_reading) { - m_elog.write(log::elevel::devel,"write while not reading"); + m_elog->write(log::elevel::devel,"write while not reading"); break; } in.read(m_buf+m_cursor,static_cast(m_len-m_cursor)); if (in.gcount() == 0) { - m_elog.write(log::elevel::devel,"read zero bytes"); + m_elog->write(log::elevel::devel,"read zero bytes"); break; } @@ -632,10 +632,10 @@ private: } size_t read_some_impl(char const * buf, size_t len) { - m_alog.write(log::alevel::devel,"iostream_con read_some"); + m_alog->write(log::alevel::devel,"iostream_con read_some"); if (!m_reading) { - m_elog.write(log::elevel::devel,"write while not reading"); + m_elog->write(log::elevel::devel,"write while not reading"); return 0; } @@ -694,8 +694,8 @@ private: bool m_reading; bool const m_is_server; bool m_is_secure; - alog_type & m_alog; - elog_type & m_elog; + lib::shared_ptr m_alog; + lib::shared_ptr m_elog; std::string m_remote_endpoint; // This lock ensures that only one thread can edit read data for this diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp b/src/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp similarity index 98% rename from src/plugins/server/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp rename to src/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp index 14ec65370..14cba7255 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp +++ b/src/3rdparty/include/websocketpp/transport/iostream/endpoint.hpp @@ -168,7 +168,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 a, lib::shared_ptr e) { m_elog = e; m_alog = a; } @@ -209,8 +209,8 @@ private: shutdown_handler m_shutdown_handler; write_handler m_write_handler; - elog_type * m_elog; - alog_type * m_alog; + lib::shared_ptr m_elog; + lib::shared_ptr m_alog; bool m_is_secure; }; diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/stub/base.hpp b/src/3rdparty/include/websocketpp/transport/stub/base.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/stub/base.hpp rename to src/3rdparty/include/websocketpp/transport/stub/base.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/stub/connection.hpp b/src/3rdparty/include/websocketpp/transport/stub/connection.hpp similarity index 94% rename from src/plugins/server/3rdparty/include/websocketpp/transport/stub/connection.hpp rename to src/3rdparty/include/websocketpp/transport/stub/connection.hpp index 59bd4a0a4..5bbbf0d79 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/transport/stub/connection.hpp +++ b/src/3rdparty/include/websocketpp/transport/stub/connection.hpp @@ -72,10 +72,10 @@ public: typedef lib::shared_ptr timer_ptr; - explicit connection(bool is_server, alog_type & alog, elog_type & elog) + explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) : m_alog(alog), m_elog(elog) { - m_alog.write(log::alevel::devel,"stub con transport constructor"); + m_alog->write(log::alevel::devel,"stub con transport constructor"); } /// Get a shared pointer to this component @@ -175,7 +175,7 @@ protected: * @param handler The `init_handler` to call when initialization is done */ void init(init_handler handler) { - m_alog.write(log::alevel::devel,"stub connection init"); + m_alog->write(log::alevel::devel,"stub connection init"); handler(make_error_code(error::not_implemented)); } @@ -206,7 +206,7 @@ protected: void async_read_at_least(size_t num_bytes, char * buf, size_t len, read_handler handler) { - m_alog.write(log::alevel::devel, "stub_con async_read_at_least"); + m_alog->write(log::alevel::devel, "stub_con async_read_at_least"); handler(make_error_code(error::not_implemented), 0); } @@ -223,7 +223,7 @@ protected: * @param handler Callback to invoke with operation status. */ void async_write(char const * buf, size_t len, write_handler handler) { - m_alog.write(log::alevel::devel,"stub_con async_write"); + m_alog->write(log::alevel::devel,"stub_con async_write"); handler(make_error_code(error::not_implemented)); } @@ -239,7 +239,7 @@ protected: * @param handler Callback to invoke with operation status. */ void async_write(std::vector const & bufs, write_handler handler) { - m_alog.write(log::alevel::devel,"stub_con async_write buffer list"); + m_alog->write(log::alevel::devel,"stub_con async_write buffer list"); handler(make_error_code(error::not_implemented)); } @@ -274,8 +274,8 @@ protected: } private: // member variables! - alog_type & m_alog; - elog_type & m_elog; + lib::shared_ptr m_alog; + lib::shared_ptr m_elog; }; diff --git a/src/plugins/server/3rdparty/include/websocketpp/transport/stub/endpoint.hpp b/src/3rdparty/include/websocketpp/transport/stub/endpoint.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/transport/stub/endpoint.hpp rename to src/3rdparty/include/websocketpp/transport/stub/endpoint.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/uri.hpp b/src/3rdparty/include/websocketpp/uri.hpp similarity index 99% rename from src/plugins/server/3rdparty/include/websocketpp/uri.hpp rename to src/3rdparty/include/websocketpp/uri.hpp index 7159234f0..c0b8b0cbd 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/uri.hpp +++ b/src/3rdparty/include/websocketpp/uri.hpp @@ -31,6 +31,7 @@ #include #include +#include #include #include diff --git a/src/plugins/server/3rdparty/include/websocketpp/utf8_validator.hpp b/src/3rdparty/include/websocketpp/utf8_validator.hpp similarity index 100% rename from src/plugins/server/3rdparty/include/websocketpp/utf8_validator.hpp rename to src/3rdparty/include/websocketpp/utf8_validator.hpp diff --git a/src/plugins/server/3rdparty/include/websocketpp/utilities.hpp b/src/3rdparty/include/websocketpp/utilities.hpp similarity index 97% rename from src/plugins/server/3rdparty/include/websocketpp/utilities.hpp rename to src/3rdparty/include/websocketpp/utilities.hpp index 747f1199b..b983c9f3a 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/utilities.hpp +++ b/src/3rdparty/include/websocketpp/utilities.hpp @@ -72,11 +72,9 @@ private: * Based on code from * http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find */ -struct ci_less : std::binary_function { +struct ci_less { // case-independent (ci) compare_less binary function - struct nocase_compare - : public std::binary_function - { + struct nocase_compare { bool operator() (unsigned char const & c1, unsigned char const & c2) const { return tolower (c1) < tolower (c2); } diff --git a/src/plugins/server/3rdparty/include/websocketpp/version.hpp b/src/3rdparty/include/websocketpp/version.hpp similarity index 94% rename from src/plugins/server/3rdparty/include/websocketpp/version.hpp rename to src/3rdparty/include/websocketpp/version.hpp index b88cc1104..5766546f7 100644 --- a/src/plugins/server/3rdparty/include/websocketpp/version.hpp +++ b/src/3rdparty/include/websocketpp/version.hpp @@ -42,9 +42,9 @@ namespace websocketpp { /// Library major version number static int const major_version = 0; /// Library minor version number -static int const minor_version = 7; +static int const minor_version = 8; /// Library patch version number -static int const patch_version = 0; +static int const patch_version = 2; /// Library pre-release flag /** * This is a textual flag indicating the type and number for pre-release @@ -54,7 +54,7 @@ static int const patch_version = 0; static char const prerelease_flag[] = ""; /// Default user agent string -static char const user_agent[] = "WebSocket++/0.7.0"; +static char const user_agent[] = "WebSocket++/0.8.2"; } // namespace websocketpp diff --git a/src/plugins/server/3rdparty/win32_include/microhttpd.h b/src/3rdparty/win32_include/microhttpd.h similarity index 100% rename from src/plugins/server/3rdparty/win32_include/microhttpd.h rename to src/3rdparty/win32_include/microhttpd.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/COPYING b/src/3rdparty/win32_src/microhttpd/COPYING similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/COPYING rename to src/3rdparty/win32_src/microhttpd/COPYING diff --git a/src/plugins/server/3rdparty/win32_include/MHD_config.h b/src/3rdparty/win32_src/microhttpd/MHD_config.h similarity index 100% rename from src/plugins/server/3rdparty/win32_include/MHD_config.h rename to src/3rdparty/win32_src/microhttpd/MHD_config.h diff --git a/src/plugins/server/3rdparty/win32_include/autoinit_funcs.h b/src/3rdparty/win32_src/microhttpd/autoinit_funcs.h similarity index 100% rename from src/plugins/server/3rdparty/win32_include/autoinit_funcs.h rename to src/3rdparty/win32_src/microhttpd/autoinit_funcs.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/base64.c b/src/3rdparty/win32_src/microhttpd/base64.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/base64.c rename to src/3rdparty/win32_src/microhttpd/base64.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/base64.h b/src/3rdparty/win32_src/microhttpd/base64.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/base64.h rename to src/3rdparty/win32_src/microhttpd/base64.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/basicauth.c b/src/3rdparty/win32_src/microhttpd/basicauth.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/basicauth.c rename to src/3rdparty/win32_src/microhttpd/basicauth.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/connection.c b/src/3rdparty/win32_src/microhttpd/connection.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/connection.c rename to src/3rdparty/win32_src/microhttpd/connection.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/connection.h b/src/3rdparty/win32_src/microhttpd/connection.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/connection.h rename to src/3rdparty/win32_src/microhttpd/connection.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/connection_https.c b/src/3rdparty/win32_src/microhttpd/connection_https.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/connection_https.c rename to src/3rdparty/win32_src/microhttpd/connection_https.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/connection_https.h b/src/3rdparty/win32_src/microhttpd/connection_https.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/connection_https.h rename to src/3rdparty/win32_src/microhttpd/connection_https.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/daemon.c b/src/3rdparty/win32_src/microhttpd/daemon.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/daemon.c rename to src/3rdparty/win32_src/microhttpd/daemon.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/digestauth.c b/src/3rdparty/win32_src/microhttpd/digestauth.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/digestauth.c rename to src/3rdparty/win32_src/microhttpd/digestauth.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/internal.c b/src/3rdparty/win32_src/microhttpd/internal.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/internal.c rename to src/3rdparty/win32_src/microhttpd/internal.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/internal.h b/src/3rdparty/win32_src/microhttpd/internal.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/internal.h rename to src/3rdparty/win32_src/microhttpd/internal.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/md5.c b/src/3rdparty/win32_src/microhttpd/md5.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/md5.c rename to src/3rdparty/win32_src/microhttpd/md5.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/md5.h b/src/3rdparty/win32_src/microhttpd/md5.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/md5.h rename to src/3rdparty/win32_src/microhttpd/md5.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/memorypool.c b/src/3rdparty/win32_src/microhttpd/memorypool.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/memorypool.c rename to src/3rdparty/win32_src/microhttpd/memorypool.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/memorypool.h b/src/3rdparty/win32_src/microhttpd/memorypool.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/memorypool.h rename to src/3rdparty/win32_src/microhttpd/memorypool.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_byteorder.h b/src/3rdparty/win32_src/microhttpd/mhd_byteorder.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_byteorder.h rename to src/3rdparty/win32_src/microhttpd/mhd_byteorder.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_compat.c b/src/3rdparty/win32_src/microhttpd/mhd_compat.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_compat.c rename to src/3rdparty/win32_src/microhttpd/mhd_compat.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_compat.h b/src/3rdparty/win32_src/microhttpd/mhd_compat.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_compat.h rename to src/3rdparty/win32_src/microhttpd/mhd_compat.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc.c b/src/3rdparty/win32_src/microhttpd/mhd_itc.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc.c rename to src/3rdparty/win32_src/microhttpd/mhd_itc.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc.h b/src/3rdparty/win32_src/microhttpd/mhd_itc.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc.h rename to src/3rdparty/win32_src/microhttpd/mhd_itc.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc_types.h b/src/3rdparty/win32_src/microhttpd/mhd_itc_types.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_itc_types.h rename to src/3rdparty/win32_src/microhttpd/mhd_itc_types.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_limits.h b/src/3rdparty/win32_src/microhttpd/mhd_limits.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_limits.h rename to src/3rdparty/win32_src/microhttpd/mhd_limits.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_locks.h b/src/3rdparty/win32_src/microhttpd/mhd_locks.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_locks.h rename to src/3rdparty/win32_src/microhttpd/mhd_locks.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_mono_clock.c b/src/3rdparty/win32_src/microhttpd/mhd_mono_clock.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_mono_clock.c rename to src/3rdparty/win32_src/microhttpd/mhd_mono_clock.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_mono_clock.h b/src/3rdparty/win32_src/microhttpd/mhd_mono_clock.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_mono_clock.h rename to src/3rdparty/win32_src/microhttpd/mhd_mono_clock.h diff --git a/src/plugins/server/3rdparty/win32_include/mhd_options.h b/src/3rdparty/win32_src/microhttpd/mhd_options.h similarity index 100% rename from src/plugins/server/3rdparty/win32_include/mhd_options.h rename to src/3rdparty/win32_src/microhttpd/mhd_options.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_sockets.c b/src/3rdparty/win32_src/microhttpd/mhd_sockets.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_sockets.c rename to src/3rdparty/win32_src/microhttpd/mhd_sockets.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_sockets.h b/src/3rdparty/win32_src/microhttpd/mhd_sockets.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_sockets.h rename to src/3rdparty/win32_src/microhttpd/mhd_sockets.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_str.c b/src/3rdparty/win32_src/microhttpd/mhd_str.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_str.c rename to src/3rdparty/win32_src/microhttpd/mhd_str.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_str.h b/src/3rdparty/win32_src/microhttpd/mhd_str.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_str.h rename to src/3rdparty/win32_src/microhttpd/mhd_str.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_threads.c b/src/3rdparty/win32_src/microhttpd/mhd_threads.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_threads.c rename to src/3rdparty/win32_src/microhttpd/mhd_threads.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/mhd_threads.h b/src/3rdparty/win32_src/microhttpd/mhd_threads.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/mhd_threads.h rename to src/3rdparty/win32_src/microhttpd/mhd_threads.h diff --git a/src/plugins/server/3rdparty/win32_include/platform.h b/src/3rdparty/win32_src/microhttpd/platform.h similarity index 100% rename from src/plugins/server/3rdparty/win32_include/platform.h rename to src/3rdparty/win32_src/microhttpd/platform.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/postprocessor.c b/src/3rdparty/win32_src/microhttpd/postprocessor.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/postprocessor.c rename to src/3rdparty/win32_src/microhttpd/postprocessor.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/reason_phrase.c b/src/3rdparty/win32_src/microhttpd/reason_phrase.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/reason_phrase.c rename to src/3rdparty/win32_src/microhttpd/reason_phrase.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/response.c b/src/3rdparty/win32_src/microhttpd/response.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/response.c rename to src/3rdparty/win32_src/microhttpd/response.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/response.h b/src/3rdparty/win32_src/microhttpd/response.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/response.h rename to src/3rdparty/win32_src/microhttpd/response.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/sysfdsetsize.c b/src/3rdparty/win32_src/microhttpd/sysfdsetsize.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/sysfdsetsize.c rename to src/3rdparty/win32_src/microhttpd/sysfdsetsize.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/sysfdsetsize.h b/src/3rdparty/win32_src/microhttpd/sysfdsetsize.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/sysfdsetsize.h rename to src/3rdparty/win32_src/microhttpd/sysfdsetsize.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_daemon.c b/src/3rdparty/win32_src/microhttpd/test_daemon.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_daemon.c rename to src/3rdparty/win32_src/microhttpd/test_daemon.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_helpers.h b/src/3rdparty/win32_src/microhttpd/test_helpers.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_helpers.h rename to src/3rdparty/win32_src/microhttpd/test_helpers.h diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor.c b/src/3rdparty/win32_src/microhttpd/test_postprocessor.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor.c rename to src/3rdparty/win32_src/microhttpd/test_postprocessor.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor_amp.c b/src/3rdparty/win32_src/microhttpd/test_postprocessor_amp.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor_amp.c rename to src/3rdparty/win32_src/microhttpd/test_postprocessor_amp.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor_large.c b/src/3rdparty/win32_src/microhttpd/test_postprocessor_large.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_postprocessor_large.c rename to src/3rdparty/win32_src/microhttpd/test_postprocessor_large.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_shutdown_select.c b/src/3rdparty/win32_src/microhttpd/test_shutdown_select.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_shutdown_select.c rename to src/3rdparty/win32_src/microhttpd/test_shutdown_select.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_str.c b/src/3rdparty/win32_src/microhttpd/test_str.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_str.c rename to src/3rdparty/win32_src/microhttpd/test_str.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/test_upgrade.c b/src/3rdparty/win32_src/microhttpd/test_upgrade.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/test_upgrade.c rename to src/3rdparty/win32_src/microhttpd/test_upgrade.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/tsearch.c b/src/3rdparty/win32_src/microhttpd/tsearch.c similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/tsearch.c rename to src/3rdparty/win32_src/microhttpd/tsearch.c diff --git a/src/plugins/server/3rdparty/win32_src/microhttpd/tsearch.h b/src/3rdparty/win32_src/microhttpd/tsearch.h similarity index 100% rename from src/plugins/server/3rdparty/win32_src/microhttpd/tsearch.h rename to src/3rdparty/win32_src/microhttpd/tsearch.h diff --git a/src/plugins/server/3rdparty/include/json.hpp b/src/plugins/server/3rdparty/include/json.hpp deleted file mode 100644 index c9af0bed3..000000000 --- a/src/plugins/server/3rdparty/include/json.hpp +++ /dev/null @@ -1,20406 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.5.0 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -Licensed under the MIT License . -SPDX-License-Identifier: MIT -Copyright (c) 2013-2018 Niels Lohmann . - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef NLOHMANN_JSON_HPP -#define NLOHMANN_JSON_HPP - -#define NLOHMANN_JSON_VERSION_MAJOR 3 -#define NLOHMANN_JSON_VERSION_MINOR 5 -#define NLOHMANN_JSON_VERSION_PATCH 0 - -#include // all_of, find, for_each -#include // assert -#include // and, not, or -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#include // istream, ostream -#include // random_access_iterator_tag -#include // accumulate -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap - -// #include -#ifndef NLOHMANN_JSON_FWD_HPP -#define NLOHMANN_JSON_FWD_HPP - -#include // int64_t, uint64_t -#include // map -#include // allocator -#include // string -#include // vector - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -namespace nlohmann -{ -/*! -@brief default JSONSerializer template argument - -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template -struct adl_serializer; - -template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer> -class basic_json; - -/*! -@brief JSON Pointer - -A JSON pointer defines a string syntax for identifying a specific value -within a JSON document. It can be used with functions `at` and -`operator[]`. Furthermore, JSON pointers are the base for JSON patches. - -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) - -@since version 2.0.0 -*/ -template -class json_pointer; - -/*! -@brief default JSON class - -This type is the default specialization of the @ref basic_json class which -uses the standard template types. - -@since version 1.0.0 -*/ -using json = basic_json<>; -} // namespace nlohmann - -#endif - -// #include - - -// This file contains all internal macro definitions -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// disable float-equal warnings on GCC/clang -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdocumentation" -#endif - -// allow for portable deprecation warnings -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #define JSON_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) - #define JSON_DEPRECATED __declspec(deprecated) -#else - #define JSON_DEPRECATED -#endif - -// allow to disable exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// manual branch prediction -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) - #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) - #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else - #define JSON_LIKELY(x) x - #define JSON_UNLIKELY(x) x -#endif - -// C++ language standard detection -#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// #include - - -#include // not -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type - -namespace nlohmann -{ -namespace detail -{ -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -template -using uncvref_t = typename std::remove_cv::type>::type; - -// implementation of C++14 index_sequence and affiliates -// source: https://stackoverflow.com/a/32223343 -template -struct index_sequence -{ - using type = index_sequence; - using value_type = std::size_t; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -template -struct merge_and_renumber; - -template -struct merge_and_renumber, index_sequence> - : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; - -template -struct make_index_sequence - : merge_and_renumber < typename make_index_sequence < N / 2 >::type, - typename make_index_sequence < N - N / 2 >::type > {}; - -template<> struct make_index_sequence<0> : index_sequence<> {}; -template<> struct make_index_sequence<1> : index_sequence<0> {}; - -template -using index_sequence_for = make_index_sequence; - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static constexpr T value{}; -}; - -template -constexpr T static_const::value; -} // namespace detail -} // namespace nlohmann - -// #include - - -#include // not -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval - -// #include - -// #include - - -#include // random_access_iterator_tag - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; -} // namespace detail -} // namespace nlohmann - -// #include - - -namespace nlohmann -{ -namespace detail -{ -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; -} -} - -// #include - -// #include - - -#include - -// #include - - -// http://en.cppreference.com/w/cpp/experimental/is_detected -namespace nlohmann -{ -namespace detail -{ -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - void operator=(nonesuch const&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template