Updating websocket++ to latest github release (0.3 alpha4).
This commit is contained in:
Vendored
+122
@@ -1,3 +1,5 @@
|
|||||||
|
Main Library:
|
||||||
|
|
||||||
Copyright (c) 2013, Peter Thorson. All rights reserved.
|
Copyright (c) 2013, Peter Thorson. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -21,3 +23,123 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
******
|
******
|
||||||
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
|
base64.hpp is a repackaging of the base64.cpp and base64.h files into a
|
||||||
single headersuitable for use as a header only library. This conversion was
|
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
|
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
|
the code are redistributed under the same license as the original, which is
|
||||||
listed below.
|
listed below.
|
||||||
|
|||||||
+4
-3
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
md5.hpp is a reformulation of the md5.h and md5.c code to allow it to function
|
md5.hpp is a reformulation of the md5.h and md5.c code from
|
||||||
as a component of a header only library. This conversion was done by Peter
|
http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to
|
||||||
Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The
|
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)
|
changes are released under the same license as the original (listed below)
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
|||||||
+7
-4
@@ -229,30 +229,37 @@ public:
|
|||||||
m_close_handler = h;
|
m_close_handler = h;
|
||||||
}
|
}
|
||||||
void set_fail_handler(fail_handler h) {
|
void set_fail_handler(fail_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_fail_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_fail_handler = h;
|
m_fail_handler = h;
|
||||||
}
|
}
|
||||||
void set_ping_handler(ping_handler h) {
|
void set_ping_handler(ping_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_ping_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_ping_handler = h;
|
m_ping_handler = h;
|
||||||
}
|
}
|
||||||
void set_pong_handler(pong_handler h) {
|
void set_pong_handler(pong_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_pong_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_pong_handler = h;
|
m_pong_handler = h;
|
||||||
}
|
}
|
||||||
void set_pong_timeout_handler(pong_timeout_handler h) {
|
void set_pong_timeout_handler(pong_timeout_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_pong_timeout_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_pong_timeout_handler = h;
|
m_pong_timeout_handler = h;
|
||||||
}
|
}
|
||||||
void set_interrupt_handler(interrupt_handler h) {
|
void set_interrupt_handler(interrupt_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_interrupt_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_interrupt_handler = h;
|
m_interrupt_handler = h;
|
||||||
}
|
}
|
||||||
void set_http_handler(http_handler h) {
|
void set_http_handler(http_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_http_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_http_handler = h;
|
m_http_handler = h;
|
||||||
}
|
}
|
||||||
void set_validate_handler(validate_handler h) {
|
void set_validate_handler(validate_handler h) {
|
||||||
|
m_alog.write(log::alevel::devel,"set_validate_handler");
|
||||||
scoped_lock_type guard(m_mutex);
|
scoped_lock_type guard(m_mutex);
|
||||||
m_validate_handler = h;
|
m_validate_handler = h;
|
||||||
}
|
}
|
||||||
@@ -390,7 +397,6 @@ public:
|
|||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
connection_ptr create_connection();
|
connection_ptr create_connection();
|
||||||
void remove_connection(connection_ptr con);
|
|
||||||
|
|
||||||
alog_type m_alog;
|
alog_type m_alog;
|
||||||
elog_type m_elog;
|
elog_type m_elog;
|
||||||
@@ -411,9 +417,6 @@ private:
|
|||||||
|
|
||||||
rng_type m_rng;
|
rng_type m_rng;
|
||||||
|
|
||||||
// endpoint resources
|
|
||||||
std::set<connection_ptr> m_connections;
|
|
||||||
|
|
||||||
// static settings
|
// static settings
|
||||||
bool const m_is_server;
|
bool const m_is_server;
|
||||||
|
|
||||||
|
|||||||
@@ -1177,27 +1177,27 @@ void connection<config>::handle_send_http_response(
|
|||||||
|
|
||||||
this->log_open_result();
|
this->log_open_result();
|
||||||
|
|
||||||
|
if (m_handshake_timer) {
|
||||||
|
m_handshake_timer->cancel();
|
||||||
|
m_handshake_timer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_response.get_status_code() != http::status_code::switching_protocols)
|
if (m_response.get_status_code() != http::status_code::switching_protocols)
|
||||||
{
|
{
|
||||||
if (m_processor) {
|
if (m_processor) {
|
||||||
// if this was not a websocket connection, we have written
|
|
||||||
// the expected response and the connection can be closed.
|
|
||||||
} else {
|
|
||||||
// this was a websocket connection that ended in an error
|
// this was a websocket connection that ended in an error
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "Handshake ended with HTTP error: "
|
s << "Handshake ended with HTTP error: "
|
||||||
<< m_response.get_status_code();
|
<< 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.
|
||||||
}
|
}
|
||||||
this->terminate(make_error_code(error::http_connection_ended));
|
this->terminate(make_error_code(error::http_connection_ended));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_handshake_timer) {
|
|
||||||
m_handshake_timer->cancel();
|
|
||||||
m_handshake_timer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->atomic_state_change(
|
this->atomic_state_change(
|
||||||
istate::PROCESS_HTTP_REQUEST,
|
istate::PROCESS_HTTP_REQUEST,
|
||||||
istate::PROCESS_CONNECTION,
|
istate::PROCESS_CONNECTION,
|
||||||
@@ -1339,6 +1339,11 @@ void connection<config>::handle_read_http_response(const lib::error_code& ec,
|
|||||||
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_response.headers_ready()) {
|
||||||
|
if (m_handshake_timer) {
|
||||||
|
m_handshake_timer->cancel();
|
||||||
|
m_handshake_timer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
lib::error_code ec = m_processor->validate_server_handshake_response(
|
lib::error_code ec = m_processor->validate_server_handshake_response(
|
||||||
m_request,
|
m_request,
|
||||||
m_response
|
m_response
|
||||||
@@ -1361,11 +1366,6 @@ void connection<config>::handle_read_http_response(const lib::error_code& ec,
|
|||||||
"handle_read_http_response must be called from READ_HTTP_RESPONSE state"
|
"handle_read_http_response must be called from READ_HTTP_RESPONSE state"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_handshake_timer) {
|
|
||||||
m_handshake_timer->cancel();
|
|
||||||
m_handshake_timer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->log_open_result();
|
this->log_open_result();
|
||||||
|
|
||||||
if (m_open_handler) {
|
if (m_open_handler) {
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ endpoint<connection,config>::create_connection() {
|
|||||||
// Cast that weak pointer to void* and manage it using another shared_ptr
|
// Cast that weak pointer to void* and manage it using another shared_ptr
|
||||||
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
|
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
|
||||||
|
|
||||||
// con->set_handle(hdl);
|
|
||||||
|
|
||||||
//
|
|
||||||
con->set_handle(w);
|
con->set_handle(w);
|
||||||
|
|
||||||
// Copy default handlers from the endpoint
|
// Copy default handlers from the endpoint
|
||||||
@@ -67,14 +64,6 @@ endpoint<connection,config>::create_connection() {
|
|||||||
con->set_validate_handler(m_validate_handler);
|
con->set_validate_handler(m_validate_handler);
|
||||||
con->set_message_handler(m_message_handler);
|
con->set_message_handler(m_message_handler);
|
||||||
|
|
||||||
con->set_termination_handler(
|
|
||||||
lib::bind(
|
|
||||||
&type::remove_connection,
|
|
||||||
this,
|
|
||||||
lib::placeholders::_1
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
|
|
||||||
ec = transport_type::init(con);
|
ec = transport_type::init(con);
|
||||||
@@ -83,9 +72,6 @@ endpoint<connection,config>::create_connection() {
|
|||||||
return connection_ptr();
|
return connection_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_lock_type lock(m_mutex);
|
|
||||||
m_connections.insert(con);
|
|
||||||
|
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,20 +202,6 @@ void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
|||||||
if (ec) { throw ec; }
|
if (ec) { throw ec; }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
|
||||||
void endpoint<connection,config>::remove_connection(connection_ptr con) {
|
|
||||||
std::stringstream s;
|
|
||||||
s << "remove_connection. New count: " << m_connections.size()-1;
|
|
||||||
m_alog.write(log::alevel::devel,s.str());
|
|
||||||
|
|
||||||
scoped_lock_type lock(m_mutex);
|
|
||||||
|
|
||||||
// unregister the termination handler
|
|
||||||
con->set_termination_handler(termination_handler());
|
|
||||||
|
|
||||||
m_connections.erase(con);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP
|
#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP
|
||||||
|
|||||||
@@ -614,27 +614,11 @@ protected:
|
|||||||
lib::error_code process_handshake_key(std::string & key) const {
|
lib::error_code process_handshake_key(std::string & key) const {
|
||||||
key.append(constants::handshake_guid);
|
key.append(constants::handshake_guid);
|
||||||
|
|
||||||
sha1 sha;
|
unsigned char message_digest[20];
|
||||||
uint32_t message_digest[5];
|
sha1::calc(key.c_str(),key.length(),message_digest);
|
||||||
|
key = base64_encode(message_digest,20);
|
||||||
sha << key.c_str();
|
|
||||||
|
|
||||||
if (sha.get_raw_digest(message_digest)){
|
|
||||||
// convert sha1 hash bytes to network byte order because this sha1
|
|
||||||
// library works on ints rather than bytes
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
message_digest[i] = htonl(message_digest[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
key = base64_encode(
|
|
||||||
reinterpret_cast<unsigned char const *>(message_digest),
|
|
||||||
20
|
|
||||||
);
|
|
||||||
|
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
} else {
|
|
||||||
return error::make_error_code(error::sha1_library);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads bytes from buf into m_basic_header
|
/// Reads bytes from buf into m_basic_header
|
||||||
|
|||||||
@@ -66,8 +66,7 @@ public:
|
|||||||
|
|
||||||
explicit client() : endpoint_type(false)
|
explicit client() : endpoint_type(false)
|
||||||
{
|
{
|
||||||
endpoint_type::m_alog.write(log::alevel::devel,
|
endpoint_type::m_alog.write(log::alevel::devel, "client constructor");
|
||||||
"client constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a new connection
|
/// Get a new connection
|
||||||
@@ -77,15 +76,17 @@ public:
|
|||||||
* applying connection specific settings before performing the opening
|
* applying connection specific settings before performing the opening
|
||||||
* handshake.
|
* handshake.
|
||||||
*
|
*
|
||||||
|
* @param [in] location URI to open the connection to as a uri_ptr
|
||||||
|
* @param [out] ec An status code indicating failure reasons, if any
|
||||||
|
*
|
||||||
* @return A connection_ptr to the new connection
|
* @return A connection_ptr to the new connection
|
||||||
*/
|
*/
|
||||||
connection_ptr get_connection(uri_ptr location, lib::error_code &ec) {
|
connection_ptr get_connection(uri_ptr location, lib::error_code & ec) {
|
||||||
if (location->get_secure() && !transport_type::is_secure()) {
|
if (location->get_secure() && !transport_type::is_secure()) {
|
||||||
ec = error::make_error_code(error::endpoint_not_secure);
|
ec = error::make_error_code(error::endpoint_not_secure);
|
||||||
return connection_ptr();
|
return connection_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// create connection
|
|
||||||
connection_ptr con = endpoint_type::create_connection();
|
connection_ptr con = endpoint_type::create_connection();
|
||||||
|
|
||||||
if (!con) {
|
if (!con) {
|
||||||
@@ -95,7 +96,6 @@ public:
|
|||||||
|
|
||||||
con->set_uri(location);
|
con->set_uri(location);
|
||||||
|
|
||||||
// Success
|
|
||||||
ec = lib::error_code();
|
ec = lib::error_code();
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
@@ -106,10 +106,12 @@ public:
|
|||||||
* suitable for passing to connect(connection_ptr). This overload allows
|
* suitable for passing to connect(connection_ptr). This overload allows
|
||||||
* default construction of the uri_ptr from a standard string.
|
* default construction of the uri_ptr from a standard string.
|
||||||
*
|
*
|
||||||
|
* @param [in] u URI to open the connection to as a string
|
||||||
|
* @param [out] ec An status code indicating failure reasons, if any
|
||||||
|
*
|
||||||
* @return A connection_ptr to the new connection
|
* @return A connection_ptr to the new connection
|
||||||
*/
|
*/
|
||||||
connection_ptr get_connection(const std::string& u, lib::error_code &ec) {
|
connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
|
||||||
// parse uri
|
|
||||||
uri_ptr location(new uri(u));
|
uri_ptr location(new uri(u));
|
||||||
|
|
||||||
if (!location->get_valid()) {
|
if (!location->get_valid()) {
|
||||||
@@ -137,35 +139,17 @@ public:
|
|||||||
lib::bind(
|
lib::bind(
|
||||||
&type::handle_connect,
|
&type::handle_connect,
|
||||||
this,
|
this,
|
||||||
lib::placeholders::_1,
|
con,
|
||||||
lib::placeholders::_2
|
lib::placeholders::_1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// connect(...)
|
|
||||||
private:
|
private:
|
||||||
// handle_connect
|
// handle_connect
|
||||||
void handle_connect(connection_hdl hdl, const lib::error_code & ec) {
|
void handle_connect(connection_ptr con, lib::error_code const & ec) {
|
||||||
lib::error_code hdl_ec;
|
if (ec) {
|
||||||
connection_ptr con = endpoint_type::get_con_from_hdl(hdl,hdl_ec);
|
|
||||||
|
|
||||||
if (hdl_ec == error::bad_connection) {
|
|
||||||
endpoint_type::m_elog.write(log::elevel::fatal,
|
|
||||||
"handle_connect got an invalid handle back");
|
|
||||||
} else if (hdl_ec) {
|
|
||||||
// There was some other unknown error attempting to convert the hdl
|
|
||||||
// to a connection.
|
|
||||||
endpoint_type::m_elog.write(log::elevel::fatal,
|
|
||||||
"handle_connect error in get_con_from_hdl: "+hdl_ec.message());
|
|
||||||
//con->terminate();
|
|
||||||
} else if (ec) {
|
|
||||||
// TODO
|
|
||||||
// Set connection's failure reasons
|
|
||||||
con->terminate(ec);
|
con->terminate(ec);
|
||||||
|
|
||||||
endpoint_type::m_elog.write(log::elevel::rerror,
|
endpoint_type::m_elog.write(log::elevel::rerror,
|
||||||
|
|||||||
@@ -90,29 +90,13 @@ public:
|
|||||||
lib::bind(
|
lib::bind(
|
||||||
&type::handle_accept,
|
&type::handle_accept,
|
||||||
this,
|
this,
|
||||||
lib::placeholders::_1,
|
con,
|
||||||
lib::placeholders::_2
|
lib::placeholders::_1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_accept(connection_hdl hdl, const lib::error_code& ec) {
|
void handle_accept(connection_ptr con, const lib::error_code& ec) {
|
||||||
lib::error_code hdl_ec;
|
|
||||||
connection_ptr con = endpoint_type::get_con_from_hdl(hdl,hdl_ec);
|
|
||||||
|
|
||||||
if (hdl_ec == error::bad_connection) {
|
|
||||||
// The connection we were trying to connect went out of scope
|
|
||||||
// This really shouldn't happen
|
|
||||||
endpoint_type::m_elog.write(log::elevel::fatal,
|
|
||||||
"handle_accept got an invalid handle back");
|
|
||||||
//con->terminate();
|
|
||||||
} else if (hdl_ec) {
|
|
||||||
// There was some other unknown error attempting to convert the hdl
|
|
||||||
// to a connection.
|
|
||||||
endpoint_type::m_elog.write(log::elevel::fatal,
|
|
||||||
"handle_accept error in get_con_from_hdl: "+hdl_ec.message());
|
|
||||||
//con->terminate();
|
|
||||||
} else {
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
con->terminate(ec);
|
con->terminate(ec);
|
||||||
|
|
||||||
@@ -121,7 +105,6 @@ public:
|
|||||||
} else {
|
} else {
|
||||||
con->start();
|
con->start();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: are there cases where we should terminate this loop?
|
// TODO: are there cases where we should terminate this loop?
|
||||||
start_accept();
|
start_accept();
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
Copyright (C) 1998, 2009
|
|
||||||
Paul E. Jones <paulej@packetizer.com>
|
|
||||||
|
|
||||||
Freeware Public License (FPL)
|
|
||||||
|
|
||||||
This software is licensed as "freeware." Permission to distribute
|
|
||||||
this software in source and binary forms, including incorporation
|
|
||||||
into other products, is hereby granted without a fee. THIS SOFTWARE
|
|
||||||
IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
||||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD
|
|
||||||
LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER
|
|
||||||
DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA
|
|
||||||
OR DATA BEING RENDERED INACCURATE.
|
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Contributors:
|
||||||
|
Gustav
|
||||||
|
Several members in the gamedev.se forum.
|
||||||
|
Gregory Petrosyan
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sha1.h"
|
||||||
|
|
||||||
|
namespace sha1
|
||||||
|
{
|
||||||
|
namespace // local
|
||||||
|
{
|
||||||
|
// Rotate an integer value to left.
|
||||||
|
inline const unsigned int rol(const unsigned int value,
|
||||||
|
const unsigned int steps)
|
||||||
|
{
|
||||||
|
return ((value << steps) | (value >> (32 - steps)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the first 16 integers in the buffert to zero.
|
||||||
|
// Used for clearing the W buffert.
|
||||||
|
inline void clearWBuffert(unsigned int* buffert)
|
||||||
|
{
|
||||||
|
for (int pos = 16; --pos >= 0;)
|
||||||
|
{
|
||||||
|
buffert[pos] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void innerHash(unsigned int* result, unsigned int* w)
|
||||||
|
{
|
||||||
|
unsigned int a = result[0];
|
||||||
|
unsigned int b = result[1];
|
||||||
|
unsigned int c = result[2];
|
||||||
|
unsigned int d = result[3];
|
||||||
|
unsigned int e = result[4];
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
|
||||||
|
#define sha1macro(func,val) \
|
||||||
|
{ \
|
||||||
|
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||||
|
e = d; \
|
||||||
|
d = c; \
|
||||||
|
c = rol(b, 30); \
|
||||||
|
b = a; \
|
||||||
|
a = t; \
|
||||||
|
}
|
||||||
|
|
||||||
|
while (round < 16)
|
||||||
|
{
|
||||||
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 20)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 40)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 60)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 80)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef sha1macro
|
||||||
|
|
||||||
|
result[0] += a;
|
||||||
|
result[1] += b;
|
||||||
|
result[2] += c;
|
||||||
|
result[3] += d;
|
||||||
|
result[4] += e;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void calc(const void* src, const int bytelength, unsigned char* hash)
|
||||||
|
{
|
||||||
|
// Init the result array.
|
||||||
|
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
|
||||||
|
|
||||||
|
// Cast the void src pointer to be the byte array we can work with.
|
||||||
|
const unsigned char* sarray = (const unsigned char*) src;
|
||||||
|
|
||||||
|
// The reusable round buffer
|
||||||
|
unsigned int w[80];
|
||||||
|
|
||||||
|
// Loop through all complete 64byte blocks.
|
||||||
|
const int endOfFullBlocks = bytelength - 64;
|
||||||
|
int endCurrentBlock;
|
||||||
|
int currentBlock = 0;
|
||||||
|
|
||||||
|
while (currentBlock <= endOfFullBlocks)
|
||||||
|
{
|
||||||
|
endCurrentBlock = currentBlock + 64;
|
||||||
|
|
||||||
|
// Init the round buffer with the 64 byte block data.
|
||||||
|
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||||
|
{
|
||||||
|
// This line will swap endian on big endian and keep endian on little endian.
|
||||||
|
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||||
|
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||||
|
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||||
|
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||||
|
}
|
||||||
|
innerHash(result, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the last and not full 64 byte block if existing.
|
||||||
|
endCurrentBlock = bytelength - currentBlock;
|
||||||
|
clearWBuffert(w);
|
||||||
|
int lastBlockBytes = 0;
|
||||||
|
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes)
|
||||||
|
{
|
||||||
|
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
|
}
|
||||||
|
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
|
if (endCurrentBlock >= 56)
|
||||||
|
{
|
||||||
|
innerHash(result, w);
|
||||||
|
clearWBuffert(w);
|
||||||
|
}
|
||||||
|
w[15] = bytelength << 3;
|
||||||
|
innerHash(result, w);
|
||||||
|
|
||||||
|
// Store hash in result pointer, and make sure we get in in the correct order on both endian models.
|
||||||
|
for (int hashByte = 20; --hashByte >= 0;)
|
||||||
|
{
|
||||||
|
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toHexString(const unsigned char* hash, char* hexstring)
|
||||||
|
{
|
||||||
|
const char hexDigits[] = { "0123456789abcdef" };
|
||||||
|
|
||||||
|
for (int hashByte = 20; --hashByte >= 0;)
|
||||||
|
{
|
||||||
|
hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf];
|
||||||
|
hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf];
|
||||||
|
}
|
||||||
|
hexstring[40] = 0;
|
||||||
|
}
|
||||||
|
} // namespace sha1
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHA1_DEFINED
|
||||||
|
#define SHA1_DEFINED
|
||||||
|
|
||||||
|
namespace sha1
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@param src points to any kind of data to be hashed.
|
||||||
|
@param bytelength the number of bytes to hash from the src pointer.
|
||||||
|
@param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
|
||||||
|
*/
|
||||||
|
void calc(const void* src, const int bytelength, unsigned char* hash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function.
|
||||||
|
@param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string.
|
||||||
|
*/
|
||||||
|
void toHexString(const unsigned char* hash, char* hexstring);
|
||||||
|
|
||||||
|
} // namespace sha1
|
||||||
|
|
||||||
|
#endif // SHA1_DEFINED
|
||||||
+162
-384
@@ -1,406 +1,184 @@
|
|||||||
/*
|
/*
|
||||||
* sha1.hpp
|
*****
|
||||||
*
|
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the shallsha1
|
||||||
* Copyright (C) 1998, 2009
|
library (http://code.google.com/p/smallsha1/) into a single header suitable for
|
||||||
* Paul E. Jones <paulej@packetizer.com>
|
use as a header only library. This conversion was done by Peter Thorson
|
||||||
* All Rights Reserved.
|
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||||
*
|
under the same license as the original, which is listed below.
|
||||||
* Modifications were done in 2012-13 by Peter Thorson (webmaster@zaphoyd.com)
|
*****
|
||||||
* to allow header only usage of the library and use C++ features to better
|
|
||||||
* support C++ usage. These changes are distributed under the original freeware
|
Copyright (c) 2011, Micael Hildenborg
|
||||||
* license included below
|
All rights reserved.
|
||||||
*
|
|
||||||
* Freeware Public License (FPL)
|
Redistribution and use in source and binary forms, with or without
|
||||||
*
|
modification, are permitted provided that the following conditions are met:
|
||||||
* This software is licensed as "freeware." Permission to distribute
|
* Redistributions of source code must retain the above copyright
|
||||||
* this software in source and binary forms, including incorporation
|
notice, this list of conditions and the following disclaimer.
|
||||||
* into other products, is hereby granted without a fee. THIS SOFTWARE
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
* IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES,
|
notice, this list of conditions and the following disclaimer in the
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
documentation and/or other materials provided with the distribution.
|
||||||
* AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD
|
* Neither the name of Micael Hildenborg nor the
|
||||||
* LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER
|
names of its contributors may be used to endorse or promote products
|
||||||
* DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA
|
derived from this software without specific prior written permission.
|
||||||
* OR DATA BEING RENDERED INACCURATE.
|
|
||||||
*
|
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
|
||||||
* Description:
|
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||||
* This class implements the Secure Hashing Standard as defined
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* in FIPS PUB 180-1 published April 17, 1995.
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
*
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* Many of the variable names in this class, especially the single
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* character names, were used because those were the names used
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* in the publication.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* The Secure Hashing Standard, which uses the Secure Hashing
|
|
||||||
* Algorithm (SHA), produces a 160-bit message digest for a
|
|
||||||
* given data stream. In theory, it is highly improbable that
|
|
||||||
* two messages will produce the same message digest. Therefore,
|
|
||||||
* this algorithm can serve as a means of providing a "fingerprint"
|
|
||||||
* for a message.
|
|
||||||
*
|
|
||||||
* Portability Issues:
|
|
||||||
* SHA-1 is defined in terms of 32-bit "words". This code was
|
|
||||||
* written with the expectation that the processor has at least
|
|
||||||
* a 32-bit machine word size. If the machine word size is larger,
|
|
||||||
* the code should still function properly. One caveat to that
|
|
||||||
* is that the input functions taking characters and character arrays
|
|
||||||
* assume that only 8 bits of information are stored in each character.
|
|
||||||
*
|
|
||||||
* Caveats:
|
|
||||||
* SHA-1 is designed to work with messages less than 2^64 bits long.
|
|
||||||
* Although SHA-1 allows a message digest to be generated for
|
|
||||||
* messages of any number of bits less than 2^64, this implementation
|
|
||||||
* only works with messages with a length that is a multiple of 8
|
|
||||||
* bits.
|
|
||||||
*
|
|
||||||
*****************************************************************************
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SHA1_H_
|
#ifndef SHA1_DEFINED
|
||||||
#define _SHA1_H_
|
#define SHA1_DEFINED
|
||||||
|
|
||||||
#include <websocketpp/common/stdint.hpp>
|
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
|
namespace sha1 {
|
||||||
|
|
||||||
/// Provides SHA1 hashing functionality
|
namespace // local
|
||||||
class sha1 {
|
{
|
||||||
public:
|
// Rotate an integer value to left.
|
||||||
sha1() {
|
inline const unsigned int rol(const unsigned int value,
|
||||||
reset();
|
const unsigned int steps)
|
||||||
|
{
|
||||||
|
return ((value << steps) | (value >> (32 - steps)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~sha1() {}
|
// Sets the first 16 integers in the buffert to zero.
|
||||||
|
// Used for clearing the W buffert.
|
||||||
/// Re-initialize the class
|
inline void clearWBuffert(unsigned int* buffert)
|
||||||
void reset() {
|
{
|
||||||
length_low = 0;
|
for (int pos = 16; --pos >= 0;)
|
||||||
length_high = 0;
|
{
|
||||||
message_block_index = 0;
|
buffert[pos] = 0;
|
||||||
|
}
|
||||||
H[0] = 0x67452301;
|
|
||||||
H[1] = 0xEFCDAB89;
|
|
||||||
H[2] = 0x98BADCFE;
|
|
||||||
H[3] = 0x10325476;
|
|
||||||
H[4] = 0xC3D2E1F0;
|
|
||||||
|
|
||||||
computed = false;
|
|
||||||
corrupted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the message digest as a raw integer array
|
inline void innerHash(unsigned int* result, unsigned int* w)
|
||||||
|
{
|
||||||
|
unsigned int a = result[0];
|
||||||
|
unsigned int b = result[1];
|
||||||
|
unsigned int c = result[2];
|
||||||
|
unsigned int d = result[3];
|
||||||
|
unsigned int e = result[4];
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
|
||||||
|
#define sha1macro(func,val) \
|
||||||
|
{ \
|
||||||
|
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||||
|
e = d; \
|
||||||
|
d = c; \
|
||||||
|
c = rol(b, 30); \
|
||||||
|
b = a; \
|
||||||
|
a = t; \
|
||||||
|
}
|
||||||
|
|
||||||
|
while (round < 16)
|
||||||
|
{
|
||||||
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 20)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 40)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 60)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
while (round < 80)
|
||||||
|
{
|
||||||
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
|
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||||
|
++round;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef sha1macro
|
||||||
|
|
||||||
|
result[0] += a;
|
||||||
|
result[1] += b;
|
||||||
|
result[2] += c;
|
||||||
|
result[3] += d;
|
||||||
|
result[4] += e;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param [out] message_digest_array Integer array to store the message in
|
@param src points to any kind of data to be hashed.
|
||||||
* @return Whether or not the extraction was sucessful
|
@param bytelength the number of bytes to hash from the src pointer.
|
||||||
|
@param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
|
||||||
*/
|
*/
|
||||||
bool get_raw_digest(uint32_t * message_digest_array) {
|
inline void calc(const void* src, const int bytelength, unsigned char* hash) {
|
||||||
if (corrupted) {
|
// Init the result array.
|
||||||
return false;
|
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
|
||||||
|
|
||||||
|
// Cast the void src pointer to be the byte array we can work with.
|
||||||
|
const unsigned char* sarray = (const unsigned char*) src;
|
||||||
|
|
||||||
|
// The reusable round buffer
|
||||||
|
unsigned int w[80];
|
||||||
|
|
||||||
|
// Loop through all complete 64byte blocks.
|
||||||
|
const int endOfFullBlocks = bytelength - 64;
|
||||||
|
int endCurrentBlock;
|
||||||
|
int currentBlock = 0;
|
||||||
|
|
||||||
|
while (currentBlock <= endOfFullBlocks)
|
||||||
|
{
|
||||||
|
endCurrentBlock = currentBlock + 64;
|
||||||
|
|
||||||
|
// Init the round buffer with the 64 byte block data.
|
||||||
|
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||||
|
{
|
||||||
|
// This line will swap endian on big endian and keep endian on little endian.
|
||||||
|
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||||
|
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||||
|
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||||
|
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||||
|
}
|
||||||
|
innerHash(result, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!computed) {
|
// Handle the last and not full 64 byte block if existing.
|
||||||
pad_message();
|
endCurrentBlock = bytelength - currentBlock;
|
||||||
computed = true;
|
clearWBuffert(w);
|
||||||
|
int lastBlockBytes = 0;
|
||||||
|
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes)
|
||||||
|
{
|
||||||
|
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
}
|
}
|
||||||
|
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
for (int i = 0; i < 5; i++) {
|
if (endCurrentBlock >= 56)
|
||||||
message_digest_array[i] = H[i];
|
{
|
||||||
|
innerHash(result, w);
|
||||||
|
clearWBuffert(w);
|
||||||
}
|
}
|
||||||
|
w[15] = bytelength << 3;
|
||||||
|
innerHash(result, w);
|
||||||
|
|
||||||
return true;
|
// Store hash in result pointer, and make sure we get in in the correct order on both endian models.
|
||||||
}
|
for (int hashByte = 20; --hashByte >= 0;)
|
||||||
|
{
|
||||||
/// Provide input to SHA1
|
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||||
/**
|
|
||||||
* @param [in] message_array The input bytes
|
|
||||||
* @param [in] length Length of the message array
|
|
||||||
*/
|
|
||||||
void input(unsigned char const * message_array, uint32_t length) {
|
|
||||||
if (!length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (computed || corrupted) {
|
|
||||||
corrupted = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (length-- && !corrupted) {
|
|
||||||
// Suppresses Visual Studio code analysis for write overrun. It doesn't know the
|
|
||||||
// index into Message_Block is protected by checking length.
|
|
||||||
//
|
|
||||||
// TODO: is there a more compatible way to write the original code to avoid
|
|
||||||
// this sort of warning?
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(suppress: 6386)
|
|
||||||
#endif
|
|
||||||
message_block[message_block_index++] = (*message_array & 0xFF);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
length_low += 8;
|
|
||||||
length_low &= 0xFFFFFFFF; // Force it to 32 bits
|
|
||||||
if (length_low == 0) {
|
|
||||||
length_high++;
|
|
||||||
length_high &= 0xFFFFFFFF; // Force it to 32 bits
|
|
||||||
if (length_high == 0) {
|
|
||||||
corrupted = true; // Message is too long
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message_block_index == 64) {
|
} // namespace sha1
|
||||||
process_message_block();
|
|
||||||
}
|
|
||||||
|
|
||||||
message_array++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload with signed message array
|
|
||||||
*
|
|
||||||
* @param [in] message_array The input bytes
|
|
||||||
* @param [in] length Length of the message array
|
|
||||||
*/
|
|
||||||
void input(char const * message_array, uint32_t length) {
|
|
||||||
input(reinterpret_cast<const unsigned char *>(message_array), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload with a single unsigned char
|
|
||||||
*
|
|
||||||
* @param [in] message_element The character to input
|
|
||||||
*/
|
|
||||||
void input(unsigned char message_element) {
|
|
||||||
input(&message_element, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload with a single signed char
|
|
||||||
*
|
|
||||||
* @param [in] message_element The character to input
|
|
||||||
*/
|
|
||||||
void input(char message_element) {
|
|
||||||
input(reinterpret_cast<unsigned char *>(&message_element), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload via signed char array stream input
|
|
||||||
*
|
|
||||||
* @param [in] message_array The character array to input
|
|
||||||
*/
|
|
||||||
sha1& operator<<(char const * message_array) {
|
|
||||||
char const * p = message_array;
|
|
||||||
|
|
||||||
while(*p) {
|
|
||||||
input(*p);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload via unsigned char array stream input
|
|
||||||
*
|
|
||||||
* @param [in] message_array The character array to input
|
|
||||||
*/
|
|
||||||
sha1& operator<<(unsigned char const * message_array) {
|
|
||||||
unsigned char const * p = message_array;
|
|
||||||
|
|
||||||
while(*p) {
|
|
||||||
input(*p);
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload via signed char stream input
|
|
||||||
*
|
|
||||||
* @param [in] message_element The character to input
|
|
||||||
*/
|
|
||||||
sha1& operator<<(char message_element) {
|
|
||||||
input((unsigned char *) &message_element, 1);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide input to SHA1
|
|
||||||
/**
|
|
||||||
* Overload via unsigned char stream input
|
|
||||||
*
|
|
||||||
* @param [in] message_element The character to input
|
|
||||||
*/
|
|
||||||
sha1& operator<<(unsigned char message_element) {
|
|
||||||
input(&message_element, 1);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
/// Process the next 512 bits of the message
|
|
||||||
/**
|
|
||||||
* Many of the variable names in this function, especially the single
|
|
||||||
* character names, were used because those were the names used
|
|
||||||
* in the publication.
|
|
||||||
*/
|
|
||||||
void process_message_block() {
|
|
||||||
// Constants defined for SHA-1
|
|
||||||
uint32_t const K[] = { 0x5A827999,
|
|
||||||
0x6ED9EBA1,
|
|
||||||
0x8F1BBCDC,
|
|
||||||
0xCA62C1D6 };
|
|
||||||
uint32_t temp; // Temporary word value
|
|
||||||
uint32_t W[80]; // Word sequence
|
|
||||||
uint32_t A, B, C, D, E; // Word buffers
|
|
||||||
|
|
||||||
// Initialize the first 16 words in the array W
|
|
||||||
for (int t = 0; t < 16; t++) {
|
|
||||||
W[t] = ((uint32_t) message_block[t * 4]) << 24;
|
|
||||||
W[t] |= ((uint32_t) message_block[t * 4 + 1]) << 16;
|
|
||||||
W[t] |= ((uint32_t) message_block[t * 4 + 2]) << 8;
|
|
||||||
W[t] |= ((uint32_t) message_block[t * 4 + 3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int t = 16; t < 80; t++) {
|
|
||||||
W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
|
|
||||||
}
|
|
||||||
|
|
||||||
A = H[0];
|
|
||||||
B = H[1];
|
|
||||||
C = H[2];
|
|
||||||
D = H[3];
|
|
||||||
E = H[4];
|
|
||||||
|
|
||||||
for (int t = 0; t < 20; t++) {
|
|
||||||
temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
|
|
||||||
temp &= 0xFFFFFFFF;
|
|
||||||
E = D;
|
|
||||||
D = C;
|
|
||||||
C = CircularShift(30,B);
|
|
||||||
B = A;
|
|
||||||
A = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int t = 20; t < 40; t++) {
|
|
||||||
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
|
|
||||||
temp &= 0xFFFFFFFF;
|
|
||||||
E = D;
|
|
||||||
D = C;
|
|
||||||
C = CircularShift(30,B);
|
|
||||||
B = A;
|
|
||||||
A = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int t = 40; t < 60; t++) {
|
|
||||||
temp = CircularShift(5,A) +
|
|
||||||
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
|
|
||||||
temp &= 0xFFFFFFFF;
|
|
||||||
E = D;
|
|
||||||
D = C;
|
|
||||||
C = CircularShift(30,B);
|
|
||||||
B = A;
|
|
||||||
A = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int t = 60; t < 80; t++) {
|
|
||||||
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
|
|
||||||
temp &= 0xFFFFFFFF;
|
|
||||||
E = D;
|
|
||||||
D = C;
|
|
||||||
C = CircularShift(30,B);
|
|
||||||
B = A;
|
|
||||||
A = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
H[0] = (H[0] + A) & 0xFFFFFFFF;
|
|
||||||
H[1] = (H[1] + B) & 0xFFFFFFFF;
|
|
||||||
H[2] = (H[2] + C) & 0xFFFFFFFF;
|
|
||||||
H[3] = (H[3] + D) & 0xFFFFFFFF;
|
|
||||||
H[4] = (H[4] + E) & 0xFFFFFFFF;
|
|
||||||
|
|
||||||
message_block_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Pads the current message block to 512 bits
|
|
||||||
/**
|
|
||||||
* According to the standard, the message must be padded to an even
|
|
||||||
* 512 bits. The first padding bit must be a '1'. The last 64 bits
|
|
||||||
* represent the length of the original message. All bits in between
|
|
||||||
* should be 0. This function will pad the message according to those
|
|
||||||
* rules by filling the message_block array accordingly. It will also
|
|
||||||
* call ProcessMessageBlock() appropriately. When it returns, it
|
|
||||||
* can be assumed that the message digest has been computed.
|
|
||||||
*/
|
|
||||||
void pad_message() {
|
|
||||||
// Check to see if the current message block is too small to hold
|
|
||||||
// the initial padding bits and length. If so, we will pad the
|
|
||||||
// block, process it, and then continue padding into a second block.
|
|
||||||
if (message_block_index > 55) {
|
|
||||||
message_block[message_block_index++] = 0x80;
|
|
||||||
while(message_block_index < 64) {
|
|
||||||
message_block[message_block_index++] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
process_message_block();
|
|
||||||
|
|
||||||
while(message_block_index < 56) {
|
|
||||||
message_block[message_block_index++] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message_block[message_block_index++] = 0x80;
|
|
||||||
while(message_block_index < 56) {
|
|
||||||
message_block[message_block_index++] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the message length as the last 8 octets
|
|
||||||
message_block[56] = (length_high >> 24) & 0xFF;
|
|
||||||
message_block[57] = (length_high >> 16) & 0xFF;
|
|
||||||
message_block[58] = (length_high >> 8) & 0xFF;
|
|
||||||
message_block[59] = (length_high) & 0xFF;
|
|
||||||
message_block[60] = (length_low >> 24) & 0xFF;
|
|
||||||
message_block[61] = (length_low >> 16) & 0xFF;
|
|
||||||
message_block[62] = (length_low >> 8) & 0xFF;
|
|
||||||
message_block[63] = (length_low) & 0xFF;
|
|
||||||
|
|
||||||
process_message_block();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs a circular left shift operation
|
|
||||||
/**
|
|
||||||
* @param [in] bits How many bits to shift
|
|
||||||
* @param [in] word The word to shift
|
|
||||||
* @return The shifted word
|
|
||||||
*/
|
|
||||||
inline uint32_t CircularShift(int bits, uint32_t word) {
|
|
||||||
return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t H[5]; // Message digest buffers
|
|
||||||
|
|
||||||
uint32_t length_low; // Message length in bits
|
|
||||||
uint32_t length_high; // Message length in bits
|
|
||||||
|
|
||||||
unsigned char message_block[64]; // 512-bit message blocks
|
|
||||||
int message_block_index; // Index into message block array
|
|
||||||
|
|
||||||
bool computed; // Is the digest computed?
|
|
||||||
bool corrupted; // Is the message digest corruped?
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
#endif // _SHA1_H_
|
#endif // SHA1_DEFINED
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ namespace transport {
|
|||||||
*/
|
*/
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
// Forward declaration of class endpoint so that it can be friended/referenced
|
||||||
|
// before being included.
|
||||||
|
template <typename config>
|
||||||
|
class endpoint;
|
||||||
|
|
||||||
typedef lib::function<void(boost::system::error_code const &)>
|
typedef lib::function<void(boost::system::error_code const &)>
|
||||||
socket_shutdown_handler;
|
socket_shutdown_handler;
|
||||||
|
|
||||||
|
|||||||
@@ -81,9 +81,16 @@ public:
|
|||||||
|
|
||||||
/// Type of a pointer to the ASIO io_service being used
|
/// Type of a pointer to the ASIO io_service being used
|
||||||
typedef boost::asio::io_service* io_service_ptr;
|
typedef boost::asio::io_service* io_service_ptr;
|
||||||
|
/// Type of a pointer to the ASIO io_service::strand being used
|
||||||
|
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
||||||
/// Type of a pointer to the ASIO timer class
|
/// Type of a pointer to the ASIO timer class
|
||||||
typedef lib::shared_ptr<boost::asio::deadline_timer> timer_ptr;
|
typedef lib::shared_ptr<boost::asio::deadline_timer> timer_ptr;
|
||||||
|
|
||||||
|
// connection is friends with its associated endpoint to allow the endpoint
|
||||||
|
// to call private/protected utility methods that we don't want to expose
|
||||||
|
// to the public api.
|
||||||
|
friend class endpoint<config>;
|
||||||
|
|
||||||
// generate and manage our own io_service
|
// generate and manage our own io_service
|
||||||
explicit connection(bool is_server, alog_type& alog, elog_type& elog)
|
explicit connection(bool is_server, alog_type& alog, elog_type& elog)
|
||||||
: m_is_server(is_server)
|
: m_is_server(is_server)
|
||||||
@@ -102,29 +109,13 @@ public:
|
|||||||
return socket_con_type::is_secure();
|
return socket_con_type::is_secure();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish constructing the transport
|
/// Sets the tcp init handler
|
||||||
/**
|
/**
|
||||||
* init_asio is called once immediately after construction to initialize
|
* The tcp init handler is called after the tcp connection has been
|
||||||
* boost::asio components to the io_service
|
* established.
|
||||||
*
|
*
|
||||||
* TODO: this method is not protected because the endpoint needs to call it.
|
* @param h The handler to call on tcp init.
|
||||||
* need to figure out if there is a way to friend the endpoint safely across
|
|
||||||
* different compilers.
|
|
||||||
*
|
|
||||||
* @param io_service A pointer to the io_service to register with this
|
|
||||||
* connection
|
|
||||||
*
|
|
||||||
* @return Status code for the success or failure of the initialization
|
|
||||||
*/
|
*/
|
||||||
lib::error_code init_asio (io_service_ptr io_service) {
|
|
||||||
// do we need to store or use the io_service at this level?
|
|
||||||
m_io_service = io_service;
|
|
||||||
|
|
||||||
//m_strand.reset(new boost::asio::strand(*io_service));
|
|
||||||
|
|
||||||
return socket_con_type::init_asio(io_service, m_is_server);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_tcp_init_handler(tcp_init_handler h) {
|
void set_tcp_init_handler(tcp_init_handler h) {
|
||||||
m_tcp_init_handler = h;
|
m_tcp_init_handler = h;
|
||||||
}
|
}
|
||||||
@@ -251,26 +242,6 @@ public:
|
|||||||
return m_connection_hdl;
|
return m_connection_hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// initialize the proxy buffers and http parsers
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param authority The address of the server we want the proxy to tunnel to
|
|
||||||
* in the format of a URI authority (host:port)
|
|
||||||
*/
|
|
||||||
lib::error_code proxy_init(const std::string & authority) {
|
|
||||||
if (!m_proxy_data) {
|
|
||||||
return websocketpp::error::make_error_code(
|
|
||||||
websocketpp::error::invalid_state);
|
|
||||||
}
|
|
||||||
m_proxy_data->req.set_version("HTTP/1.1");
|
|
||||||
m_proxy_data->req.set_method("CONNECT");
|
|
||||||
|
|
||||||
m_proxy_data->req.set_uri(authority);
|
|
||||||
m_proxy_data->req.replace_header("Host",authority);
|
|
||||||
|
|
||||||
return lib::error_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Call back a function after a period of time.
|
/// Call back a function after a period of time.
|
||||||
/**
|
/**
|
||||||
* Sets a timer that calls back a function after the specified period of
|
* Sets a timer that calls back a function after the specified period of
|
||||||
@@ -294,13 +265,13 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
new_timer->async_wait(
|
new_timer->async_wait(
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_timer,
|
&type::handle_timer,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
new_timer,
|
new_timer,
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
return new_timer;
|
return new_timer;
|
||||||
@@ -311,10 +282,10 @@ public:
|
|||||||
* The timer pointer is included to ensure the timer isn't destroyed until
|
* The timer pointer is included to ensure the timer isn't destroyed until
|
||||||
* after it has expired.
|
* after it has expired.
|
||||||
*
|
*
|
||||||
|
* TODO: candidate for protected status
|
||||||
|
*
|
||||||
* @param t Pointer to the timer in question
|
* @param t Pointer to the timer in question
|
||||||
*
|
|
||||||
* @param callback The function to call back
|
* @param callback The function to call back
|
||||||
*
|
|
||||||
* @param ec The status code
|
* @param ec The status code
|
||||||
*/
|
*/
|
||||||
void handle_timer(timer_ptr t, timer_handler callback, const
|
void handle_timer(timer_ptr t, timer_handler callback, const
|
||||||
@@ -332,6 +303,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
/// Get a pointer to this connection's strand
|
||||||
|
strand_ptr get_strand() {
|
||||||
|
return m_strand;
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize transport for reading
|
/// Initialize transport for reading
|
||||||
/**
|
/**
|
||||||
* init_asio is called once immediately after construction to initialize
|
* init_asio is called once immediately after construction to initialize
|
||||||
@@ -367,6 +343,47 @@ protected:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// initialize the proxy buffers and http parsers
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param authority The address of the server we want the proxy to tunnel to
|
||||||
|
* in the format of a URI authority (host:port)
|
||||||
|
*
|
||||||
|
* @return Status code indicating what errors occurred, if any
|
||||||
|
*/
|
||||||
|
lib::error_code proxy_init(std::string const & authority) {
|
||||||
|
if (!m_proxy_data) {
|
||||||
|
return websocketpp::error::make_error_code(
|
||||||
|
websocketpp::error::invalid_state);
|
||||||
|
}
|
||||||
|
m_proxy_data->req.set_version("HTTP/1.1");
|
||||||
|
m_proxy_data->req.set_method("CONNECT");
|
||||||
|
|
||||||
|
m_proxy_data->req.set_uri(authority);
|
||||||
|
m_proxy_data->req.replace_header("Host",authority);
|
||||||
|
|
||||||
|
return lib::error_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finish constructing the transport
|
||||||
|
/**
|
||||||
|
* init_asio is called once immediately after construction to initialize
|
||||||
|
* boost::asio components to the io_service
|
||||||
|
*
|
||||||
|
* @param io_service A pointer to the io_service to register with this
|
||||||
|
* connection
|
||||||
|
*
|
||||||
|
* @return Status code for the success or failure of the initialization
|
||||||
|
*/
|
||||||
|
lib::error_code init_asio (io_service_ptr io_service) {
|
||||||
|
// do we need to store or use the io_service at this level?
|
||||||
|
m_io_service = io_service;
|
||||||
|
|
||||||
|
m_strand.reset(new boost::asio::strand(*io_service));
|
||||||
|
|
||||||
|
return socket_con_type::init_asio(io_service, m_strand, m_is_server);
|
||||||
|
}
|
||||||
|
|
||||||
void handle_pre_init(init_handler callback, const lib::error_code& ec) {
|
void handle_pre_init(init_handler callback, const lib::error_code& ec) {
|
||||||
if (m_alog.static_test(log::alevel::devel)) {
|
if (m_alog.static_test(log::alevel::devel)) {
|
||||||
m_alog.write(log::alevel::devel,"asio connection handle pre_init");
|
m_alog.write(log::alevel::devel,"asio connection handle pre_init");
|
||||||
@@ -497,12 +514,12 @@ protected:
|
|||||||
boost::asio::async_write(
|
boost::asio::async_write(
|
||||||
socket_con_type::get_next_layer(),
|
socket_con_type::get_next_layer(),
|
||||||
m_bufs,
|
m_bufs,
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_proxy_write,
|
&type::handle_proxy_write,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,13 +585,13 @@ protected:
|
|||||||
socket_con_type::get_next_layer(),
|
socket_con_type::get_next_layer(),
|
||||||
m_proxy_data->read_buf,
|
m_proxy_data->read_buf,
|
||||||
"\r\n\r\n",
|
"\r\n\r\n",
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_proxy_read,
|
&type::handle_proxy_read,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1,
|
lib::placeholders::_1,
|
||||||
lib::placeholders::_2
|
lib::placeholders::_2
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,13 +697,13 @@ protected:
|
|||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
boost::asio::buffer(buf,len),
|
boost::asio::buffer(buf,len),
|
||||||
boost::asio::transfer_at_least(num_bytes),
|
boost::asio::transfer_at_least(num_bytes),
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_async_read,
|
&type::handle_async_read,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
handler,
|
handler,
|
||||||
lib::placeholders::_1,
|
lib::placeholders::_1,
|
||||||
lib::placeholders::_2
|
lib::placeholders::_2
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,12 +735,12 @@ protected:
|
|||||||
boost::asio::async_write(
|
boost::asio::async_write(
|
||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
m_bufs,
|
m_bufs,
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_async_write,
|
&type::handle_async_write,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
handler,
|
handler,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,12 +754,12 @@ protected:
|
|||||||
boost::asio::async_write(
|
boost::asio::async_write(
|
||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
m_bufs,
|
m_bufs,
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_async_write,
|
&type::handle_async_write,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
handler,
|
handler,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,16 +790,14 @@ protected:
|
|||||||
/// Trigger the on_interrupt handler
|
/// Trigger the on_interrupt handler
|
||||||
/**
|
/**
|
||||||
* This needs to be thread safe
|
* This needs to be thread safe
|
||||||
*
|
|
||||||
* Might need a strand at some point?
|
|
||||||
*/
|
*/
|
||||||
lib::error_code interrupt(interrupt_handler handler) {
|
lib::error_code interrupt(interrupt_handler handler) {
|
||||||
m_io_service->post(handler);
|
m_io_service->post(m_strand->wrap(handler));
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code dispatch(dispatch_handler handler) {
|
lib::error_code dispatch(dispatch_handler handler) {
|
||||||
m_io_service->post(handler);
|
m_io_service->post(m_strand->wrap(handler));
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,7 +920,9 @@ private:
|
|||||||
|
|
||||||
// transport resources
|
// transport resources
|
||||||
io_service_ptr m_io_service;
|
io_service_ptr m_io_service;
|
||||||
|
strand_ptr m_strand;
|
||||||
connection_hdl m_connection_hdl;
|
connection_hdl m_connection_hdl;
|
||||||
|
|
||||||
std::vector<boost::asio::const_buffer> m_bufs;
|
std::vector<boost::asio::const_buffer> m_bufs;
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
|
|||||||
@@ -574,13 +574,12 @@ public:
|
|||||||
|
|
||||||
m_acceptor->async_accept(
|
m_acceptor->async_accept(
|
||||||
tcon->get_raw_socket(),
|
tcon->get_raw_socket(),
|
||||||
lib::bind(
|
tcon->get_strand()->wrap(lib::bind(
|
||||||
&type::handle_accept,
|
&type::handle_accept,
|
||||||
this,
|
this,
|
||||||
tcon->get_handle(),
|
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,18 +611,19 @@ protected:
|
|||||||
m_elog = e;
|
m_elog = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_accept(connection_hdl hdl, accept_handler callback,
|
void handle_accept(accept_handler callback, boost::system::error_code const
|
||||||
const boost::system::error_code& error)
|
& boost_ec)
|
||||||
{
|
{
|
||||||
if (error) {
|
lib::error_code ret_ec;
|
||||||
//con->terminate();
|
|
||||||
// TODO: Better translation of errors at this point
|
m_alog->write(log::alevel::devel, "asio::handle_accept");
|
||||||
callback(hdl,make_error_code(error::pass_through));
|
|
||||||
return;
|
if (boost_ec) {
|
||||||
|
log_err(log::elevel::devel,"asio handle_accept",boost_ec);
|
||||||
|
ret_ec = make_error_code(error::pass_through);
|
||||||
}
|
}
|
||||||
|
|
||||||
//con->start();
|
callback(ret_ec);
|
||||||
callback(hdl,lib::error_code());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiate a new connection
|
/// Initiate a new connection
|
||||||
@@ -649,13 +649,13 @@ protected:
|
|||||||
uri_ptr pu(new uri(proxy));
|
uri_ptr pu(new uri(proxy));
|
||||||
|
|
||||||
if (!pu->get_valid()) {
|
if (!pu->get_valid()) {
|
||||||
cb(tcon->get_handle(),make_error_code(error::proxy_invalid));
|
cb(make_error_code(error::proxy_invalid));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ec = tcon->proxy_init(u->get_authority());
|
ec = tcon->proxy_init(u->get_authority());
|
||||||
if (ec) {
|
if (ec) {
|
||||||
cb(tcon->get_handle(),ec);
|
cb(ec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,12 +672,11 @@ protected:
|
|||||||
|
|
||||||
timer_ptr dns_timer;
|
timer_ptr dns_timer;
|
||||||
|
|
||||||
dns_timer = set_timer(
|
dns_timer = tcon->set_timer(
|
||||||
config::timeout_dns_resolve,
|
config::timeout_dns_resolve,
|
||||||
lib::bind(
|
lib::bind(
|
||||||
&type::handle_resolve_timeout,
|
&type::handle_resolve_timeout,
|
||||||
this,
|
this,
|
||||||
tcon,
|
|
||||||
dns_timer,
|
dns_timer,
|
||||||
cb,
|
cb,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
@@ -686,7 +685,7 @@ protected:
|
|||||||
|
|
||||||
m_resolver->async_resolve(
|
m_resolver->async_resolve(
|
||||||
query,
|
query,
|
||||||
lib::bind(
|
tcon->get_strand()->wrap(lib::bind(
|
||||||
&type::handle_resolve,
|
&type::handle_resolve,
|
||||||
this,
|
this,
|
||||||
tcon,
|
tcon,
|
||||||
@@ -694,12 +693,12 @@ protected:
|
|||||||
cb,
|
cb,
|
||||||
lib::placeholders::_1,
|
lib::placeholders::_1,
|
||||||
lib::placeholders::_2
|
lib::placeholders::_2
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_resolve_timeout(transport_con_ptr tcon, timer_ptr dns_timer,
|
void handle_resolve_timeout(timer_ptr dns_timer, connect_handler callback,
|
||||||
connect_handler callback, const lib::error_code & ec)
|
lib::error_code const & ec)
|
||||||
{
|
{
|
||||||
lib::error_code ret_ec;
|
lib::error_code ret_ec;
|
||||||
|
|
||||||
@@ -718,11 +717,11 @@ protected:
|
|||||||
|
|
||||||
m_alog->write(log::alevel::devel,"DNS resolution timed out");
|
m_alog->write(log::alevel::devel,"DNS resolution timed out");
|
||||||
m_resolver->cancel();
|
m_resolver->cancel();
|
||||||
callback(tcon->get_handle(),ret_ec);
|
callback(ret_ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer,
|
void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer,
|
||||||
connect_handler callback, const boost::system::error_code& ec,
|
connect_handler callback, boost::system::error_code const & ec,
|
||||||
boost::asio::ip::tcp::resolver::iterator iterator)
|
boost::asio::ip::tcp::resolver::iterator iterator)
|
||||||
{
|
{
|
||||||
if (ec == boost::asio::error::operation_aborted ||
|
if (ec == boost::asio::error::operation_aborted ||
|
||||||
@@ -736,7 +735,7 @@ protected:
|
|||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_resolve",ec);
|
log_err(log::elevel::info,"asio async_resolve",ec);
|
||||||
callback(tcon->get_handle(),make_error_code(error::pass_through));
|
callback(make_error_code(error::pass_through));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,10 +755,10 @@ protected:
|
|||||||
|
|
||||||
timer_ptr con_timer;
|
timer_ptr con_timer;
|
||||||
|
|
||||||
con_timer = set_timer(
|
con_timer = tcon->set_timer(
|
||||||
config::timeout_connect,
|
config::timeout_connect,
|
||||||
lib::bind(
|
lib::bind(
|
||||||
&type::handle_resolve_timeout,
|
&type::handle_connect_timeout,
|
||||||
this,
|
this,
|
||||||
tcon,
|
tcon,
|
||||||
con_timer,
|
con_timer,
|
||||||
@@ -771,19 +770,19 @@ protected:
|
|||||||
boost::asio::async_connect(
|
boost::asio::async_connect(
|
||||||
tcon->get_raw_socket(),
|
tcon->get_raw_socket(),
|
||||||
iterator,
|
iterator,
|
||||||
lib::bind(
|
tcon->get_strand()->wrap(lib::bind(
|
||||||
&type::handle_connect,
|
&type::handle_connect,
|
||||||
this,
|
this,
|
||||||
tcon,
|
tcon,
|
||||||
con_timer,
|
con_timer,
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_connect_timeout(transport_con_ptr tcon, timer_ptr con_timer,
|
void handle_connect_timeout(transport_con_ptr tcon, timer_ptr con_timer,
|
||||||
connect_handler callback, const lib::error_code & ec)
|
connect_handler callback, lib::error_code const & ec)
|
||||||
{
|
{
|
||||||
lib::error_code ret_ec;
|
lib::error_code ret_ec;
|
||||||
|
|
||||||
@@ -802,11 +801,11 @@ protected:
|
|||||||
|
|
||||||
m_alog->write(log::alevel::devel,"TCP connect timed out");
|
m_alog->write(log::alevel::devel,"TCP connect timed out");
|
||||||
tcon->cancel_socket();
|
tcon->cancel_socket();
|
||||||
callback(tcon->get_handle(),ret_ec);
|
callback(ret_ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_connect(transport_con_ptr tcon, timer_ptr con_timer,
|
void handle_connect(transport_con_ptr tcon, timer_ptr con_timer,
|
||||||
connect_handler callback, const boost::system::error_code& ec)
|
connect_handler callback, boost::system::error_code const & ec)
|
||||||
{
|
{
|
||||||
if (ec == boost::asio::error::operation_aborted ||
|
if (ec == boost::asio::error::operation_aborted ||
|
||||||
con_timer->expires_from_now().is_negative())
|
con_timer->expires_from_now().is_negative())
|
||||||
@@ -819,7 +818,7 @@ protected:
|
|||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_connect",ec);
|
log_err(log::elevel::info,"asio async_connect",ec);
|
||||||
callback(tcon->get_handle(),make_error_code(error::pass_through));
|
callback(make_error_code(error::pass_through));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,7 +827,7 @@ protected:
|
|||||||
"Async connect to "+tcon->get_remote_endpoint()+" successful.");
|
"Async connect to "+tcon->get_remote_endpoint()+" successful.");
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(tcon->get_handle(),lib::error_code());
|
callback(lib::error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_listening() const {
|
bool is_listening() const {
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ public:
|
|||||||
|
|
||||||
/// Type of a pointer to the ASIO io_service being used
|
/// Type of a pointer to the ASIO io_service being used
|
||||||
typedef boost::asio::io_service* io_service_ptr;
|
typedef boost::asio::io_service* io_service_ptr;
|
||||||
|
/// Type of a pointer to the ASIO io_service strand being used
|
||||||
|
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
||||||
/// Type of a shared pointer to the socket being used.
|
/// Type of a shared pointer to the socket being used.
|
||||||
typedef lib::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
|
typedef lib::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
|
||||||
|
|
||||||
@@ -152,7 +154,9 @@ protected:
|
|||||||
* @param strand A shared pointer to the connection's asio strand
|
* @param strand A shared pointer to the connection's asio strand
|
||||||
* @param is_server Whether or not the endpoint is a server or not.
|
* @param is_server Whether or not the endpoint is a server or not.
|
||||||
*/
|
*/
|
||||||
lib::error_code init_asio (io_service_ptr service, bool is_server) {
|
lib::error_code init_asio (io_service_ptr service, strand_ptr strand,
|
||||||
|
bool is_server)
|
||||||
|
{
|
||||||
if (m_state != UNINITIALIZED) {
|
if (m_state != UNINITIALIZED) {
|
||||||
return socket::make_error_code(socket::error::invalid_state);
|
return socket::make_error_code(socket::error::invalid_state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ public:
|
|||||||
typedef lib::shared_ptr<socket_type> socket_ptr;
|
typedef lib::shared_ptr<socket_type> socket_ptr;
|
||||||
/// Type of a pointer to the ASIO io_service being used
|
/// Type of a pointer to the ASIO io_service being used
|
||||||
typedef boost::asio::io_service* io_service_ptr;
|
typedef boost::asio::io_service* io_service_ptr;
|
||||||
|
/// Type of a pointer to the ASIO io_service strand being used
|
||||||
|
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
||||||
/// Type of a shared pointer to the ASIO TLS context being used
|
/// Type of a shared pointer to the ASIO TLS context being used
|
||||||
typedef lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
typedef lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||||
|
|
||||||
@@ -174,9 +176,12 @@ protected:
|
|||||||
* boost::asio components to the io_service
|
* boost::asio components to the io_service
|
||||||
*
|
*
|
||||||
* @param service A pointer to the endpoint's io_service
|
* @param service A pointer to the endpoint's io_service
|
||||||
|
* @param strand A pointer to the connection's strand
|
||||||
* @param is_server Whether or not the endpoint is a server or not.
|
* @param is_server Whether or not the endpoint is a server or not.
|
||||||
*/
|
*/
|
||||||
lib::error_code init_asio (io_service_ptr service, bool is_server) {
|
lib::error_code init_asio (io_service_ptr service, strand_ptr strand,
|
||||||
|
bool is_server)
|
||||||
|
{
|
||||||
if (!m_tls_init_handler) {
|
if (!m_tls_init_handler) {
|
||||||
return socket::make_error_code(socket::error::missing_tls_init_handler);
|
return socket::make_error_code(socket::error::missing_tls_init_handler);
|
||||||
}
|
}
|
||||||
@@ -188,6 +193,7 @@ protected:
|
|||||||
m_socket.reset(new socket_type(*service,*m_context));
|
m_socket.reset(new socket_type(*service,*m_context));
|
||||||
|
|
||||||
m_io_service = service;
|
m_io_service = service;
|
||||||
|
m_strand = strand;
|
||||||
m_is_server = is_server;
|
m_is_server = is_server;
|
||||||
|
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
@@ -224,12 +230,12 @@ protected:
|
|||||||
// TLS handshake
|
// TLS handshake
|
||||||
m_socket->async_handshake(
|
m_socket->async_handshake(
|
||||||
get_handshake_type(),
|
get_handshake_type(),
|
||||||
lib::bind(
|
m_strand->wrap(lib::bind(
|
||||||
&type::handle_init,
|
&type::handle_init,
|
||||||
get_shared(),
|
get_shared(),
|
||||||
callback,
|
callback,
|
||||||
lib::placeholders::_1
|
lib::placeholders::_1
|
||||||
)
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,6 +284,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
io_service_ptr m_io_service;
|
io_service_ptr m_io_service;
|
||||||
|
strand_ptr m_strand;
|
||||||
context_ptr m_context;
|
context_ptr m_context;
|
||||||
socket_ptr m_socket;
|
socket_ptr m_socket;
|
||||||
bool m_is_server;
|
bool m_is_server;
|
||||||
|
|||||||
@@ -71,12 +71,10 @@ namespace websocketpp {
|
|||||||
namespace transport {
|
namespace transport {
|
||||||
|
|
||||||
/// The type and signature of the callback passed to the accept method
|
/// The type and signature of the callback passed to the accept method
|
||||||
typedef lib::function<void(connection_hdl, lib::error_code const &)>
|
typedef lib::function<void(lib::error_code const &)> accept_handler;
|
||||||
accept_handler;
|
|
||||||
|
|
||||||
/// The type and signature of the callback passed to the connect method
|
/// The type and signature of the callback passed to the connect method
|
||||||
typedef lib::function<void(connection_hdl, lib::error_code const &)>
|
typedef lib::function<void(lib::error_code const &)> connect_handler;
|
||||||
connect_handler;
|
|
||||||
|
|
||||||
} // namespace transport
|
} // namespace transport
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ protected:
|
|||||||
* @param cb The function to call back with the results when complete.
|
* @param cb The function to call back with the results when complete.
|
||||||
*/
|
*/
|
||||||
void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) {
|
void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) {
|
||||||
cb(tcon->get_handle(),lib::error_code());
|
cb(lib::error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize a connection
|
/// Initialize a connection
|
||||||
|
|||||||
+4
-1
@@ -138,7 +138,10 @@ public:
|
|||||||
std::string port = "";
|
std::string port = "";
|
||||||
while (state == 1) {
|
while (state == 1) {
|
||||||
if (it == uri.end()) {
|
if (it == uri.end()) {
|
||||||
state = 3;
|
// state is not used after this point presently.
|
||||||
|
// this should be re-enabled if it ever is needed in a future
|
||||||
|
// refactoring
|
||||||
|
//state = 3;
|
||||||
break;
|
break;
|
||||||
} else if (*it == '/') {
|
} else if (*it == '/') {
|
||||||
state = 3;
|
state = 3;
|
||||||
|
|||||||
+27
-2
@@ -1,5 +1,30 @@
|
|||||||
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
/*
|
||||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
* The following code 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.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef UTF8_VALIDATOR_HPP
|
#ifndef UTF8_VALIDATOR_HPP
|
||||||
#define UTF8_VALIDATOR_HPP
|
#define UTF8_VALIDATOR_HPP
|
||||||
|
|||||||
+2
-2
@@ -50,10 +50,10 @@ static int const patch_version = 0;
|
|||||||
* This is a textual flag indicating the type and number for pre-release
|
* This is a textual flag indicating the type and number for pre-release
|
||||||
* versions (dev, alpha, beta, rc). This will be blank for release versions.
|
* versions (dev, alpha, beta, rc). This will be blank for release versions.
|
||||||
*/
|
*/
|
||||||
static char const prerelease_flag[] = "alpha3";
|
static char const prerelease_flag[] = "alpha4";
|
||||||
|
|
||||||
/// Default user agent string
|
/// Default user agent string
|
||||||
static char const user_agent[] = "WebSocket++/0.3.0-alpha3";
|
static char const user_agent[] = "WebSocket++/0.3.0-alpha4";
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user