mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 04:52:32 +00:00
Upgraded websocketpp and moved it and libmicrohttpd into the shared
3rdparty directory.
This commit is contained in:
parent
61a0ee78de
commit
b51dee258f
2
src/3rdparty/include/websocketpp/CMakeLists.txt
vendored
Normal file
2
src/3rdparty/include/websocketpp/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
init_target("websocketpp")
|
||||
final_target ()
|
145
src/3rdparty/include/websocketpp/COPYING
vendored
Normal file
145
src/3rdparty/include/websocketpp/COPYING
vendored
Normal file
@ -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
|
||||
<bjoern@hoehrmann.de>. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for
|
||||
details.
|
||||
|
||||
The original license:
|
||||
|
||||
Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
|
||||
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.
|
@ -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:
|
@ -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
|
@ -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;
|
@ -51,7 +51,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_THREAD_
|
||||
#if defined(_WEBSOCKETPP_MINGW_THREAD_)
|
||||
#include <mingw-threads/mingw.thread.h>
|
||||
#include <mingw-threads/mingw.mutex.h>
|
||||
#include <mingw-threads/mingw.condition_variable.h>
|
||||
#elif defined(_WEBSOCKETPP_CPP11_THREAD_)
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
@ -64,7 +68,7 @@
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
#ifdef _WEBSOCKETPP_CPP11_THREAD_
|
||||
#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_)
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
using std::thread;
|
@ -49,6 +49,7 @@
|
||||
|
||||
// Loggers
|
||||
#include <websocketpp/logger/basic.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
// RNG
|
||||
#include <websocketpp/random/none.hpp>
|
||||
@ -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.
|
@ -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_type>& alog,
|
||||
const lib::shared_ptr<elog_type>& 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<std::string> m_requested_subprotocols;
|
||||
|
||||
bool const m_is_server;
|
||||
alog_type& m_alog;
|
||||
elog_type& m_elog;
|
||||
const lib::shared_ptr<alog_type> m_alog;
|
||||
const lib::shared_ptr<elog_type> 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
|
@ -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<alog_type> m_alog;
|
||||
lib::shared_ptr<elog_type> m_elog;
|
||||
private:
|
||||
// dynamic settings
|
||||
std::string m_user_agent;
|
@ -29,6 +29,7 @@
|
||||
#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
|
||||
#include <websocketpp/http/constants.hpp>
|
@ -32,12 +32,13 @@
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
#include <websocketpp/extensions/extension.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
#include "zlib.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@ -46,7 +47,7 @@
|
||||
namespace websocketpp {
|
||||
namespace extensions {
|
||||
|
||||
/// Implementation of the draft permessage-deflate WebSocket extension
|
||||
/// Implementation of RFC 7692, the permessage-deflate WebSocket extension
|
||||
/**
|
||||
* ### permessage-deflate interface
|
||||
*
|
||||
@ -174,18 +175,30 @@ namespace websocketpp {
|
||||
namespace extensions {
|
||||
namespace permessage_deflate {
|
||||
|
||||
/// Default value for server_max_window_bits as defined by draft 17
|
||||
/// Default value for server_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const default_server_max_window_bits = 15;
|
||||
/// Minimum value for server_max_window_bits as defined by draft 17
|
||||
/// Minimum value for server_max_window_bits as defined by RFC 7692
|
||||
/**
|
||||
* NOTE: A value of 8 is not actually supported by zlib, the deflate
|
||||
* library that WebSocket++ uses. To preserve backwards compatibility
|
||||
* with RFC 7692 and previous versions of the library a value of 8
|
||||
* is accepted by the library but will always be negotiated as 9.
|
||||
*/
|
||||
static uint8_t const min_server_max_window_bits = 8;
|
||||
/// Maximum value for server_max_window_bits as defined by draft 17
|
||||
/// Maximum value for server_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const max_server_max_window_bits = 15;
|
||||
|
||||
/// Default value for client_max_window_bits as defined by draft 17
|
||||
/// Default value for client_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const default_client_max_window_bits = 15;
|
||||
/// Minimum value for client_max_window_bits as defined by draft 17
|
||||
/// Minimum value for client_max_window_bits as defined by RFC 7692
|
||||
/**
|
||||
* NOTE: A value of 8 is not actually supported by zlib, the deflate
|
||||
* library that WebSocket++ uses. To preserve backwards compatibility
|
||||
* with RFC 7692 and previous versions of the library a value of 8
|
||||
* is accepted by the library but will always be negotiated as 9.
|
||||
*/
|
||||
static uint8_t const min_client_max_window_bits = 8;
|
||||
/// Maximum value for client_max_window_bits as defined by draft 17
|
||||
/// Maximum value for client_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const max_client_max_window_bits = 15;
|
||||
|
||||
namespace mode {
|
||||
@ -213,7 +226,7 @@ public:
|
||||
, m_server_max_window_bits_mode(mode::accept)
|
||||
, m_client_max_window_bits_mode(mode::accept)
|
||||
, m_initialized(false)
|
||||
, m_compress_buffer_size(16384)
|
||||
, m_compress_buffer_size(8192)
|
||||
{
|
||||
m_dstate.zalloc = Z_NULL;
|
||||
m_dstate.zfree = Z_NULL;
|
||||
@ -292,6 +305,7 @@ public:
|
||||
}
|
||||
|
||||
m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
||||
m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
||||
if ((m_server_no_context_takeover && is_server) ||
|
||||
(m_client_no_context_takeover && !is_server))
|
||||
{
|
||||
@ -372,7 +386,7 @@ public:
|
||||
/**
|
||||
* The bits setting is the base 2 logarithm of the maximum window size that
|
||||
* the server must use to compress outgoing messages. The permitted range
|
||||
* is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB
|
||||
* is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB
|
||||
* window. The default setting is 15.
|
||||
*
|
||||
* Mode Options:
|
||||
@ -386,6 +400,14 @@ public:
|
||||
* adjusted by the server. A server may unilaterally set this value without
|
||||
* client support.
|
||||
*
|
||||
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
|
||||
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
|
||||
* zlib, the deflate compression library that WebSocket++ uses has always
|
||||
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
|
||||
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
|
||||
* continues to perform the 8->9 conversion for backwards compatibility
|
||||
* purposes but this should be considered deprecated functionality.
|
||||
*
|
||||
* @param bits The size to request for the outgoing window size
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
@ -394,6 +416,12 @@ public:
|
||||
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
|
||||
// See note in doc comment above about what is happening here
|
||||
if (bits == 8) {
|
||||
bits = 9;
|
||||
}
|
||||
|
||||
m_server_max_window_bits = bits;
|
||||
m_server_max_window_bits_mode = mode;
|
||||
|
||||
@ -403,8 +431,8 @@ public:
|
||||
/// Limit client LZ77 sliding window size
|
||||
/**
|
||||
* The bits setting is the base 2 logarithm of the window size that the
|
||||
* client must use to compress outgoing messages. The permitted range is 8
|
||||
* to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window.
|
||||
* client must use to compress outgoing messages. The permitted range is 9
|
||||
* to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window.
|
||||
* The default setting is 15.
|
||||
*
|
||||
* Mode Options:
|
||||
@ -417,6 +445,14 @@ public:
|
||||
* outgoing window size unilaterally. A server may only limit the client's
|
||||
* window size if the remote client supports that feature.
|
||||
*
|
||||
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
|
||||
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
|
||||
* zlib, the deflate compression library that WebSocket++ uses has always
|
||||
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
|
||||
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
|
||||
* continues to perform the 8->9 conversion for backwards compatibility
|
||||
* purposes but this should be considered deprecated functionality.
|
||||
*
|
||||
* @param bits The size to request for the outgoing window size
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
@ -425,6 +461,12 @@ public:
|
||||
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
|
||||
// See note in doc comment above about what is happening here
|
||||
if (bits == 8) {
|
||||
bits = 9;
|
||||
}
|
||||
|
||||
m_client_max_window_bits = bits;
|
||||
m_client_max_window_bits_mode = mode;
|
||||
|
||||
@ -555,7 +597,7 @@ public:
|
||||
|
||||
do {
|
||||
m_istate.avail_out = m_compress_buffer_size;
|
||||
m_istate.next_out = m_compress_buffer.get();
|
||||
m_istate.next_out = m_decompress_buffer.get();
|
||||
|
||||
ret = inflate(&m_istate, Z_SYNC_FLUSH);
|
||||
|
||||
@ -564,7 +606,7 @@ public:
|
||||
}
|
||||
|
||||
out.append(
|
||||
reinterpret_cast<char *>(m_compress_buffer.get()),
|
||||
reinterpret_cast<char *>(m_decompress_buffer.get()),
|
||||
m_compress_buffer_size - m_istate.avail_out
|
||||
);
|
||||
} while (m_istate.avail_out == 0);
|
||||
@ -642,11 +684,17 @@ private:
|
||||
* client requested that we use.
|
||||
*
|
||||
* options:
|
||||
* - decline (refuse to use the attribute)
|
||||
* - accept (use whatever the client says)
|
||||
* - largest (use largest possible value)
|
||||
* - decline (ignore value, offer our default instead)
|
||||
* - accept (use the value requested by the client)
|
||||
* - largest (use largest value acceptable to both)
|
||||
* - smallest (use smallest possible value)
|
||||
*
|
||||
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
|
||||
* be requested for negotiation by an older client/server, if the result of
|
||||
* the negotiation would be to send a value of 8, a value of 9 is offered
|
||||
* instead. This ensures that WebSocket++ will only ever negotiate connections
|
||||
* with compression settings explicitly supported by zlib.
|
||||
*
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
@ -678,6 +726,11 @@ private:
|
||||
ec = make_error_code(error::invalid_mode);
|
||||
m_server_max_window_bits = default_server_max_window_bits;
|
||||
}
|
||||
|
||||
// See note in doc comment
|
||||
if (m_server_max_window_bits == 8) {
|
||||
m_server_max_window_bits = 9;
|
||||
}
|
||||
}
|
||||
|
||||
/// Negotiate client_max_window_bits attribute
|
||||
@ -687,11 +740,17 @@ private:
|
||||
* negotiation mode.
|
||||
*
|
||||
* options:
|
||||
* - decline (refuse to use the attribute)
|
||||
* - accept (use whatever the client says)
|
||||
* - largest (use largest possible value)
|
||||
* - decline (ignore value, offer our default instead)
|
||||
* - accept (use the value requested by the client)
|
||||
* - largest (use largest value acceptable to both)
|
||||
* - smallest (use smallest possible value)
|
||||
*
|
||||
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
|
||||
* be requested for negotiation by an older client/server, if the result of
|
||||
* the negotiation would be to send a value of 8, a value of 9 is offered
|
||||
* instead. This ensures that WebSocket++ will only ever negotiate connections
|
||||
* with compression settings explicitly supported by zlib.
|
||||
*
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
@ -727,6 +786,11 @@ private:
|
||||
ec = make_error_code(error::invalid_mode);
|
||||
m_client_max_window_bits = default_client_max_window_bits;
|
||||
}
|
||||
|
||||
// See note in doc comment
|
||||
if (m_client_max_window_bits == 8) {
|
||||
m_client_max_window_bits = 9;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_enabled;
|
||||
@ -741,6 +805,7 @@ private:
|
||||
int m_flush;
|
||||
size_t m_compress_buffer_size;
|
||||
lib::unique_ptr_uchar_array m_compress_buffer;
|
||||
lib::unique_ptr_uchar_array m_decompress_buffer;
|
||||
z_stream m_dstate;
|
||||
z_stream m_istate;
|
||||
};
|
@ -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;
|
@ -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;
|
||||
|
@ -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
|
@ -53,7 +53,7 @@ template <typename config>
|
||||
void connection<config>::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<config>::send(void const * payload, size_t len,
|
||||
template <typename config>
|
||||
lib::error_code connection<config>::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<config>::send(typename config::message_type::ptr msg)
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::handle_pong_timeout(std::string payload,
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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 <typename config>
|
||||
void connection<config>::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<config>::close(close::status::value const code,
|
||||
*/
|
||||
template <typename config>
|
||||
lib::error_code connection<config>::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<config>::handle_interrupt() {
|
||||
|
||||
template <typename config>
|
||||
lib::error_code connection<config>::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<config>::pause_reading() {
|
||||
/// Pause reading handler. Not safe to call directly
|
||||
template <typename config>
|
||||
void connection<config>::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 <typename config>
|
||||
lib::error_code connection<config>::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<config>::send_http_response() {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::start() {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::handle_transport_init(lib::error_code const & ec) {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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 <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::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<config>::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<config>::handle_read_handshake(lib::error_code const & ec,
|
||||
template <typename config>
|
||||
void connection<config>::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 <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<uint8_t*>(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<config>::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<config>::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<config>::read_frame() {
|
||||
|
||||
template <typename config>
|
||||
lib::error_code connection<config>::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<config>::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<config>::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<config>::initialize_processor() {
|
||||
|
||||
template <typename config>
|
||||
lib::error_code connection<config>::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<config>::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<config>::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<config>::process_handshake_request() {
|
||||
std::pair<lib::error_code,std::string> neg_results;
|
||||
neg_results = m_processor->negotiate_extensions(m_request);
|
||||
|
||||
if (neg_results.first) {
|
||||
if (neg_results.first == processor::error::make_error_code(processor::error::extension_parse_error)) {
|
||||
// There was a fatal error in extension parsing that should result in
|
||||
// a failed connection attempt.
|
||||
m_alog.write(log::alevel::devel, "Bad request: " + neg_results.first.message());
|
||||
m_elog->write(log::elevel::info, "Bad request: " + neg_results.first.message());
|
||||
m_response.set_status(http::status_code::bad_request);
|
||||
return neg_results.first;
|
||||
} else if (neg_results.first) {
|
||||
// There was a fatal error in extension processing that is probably our
|
||||
// fault. Consider extension negotiation to have failed and continue as
|
||||
// if extensions were not supported
|
||||
m_elog->write(log::elevel::info,
|
||||
"Extension negotiation failed: " + neg_results.first.message());
|
||||
} else {
|
||||
// extension negotiation succeeded, set response header accordingly
|
||||
// we don't send an empty extensions header because it breaks many
|
||||
@ -1243,7 +1246,7 @@ lib::error_code connection<config>::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<config>::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<config>::process_handshake_request() {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::write_http_response(lib::error_code const & ec) {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::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<config>::handle_write_http_response(lib::error_code const & ec)
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::send_http_request() {
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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 <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::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 <typename config>
|
||||
void connection<config>::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 <typename config>
|
||||
void connection<config>::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 <typename config>
|
||||
void connection<config>::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<config>::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 <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::handle_terminate(terminate_status tstat,
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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() << ") ["<<m_current_msgs[i]->get_opcode()<<"] "
|
||||
<< (m_current_msgs[i]->get_opcode() == frame::opcode::text ?
|
||||
@ -1870,9 +1873,9 @@ void connection<config>::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<config>::write_frame() {
|
||||
template <typename config>
|
||||
void connection<config>::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<int> const & connection<config>::get_supported_versions() const
|
||||
template <typename config>
|
||||
void connection<config>::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<config>::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<config>::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<config>::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<config>::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<config>::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<config>::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 <typename config>
|
||||
lib::error_code connection<config>::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<config>::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<config>::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<config>::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<config>::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<config>::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 <typename config>
|
||||
@ -2296,7 +2299,7 @@ void connection<config>::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 <typename config>
|
||||
@ -2335,7 +2338,7 @@ void connection<config>::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 <typename config>
|
||||
@ -2343,7 +2346,7 @@ void connection<config>::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<config>::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
|
@ -35,7 +35,7 @@ namespace websocketpp {
|
||||
template <typename connection, typename config>
|
||||
typename endpoint<connection,config>::connection_ptr
|
||||
endpoint<connection,config>::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<connection,config>::create_connection() {
|
||||
//scoped_lock_type guard(m_mutex);
|
||||
// Create a connection on the heap and manage it using a shared pointer
|
||||
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
|
||||
m_user_agent, 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<connection,config>::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<connection,config>::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();
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
@ -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<config>(server<config> &) = delete;
|
||||
|
||||
|
||||
// no copy assignment operator because endpoints are not copyable
|
||||
server<config> & operator=(server<config> 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<transport_con_type>(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());
|
||||
}
|
||||
}
|
@ -98,12 +98,12 @@ public:
|
||||
friend class endpoint<config>;
|
||||
|
||||
// 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_type> & alog, const lib::shared_ptr<elog_type> & 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<alog_type> m_alog;
|
||||
lib::shared_ptr<elog_type> m_elog;
|
||||
|
||||
struct proxy_data {
|
||||
proxy_data() : timeout_proxy(config::timeout_proxy) {}
|
@ -35,6 +35,7 @@
|
||||
#include <websocketpp/uri.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <websocketpp/common/asio.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
|
||||
#include <sstream>
|
||||
@ -87,11 +88,14 @@ public:
|
||||
/// Type of a shared pointer to an io_service work object
|
||||
typedef lib::shared_ptr<lib::asio::io_service::work> work_ptr;
|
||||
|
||||
/// Type of socket pre-bind handler
|
||||
typedef lib::function<lib::error_code(acceptor_ptr)> tcp_pre_bind_handler;
|
||||
|
||||
// generate and manage our own io_service
|
||||
explicit endpoint()
|
||||
: m_io_service(NULL)
|
||||
, 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<alog_type>& a, const lib::shared_ptr<elog_type>& 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 <typename error_type>
|
||||
lib::error_code clean_up_listen_after_error(error_type const & ec) {
|
||||
if (m_acceptor->is_open()) {
|
||||
m_acceptor->close();
|
||||
}
|
||||
log_err(log::elevel::info,"asio listen",ec);
|
||||
return socket_con_type::translate_ec(ec);
|
||||
}
|
||||
|
||||
enum state {
|
||||
UNINITIALIZED = 0,
|
||||
READY = 1,
|
||||
@ -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<elog_type> m_elog;
|
||||
lib::shared_ptr<alog_type> m_alog;
|
||||
|
||||
// Transport state
|
||||
state m_state;
|
@ -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 <typename ErrorCodeType>
|
||||
static
|
||||
lib::error_code translate_ec(ErrorCodeType) {
|
||||
// We don't know any more information about this error so pass through
|
||||
return make_error_code(transport::error::pass_through);
|
||||
}
|
||||
|
||||
/// 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
|
@ -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 <typename ErrorCodeType>
|
||||
static
|
||||
lib::error_code translate_ec(ErrorCodeType ec) {
|
||||
if (ec.category() == lib::asio::error::get_ssl_category()) {
|
||||
if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) {
|
||||
return make_error_code(transport::error::tls_short_read);
|
||||
} else {
|
||||
// We know it is a TLS related error, but otherwise don't know
|
||||
// more. Pass through as TLS generic.
|
||||
return make_error_code(transport::error::tls_error);
|
||||
}
|
||||
// We know it is a TLS related error, but otherwise don't know more.
|
||||
// Pass through as TLS generic.
|
||||
return make_error_code(transport::error::tls_error);
|
||||
} else {
|
||||
// We don't know any more information about this error so pass
|
||||
// through
|
||||
@ -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:
|
@ -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<alog_type>& a, const lib::shared_ptr<elog_type>& e)`\n
|
||||
* Called once after construction to provide pointers to the endpoint's access
|
||||
* and error loggers. These may be stored and used to log messages or ignored.
|
||||
*/
|
@ -77,7 +77,7 @@ public:
|
||||
|
||||
typedef lib::shared_ptr<timer> timer_ptr;
|
||||
|
||||
explicit connection(bool is_server, alog_type & alog, elog_type & elog)
|
||||
explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & 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<buffer> 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<std::streamsize>(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<alog_type> m_alog;
|
||||
lib::shared_ptr<elog_type> m_elog;
|
||||
std::string m_remote_endpoint;
|
||||
|
||||
// This lock ensures that only one thread can edit read data for this
|
@ -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<alog_type> a, lib::shared_ptr<elog_type> 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<elog_type> m_elog;
|
||||
lib::shared_ptr<alog_type> m_alog;
|
||||
bool m_is_secure;
|
||||
};
|
||||
|
@ -72,10 +72,10 @@ public:
|
||||
|
||||
typedef lib::shared_ptr<timer> timer_ptr;
|
||||
|
||||
explicit connection(bool is_server, alog_type & alog, elog_type & elog)
|
||||
explicit connection(bool is_server, const lib::shared_ptr<alog_type> & alog, const lib::shared_ptr<elog_type> & 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<buffer> 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<alog_type> m_alog;
|
||||
lib::shared_ptr<elog_type> m_elog;
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
@ -72,11 +72,9 @@ private:
|
||||
* Based on code from
|
||||
* http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find
|
||||
*/
|
||||
struct ci_less : std::binary_function<std::string, std::string, bool> {
|
||||
struct ci_less {
|
||||
// case-independent (ci) compare_less binary function
|
||||
struct nocase_compare
|
||||
: public std::binary_function<unsigned char,unsigned char,bool>
|
||||
{
|
||||
struct nocase_compare {
|
||||
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
|
||||
return tolower (c1) < tolower (c2);
|
||||
}
|
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user