diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd93658 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/websocket_1.1.0.tar.gz diff --git a/0001-Unbundle-websocketpp.patch b/0001-Unbundle-websocketpp.patch new file mode 100644 index 0000000..a7a91cc --- /dev/null +++ b/0001-Unbundle-websocketpp.patch @@ -0,0 +1,25811 @@ +From 5bf16623c629385a73275d25cdf6a99ac8f7bf9a Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Wed, 11 Sep 2019 17:30:44 -0400 +Subject: [PATCH 1/2] Unbundle websocketpp. + +Signed-off-by: Elliott Sales de Andrade +--- + configure | 25 +- + src/Makevars.in | 2 +- + src/client.hpp | 2 + + src/lib/update.sh | 23 - + src/lib/websocketpp/base64/base64.hpp | 178 -- + src/lib/websocketpp/client.hpp | 33 - + src/lib/websocketpp/close.hpp | 353 --- + src/lib/websocketpp/common/asio.hpp | 141 - + src/lib/websocketpp/common/asio_ssl.hpp | 39 - + src/lib/websocketpp/common/chrono.hpp | 68 - + src/lib/websocketpp/common/connection_hdl.hpp | 52 - + src/lib/websocketpp/common/cpp11.hpp | 162 -- + src/lib/websocketpp/common/functional.hpp | 105 - + src/lib/websocketpp/common/md5.hpp | 448 ---- + src/lib/websocketpp/common/memory.hpp | 88 - + src/lib/websocketpp/common/network.hpp | 106 - + src/lib/websocketpp/common/platforms.hpp | 46 - + src/lib/websocketpp/common/random.hpp | 82 - + src/lib/websocketpp/common/regex.hpp | 59 - + src/lib/websocketpp/common/stdint.hpp | 73 - + src/lib/websocketpp/common/system_error.hpp | 84 - + src/lib/websocketpp/common/thread.hpp | 88 - + src/lib/websocketpp/common/time.hpp | 56 - + src/lib/websocketpp/common/type_traits.hpp | 65 - + src/lib/websocketpp/concurrency/basic.hpp | 46 - + src/lib/websocketpp/concurrency/none.hpp | 80 - + src/lib/websocketpp/config/asio.hpp | 77 - + src/lib/websocketpp/config/asio_client.hpp | 77 - + src/lib/websocketpp/config/asio_no_tls.hpp | 73 - + .../websocketpp/config/asio_no_tls_client.hpp | 73 - + src/lib/websocketpp/config/boost_config.hpp | 72 - + src/lib/websocketpp/config/core.hpp | 297 --- + src/lib/websocketpp/config/core_client.hpp | 294 -- + src/lib/websocketpp/config/debug.hpp | 286 -- + src/lib/websocketpp/config/debug_asio.hpp | 77 - + .../websocketpp/config/debug_asio_no_tls.hpp | 73 - + src/lib/websocketpp/config/minimal_client.hpp | 72 - + src/lib/websocketpp/config/minimal_server.hpp | 312 --- + src/lib/websocketpp/connection.hpp | 1642 ------------ + src/lib/websocketpp/connection_base.hpp | 38 - + src/lib/websocketpp/endpoint.hpp | 700 ----- + src/lib/websocketpp/endpoint_base.hpp | 38 - + src/lib/websocketpp/error.hpp | 277 -- + src/lib/websocketpp/extensions/extension.hpp | 102 - + .../permessage_deflate/disabled.hpp | 129 - + .../extensions/permessage_deflate/enabled.hpp | 817 ------ + src/lib/websocketpp/frame.hpp | 864 ------ + src/lib/websocketpp/http/constants.hpp | 308 --- + src/lib/websocketpp/http/impl/parser.hpp | 200 -- + src/lib/websocketpp/http/impl/request.hpp | 191 -- + src/lib/websocketpp/http/impl/response.hpp | 266 -- + src/lib/websocketpp/http/parser.hpp | 629 ----- + src/lib/websocketpp/http/request.hpp | 124 - + src/lib/websocketpp/http/response.hpp | 188 -- + src/lib/websocketpp/impl/connection_impl.hpp | 2375 ----------------- + src/lib/websocketpp/impl/endpoint_impl.hpp | 269 -- + src/lib/websocketpp/impl/utilities_impl.hpp | 87 - + src/lib/websocketpp/logger/basic.hpp | 199 -- + src/lib/websocketpp/logger/levels.hpp | 203 -- + src/lib/websocketpp/logger/stub.hpp | 119 - + src/lib/websocketpp/logger/syslog.hpp | 146 - + src/lib/websocketpp/message_buffer/alloc.hpp | 105 - + .../websocketpp/message_buffer/message.hpp | 340 --- + src/lib/websocketpp/message_buffer/pool.hpp | 229 -- + src/lib/websocketpp/processors/base.hpp | 299 --- + src/lib/websocketpp/processors/hybi00.hpp | 462 ---- + src/lib/websocketpp/processors/hybi07.hpp | 78 - + src/lib/websocketpp/processors/hybi08.hpp | 83 - + src/lib/websocketpp/processors/hybi13.hpp | 1078 -------- + src/lib/websocketpp/processors/processor.hpp | 407 --- + src/lib/websocketpp/random/none.hpp | 60 - + src/lib/websocketpp/random/random_device.hpp | 80 - + src/lib/websocketpp/roles/client_endpoint.hpp | 173 -- + src/lib/websocketpp/roles/server_endpoint.hpp | 195 -- + src/lib/websocketpp/server.hpp | 33 - + src/lib/websocketpp/sha1/sha1.hpp | 189 -- + src/lib/websocketpp/transport/asio/base.hpp | 232 -- + .../websocketpp/transport/asio/connection.hpp | 1197 --------- + .../websocketpp/transport/asio/endpoint.hpp | 1249 --------- + .../transport/asio/security/base.hpp | 159 -- + .../transport/asio/security/none.hpp | 373 --- + .../transport/asio/security/tls.hpp | 475 ---- + .../websocketpp/transport/base/connection.hpp | 238 -- + .../websocketpp/transport/base/endpoint.hpp | 77 - + src/lib/websocketpp/transport/debug/base.hpp | 104 - + .../transport/debug/connection.hpp | 412 --- + .../websocketpp/transport/debug/endpoint.hpp | 140 - + .../websocketpp/transport/iostream/base.hpp | 133 - + .../transport/iostream/connection.hpp | 714 ----- + .../transport/iostream/endpoint.hpp | 222 -- + src/lib/websocketpp/transport/stub/base.hpp | 95 - + .../websocketpp/transport/stub/connection.hpp | 286 -- + .../websocketpp/transport/stub/endpoint.hpp | 140 - + src/lib/websocketpp/uri.hpp | 356 --- + src/lib/websocketpp/utf8_validator.hpp | 154 -- + src/lib/websocketpp/utilities.hpp | 180 -- + src/lib/websocketpp/version.hpp | 61 - + 97 files changed, 27 insertions(+), 24979 deletions(-) + delete mode 100755 src/lib/update.sh + delete mode 100644 src/lib/websocketpp/base64/base64.hpp + delete mode 100644 src/lib/websocketpp/client.hpp + delete mode 100644 src/lib/websocketpp/close.hpp + delete mode 100644 src/lib/websocketpp/common/asio.hpp + delete mode 100644 src/lib/websocketpp/common/asio_ssl.hpp + delete mode 100644 src/lib/websocketpp/common/chrono.hpp + delete mode 100644 src/lib/websocketpp/common/connection_hdl.hpp + delete mode 100644 src/lib/websocketpp/common/cpp11.hpp + delete mode 100644 src/lib/websocketpp/common/functional.hpp + delete mode 100644 src/lib/websocketpp/common/md5.hpp + delete mode 100644 src/lib/websocketpp/common/memory.hpp + delete mode 100644 src/lib/websocketpp/common/network.hpp + delete mode 100644 src/lib/websocketpp/common/platforms.hpp + delete mode 100644 src/lib/websocketpp/common/random.hpp + delete mode 100644 src/lib/websocketpp/common/regex.hpp + delete mode 100644 src/lib/websocketpp/common/stdint.hpp + delete mode 100644 src/lib/websocketpp/common/system_error.hpp + delete mode 100644 src/lib/websocketpp/common/thread.hpp + delete mode 100644 src/lib/websocketpp/common/time.hpp + delete mode 100644 src/lib/websocketpp/common/type_traits.hpp + delete mode 100644 src/lib/websocketpp/concurrency/basic.hpp + delete mode 100644 src/lib/websocketpp/concurrency/none.hpp + delete mode 100644 src/lib/websocketpp/config/asio.hpp + delete mode 100644 src/lib/websocketpp/config/asio_client.hpp + delete mode 100644 src/lib/websocketpp/config/asio_no_tls.hpp + delete mode 100644 src/lib/websocketpp/config/asio_no_tls_client.hpp + delete mode 100644 src/lib/websocketpp/config/boost_config.hpp + delete mode 100644 src/lib/websocketpp/config/core.hpp + delete mode 100644 src/lib/websocketpp/config/core_client.hpp + delete mode 100644 src/lib/websocketpp/config/debug.hpp + delete mode 100644 src/lib/websocketpp/config/debug_asio.hpp + delete mode 100644 src/lib/websocketpp/config/debug_asio_no_tls.hpp + delete mode 100644 src/lib/websocketpp/config/minimal_client.hpp + delete mode 100644 src/lib/websocketpp/config/minimal_server.hpp + delete mode 100644 src/lib/websocketpp/connection.hpp + delete mode 100644 src/lib/websocketpp/connection_base.hpp + delete mode 100644 src/lib/websocketpp/endpoint.hpp + delete mode 100644 src/lib/websocketpp/endpoint_base.hpp + delete mode 100644 src/lib/websocketpp/error.hpp + delete mode 100644 src/lib/websocketpp/extensions/extension.hpp + delete mode 100644 src/lib/websocketpp/extensions/permessage_deflate/disabled.hpp + delete mode 100644 src/lib/websocketpp/extensions/permessage_deflate/enabled.hpp + delete mode 100644 src/lib/websocketpp/frame.hpp + delete mode 100644 src/lib/websocketpp/http/constants.hpp + delete mode 100644 src/lib/websocketpp/http/impl/parser.hpp + delete mode 100644 src/lib/websocketpp/http/impl/request.hpp + delete mode 100644 src/lib/websocketpp/http/impl/response.hpp + delete mode 100644 src/lib/websocketpp/http/parser.hpp + delete mode 100644 src/lib/websocketpp/http/request.hpp + delete mode 100644 src/lib/websocketpp/http/response.hpp + delete mode 100644 src/lib/websocketpp/impl/connection_impl.hpp + delete mode 100644 src/lib/websocketpp/impl/endpoint_impl.hpp + delete mode 100644 src/lib/websocketpp/impl/utilities_impl.hpp + delete mode 100644 src/lib/websocketpp/logger/basic.hpp + delete mode 100644 src/lib/websocketpp/logger/levels.hpp + delete mode 100644 src/lib/websocketpp/logger/stub.hpp + delete mode 100644 src/lib/websocketpp/logger/syslog.hpp + delete mode 100644 src/lib/websocketpp/message_buffer/alloc.hpp + delete mode 100644 src/lib/websocketpp/message_buffer/message.hpp + delete mode 100644 src/lib/websocketpp/message_buffer/pool.hpp + delete mode 100644 src/lib/websocketpp/processors/base.hpp + delete mode 100644 src/lib/websocketpp/processors/hybi00.hpp + delete mode 100644 src/lib/websocketpp/processors/hybi07.hpp + delete mode 100644 src/lib/websocketpp/processors/hybi08.hpp + delete mode 100644 src/lib/websocketpp/processors/hybi13.hpp + delete mode 100644 src/lib/websocketpp/processors/processor.hpp + delete mode 100644 src/lib/websocketpp/random/none.hpp + delete mode 100644 src/lib/websocketpp/random/random_device.hpp + delete mode 100644 src/lib/websocketpp/roles/client_endpoint.hpp + delete mode 100644 src/lib/websocketpp/roles/server_endpoint.hpp + delete mode 100644 src/lib/websocketpp/server.hpp + delete mode 100644 src/lib/websocketpp/sha1/sha1.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/base.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/connection.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/endpoint.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/security/base.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/security/none.hpp + delete mode 100644 src/lib/websocketpp/transport/asio/security/tls.hpp + delete mode 100644 src/lib/websocketpp/transport/base/connection.hpp + delete mode 100644 src/lib/websocketpp/transport/base/endpoint.hpp + delete mode 100644 src/lib/websocketpp/transport/debug/base.hpp + delete mode 100644 src/lib/websocketpp/transport/debug/connection.hpp + delete mode 100644 src/lib/websocketpp/transport/debug/endpoint.hpp + delete mode 100644 src/lib/websocketpp/transport/iostream/base.hpp + delete mode 100644 src/lib/websocketpp/transport/iostream/connection.hpp + delete mode 100644 src/lib/websocketpp/transport/iostream/endpoint.hpp + delete mode 100644 src/lib/websocketpp/transport/stub/base.hpp + delete mode 100644 src/lib/websocketpp/transport/stub/connection.hpp + delete mode 100644 src/lib/websocketpp/transport/stub/endpoint.hpp + delete mode 100644 src/lib/websocketpp/uri.hpp + delete mode 100644 src/lib/websocketpp/utf8_validator.hpp + delete mode 100644 src/lib/websocketpp/utilities.hpp + delete mode 100644 src/lib/websocketpp/version.hpp + +diff --git a/configure b/configure +index 07de3d0..e889fae 100755 +--- a/configure ++++ b/configure +@@ -27,7 +27,7 @@ if [ "$INCLUDE_DIR" ] || [ "$LIB_DIR" ]; then + PKG_CFLAGS="-I$INCLUDE_DIR $PKG_CFLAGS" + PKG_LIBS="-L$LIB_DIR $PKG_LIBS" + elif [ "$PKGCONFIG_CFLAGS" ] || [ "$PKGCONFIG_LIBS" ]; then +- echo "Found pkg-config cflags and libs!" ++ echo "Found pkg-config cflags and libs for $PKG_CONFIG_NAME!" + PKG_CFLAGS=${PKGCONFIG_CFLAGS} + PKG_LIBS=${PKGCONFIG_LIBS} + else +@@ -96,6 +96,29 @@ fi #AUTOBREW + + echo "Using PKG_LIBS=$PKG_LIBS" + ++# Library settings ++PKG_CONFIG_NAME="websocketpp" ++PKG_RPM_NAME="websocketpp-devel" ++ ++# Use pkg-config if available ++pkg-config ${PKG_CONFIG_NAME} --atleast-version=0.8.1 2>/dev/null ++if [ $? -eq 0 ]; then ++ echo "Found pkg-config cflags and libs for $PKG_CONFIG_NAME!" ++ PKG_CFLAGS="`pkg-config --cflags ${PKG_CONFIG_NAME}` $PKG_CFLAGS" ++ PKG_LIBS="`pkg-config --libs ${PKG_CONFIG_NAME}` $PKG_LIBS" ++else ++# Customize the error ++ echo "------------------------- ANTICONF ERROR ---------------------------" ++ echo "Configuration failed because $PKG_CONFIG_NAME was not found. Try installing:" ++ echo " * rpm: $PKG_RPM_NAME (Fedora, CentOS, RHEL)" ++ echo "--------------------------------------------------------------------" ++ exit 1; ++fi ++ ++# For debugging ++echo "Using PKG_CFLAGS=$PKG_CFLAGS" ++echo "Using PKG_LIBS=$PKG_LIBS" ++ + # Write to Makevars + sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars + +diff --git a/src/Makevars.in b/src/Makevars.in +index cf3f82f..619b196 100644 +--- a/src/Makevars.in ++++ b/src/Makevars.in +@@ -1,5 +1,5 @@ + # Use C++11 if available + CXX_STD=CXX11 + +-PKG_CPPFLAGS = -I./lib @cflags@ ++PKG_CPPFLAGS = @cflags@ + PKG_LIBS += @libs@ +diff --git a/src/client.hpp b/src/client.hpp +index 385b3fe..f5c4f4e 100644 +--- a/src/client.hpp ++++ b/src/client.hpp +@@ -1,6 +1,8 @@ + #ifndef CLIENT_HPP + #define CLIENT_HPP + ++#define ws_websocketpp websocketpp ++ + #include + #include + #include +diff --git a/src/lib/update.sh b/src/lib/update.sh +deleted file mode 100755 +index 672d18e..0000000 +--- a/src/lib/update.sh ++++ /dev/null +@@ -1,23 +0,0 @@ +-#!/bin/bash +- +-COMMIT=0.8.1 +- +-set -e +- +-rm -rf websocketpp websocketpp_repo +-git clone https://github.com/zaphoyd/websocketpp websocketpp_repo +-(cd websocketpp_repo && git checkout "$COMMIT") +-rm websocketpp_repo/websocketpp/CMakeLists.txt +-export LC_CTYPE=C +-export LANG=C +-cd websocketpp_repo/websocketpp +-find . -path ./.git -prune -o -type f -print0 | xargs -0 sed -i "" -e 's/websocketpp::/ws_websocketpp::/g' +-find . -path ./.git -prune -o -type f -print0 | xargs -0 sed -i "" -e 's/namespace websocketpp/namespace ws_websocketpp/g' +-find . -path ./.git -prune -o -type f -print0 | xargs -0 sed -i "" -e 's/&std::cout/(std::ostream*)\&Rcpp::Rcout/g' +-find . -path ./.git -prune -o -type f -print0 | xargs -0 sed -i "" -e 's/&std::cerr/(std::ostream*)\&Rcpp::Rcerr/g' +-cd ../.. +-mv websocketpp_repo/websocketpp . +-rm -rf websocketpp_repo +- +-echo "IMPORTANT NOTE: Apply this patch manually:" >&2 +-echo "https://github.com/rstudio/websocket/commit/063ca452c7639b952dfd4981602436d43305457a" >&2 +diff --git a/src/lib/websocketpp/base64/base64.hpp b/src/lib/websocketpp/base64/base64.hpp +deleted file mode 100644 +index 0fe7e6f..0000000 +--- a/src/lib/websocketpp/base64/base64.hpp ++++ /dev/null +@@ -1,178 +0,0 @@ +-/* +- ****** +- 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 +- +-*/ +- +-#ifndef _BASE64_HPP_ +-#define _BASE64_HPP_ +- +-#include +- +-namespace ws_websocketpp { +- +-static std::string const base64_chars = +- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +- "abcdefghijklmnopqrstuvwxyz" +- "0123456789+/"; +- +-/// Test whether a character is a valid base64 character +-/** +- * @param c The character to test +- * @return true if c is a valid base64 character +- */ +-static inline bool is_base64(unsigned char c) { +- return (c == 43 || // + +- (c >= 47 && c <= 57) || // /-9 +- (c >= 65 && c <= 90) || // A-Z +- (c >= 97 && c <= 122)); // a-z +-} +- +-/// Encode a char buffer into a base64 string +-/** +- * @param input The input data +- * @param len The length of input in bytes +- * @return A base64 encoded string representing input +- */ +-inline std::string base64_encode(unsigned char const * input, size_t len) { +- std::string ret; +- int i = 0; +- int j = 0; +- unsigned char char_array_3[3]; +- unsigned char char_array_4[4]; +- +- while (len--) { +- char_array_3[i++] = *(input++); +- if (i == 3) { +- char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; +- char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + +- ((char_array_3[1] & 0xf0) >> 4); +- char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + +- ((char_array_3[2] & 0xc0) >> 6); +- char_array_4[3] = char_array_3[2] & 0x3f; +- +- for(i = 0; (i <4) ; i++) { +- ret += base64_chars[char_array_4[i]]; +- } +- i = 0; +- } +- } +- +- if (i) { +- for(j = i; j < 3; j++) { +- char_array_3[j] = '\0'; +- } +- +- char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; +- char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + +- ((char_array_3[1] & 0xf0) >> 4); +- char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + +- ((char_array_3[2] & 0xc0) >> 6); +- char_array_4[3] = char_array_3[2] & 0x3f; +- +- for (j = 0; (j < i + 1); j++) { +- ret += base64_chars[char_array_4[j]]; +- } +- +- while((i++ < 3)) { +- ret += '='; +- } +- } +- +- return ret; +-} +- +-/// Encode a string into a base64 string +-/** +- * @param input The input data +- * @return A base64 encoded string representing input +- */ +-inline std::string base64_encode(std::string const & input) { +- return base64_encode( +- reinterpret_cast(input.data()), +- input.size() +- ); +-} +- +-/// Decode a base64 encoded string into a string of raw bytes +-/** +- * @param input The base64 encoded input data +- * @return A string representing the decoded raw bytes +- */ +-inline std::string base64_decode(std::string const & input) { +- size_t in_len = input.size(); +- int i = 0; +- int j = 0; +- int in_ = 0; +- unsigned char char_array_4[4], char_array_3[3]; +- std::string ret; +- +- while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) { +- char_array_4[i++] = input[in_]; in_++; +- if (i ==4) { +- for (i = 0; i <4; i++) { +- char_array_4[i] = static_cast(base64_chars.find(char_array_4[i])); +- } +- +- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); +- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); +- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; +- +- for (i = 0; (i < 3); i++) { +- ret += char_array_3[i]; +- } +- i = 0; +- } +- } +- +- if (i) { +- for (j = i; j <4; j++) +- char_array_4[j] = 0; +- +- for (j = 0; j <4; j++) +- char_array_4[j] = static_cast(base64_chars.find(char_array_4[j])); +- +- char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); +- char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); +- char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; +- +- for (j = 0; (j < i - 1); j++) { +- ret += static_cast(char_array_3[j]); +- } +- } +- +- return ret; +-} +- +-} // namespace ws_websocketpp +- +-#endif // _BASE64_HPP_ +diff --git a/src/lib/websocketpp/client.hpp b/src/lib/websocketpp/client.hpp +deleted file mode 100644 +index 8782d7e..0000000 +--- a/src/lib/websocketpp/client.hpp ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CLIENT_HPP +-#define WEBSOCKETPP_CLIENT_HPP +- +-#include +- +-#endif //WEBSOCKETPP_CLIENT_HPP +diff --git a/src/lib/websocketpp/close.hpp b/src/lib/websocketpp/close.hpp +deleted file mode 100644 +index 2ef7d6a..0000000 +--- a/src/lib/websocketpp/close.hpp ++++ /dev/null +@@ -1,353 +0,0 @@ +- +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CLOSE_HPP +-#define WEBSOCKETPP_CLOSE_HPP +- +-/** \file +- * A package of types and methods for manipulating WebSocket close codes. +- */ +- +-#include +-#include +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-/// A package of types and methods for manipulating WebSocket close codes. +-namespace close { +-/// A package of types and methods for manipulating WebSocket close status' +-namespace status { +- /// The type of a close code value. +- typedef uint16_t value; +- +- /// A blank value for internal use. +- static value const blank = 0; +- +- /// Close the connection without a WebSocket close handshake. +- /** +- * This special value requests that the WebSocket connection be closed +- * without performing the WebSocket closing handshake. This does not comply +- * with RFC6455, but should be safe to do if necessary. This could be useful +- * for clients that need to disconnect quickly and cannot afford the +- * complete handshake. +- */ +- static value const omit_handshake = 1; +- +- /// Close the connection with a forced TCP drop. +- /** +- * This special value requests that the WebSocket connection be closed by +- * forcibly dropping the TCP connection. This will leave the other side of +- * the connection with a broken connection and some expensive timeouts. this +- * should not be done except in extreme cases or in cases of malicious +- * remote endpoints. +- */ +- static value const force_tcp_drop = 2; +- +- /// Normal closure, meaning that the purpose for which the connection was +- /// established has been fulfilled. +- static value const normal = 1000; +- +- /// The endpoint was "going away", such as a server going down or a browser +- /// navigating away from a page. +- static value const going_away = 1001; +- +- /// A protocol error occurred. +- static value const protocol_error = 1002; +- +- /// The connection was terminated because an endpoint received a type of +- /// data it cannot accept. +- /** +- * (e.g., an endpoint that understands only text data MAY send this if it +- * receives a binary message). +- */ +- static value const unsupported_data = 1003; +- +- /// A dummy value to indicate that no status code was received. +- /** +- * This value is illegal on the wire. +- */ +- static value const no_status = 1005; +- +- /// A dummy value to indicate that the connection was closed abnormally. +- /** +- * In such a case there was no close frame to extract a value from. This +- * value is illegal on the wire. +- */ +- static value const abnormal_close = 1006; +- +- /// An endpoint received message data inconsistent with its type. +- /** +- * For example: Invalid UTF8 bytes in a text message. +- */ +- static value const invalid_payload = 1007; +- +- /// An endpoint received a message that violated its policy. +- /** +- * This is a generic status code that can be returned when there is no other +- * more suitable status code (e.g., 1003 or 1009) or if there is a need to +- * hide specific details about the policy. +- */ +- static value const policy_violation = 1008; +- +- /// An endpoint received a message too large to process. +- static value const message_too_big = 1009; +- +- /// A client expected the server to accept a required extension request +- /** +- * The list of extensions that are needed SHOULD appear in the /reason/ part +- * of the Close frame. Note that this status code is not used by the server, +- * because it can fail the WebSocket handshake instead. +- */ +- static value const extension_required = 1010; +- +- /// An endpoint encountered an unexpected condition that prevented it from +- /// fulfilling the request. +- static value const internal_endpoint_error = 1011; +- +- /// Indicates that the service is restarted. A client may reconnect and if +- /// if it chooses to do so, should reconnect using a randomized delay of +- /// 5-30s +- static value const service_restart = 1012; +- +- /// Indicates that the service is experiencing overload. A client should +- /// only connect to a different IP (when there are multiple for the target) +- /// 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 +- * that the connection was closed due to a failure to perform a TLS +- * handshake (e.g., the server certificate can't be verified). This value is +- * illegal on the wire. +- */ +- static value const tls_handshake = 1015; +- +- /// A generic subprotocol error +- /** +- * Indicates that a subprotocol error occurred. Typically this involves +- * receiving a message that is not formatted as a valid message for the +- * subprotocol in use. +- */ +- static value const subprotocol_error = 3000; +- +- /// A invalid subprotocol data +- /** +- * Indicates that data was received that violated the specification of the +- * subprotocol in use. +- */ +- static value const invalid_subprotocol_data = 3001; +- +- /// First value in range reserved for future protocol use +- static value const rsv_start = 1016; +- /// Last value in range reserved for future protocol use +- static value const rsv_end = 2999; +- +- /// Test whether a close code is in a reserved range +- /** +- * @param [in] code The code to test +- * @return Whether or not code is reserved +- */ +- inline bool reserved(value code) { +- return ((code >= rsv_start && code <= rsv_end) || +- code == 1004); +- } +- +- /// First value in range that is always invalid on the wire +- static value const invalid_low = 999; +- /// Last value in range that is always invalid on the wire +- static value const invalid_high = 5000; +- +- /// Test whether a close code is invalid on the wire +- /** +- * @param [in] code The code to test +- * @return Whether or not code is invalid on the wire +- */ +- inline bool invalid(value code) { +- return (code <= invalid_low || code >= invalid_high || +- code == no_status || code == abnormal_close || +- code == tls_handshake); +- } +- +- /// Determine if the code represents an unrecoverable error +- /** +- * There is a class of errors for which once they are discovered normal +- * WebSocket functionality can no longer occur. This function determines +- * if a given code is one of these values. This information is used to +- * determine if the system has the capability of waiting for a close +- * acknowledgement or if it should drop the TCP connection immediately +- * after sending its close frame. +- * +- * @param [in] code The value to test. +- * @return True if the code represents an unrecoverable error +- */ +- inline bool terminal(value code) { +- return (code == protocol_error || code == invalid_payload || +- code == policy_violation || code == message_too_big || +- code == internal_endpoint_error); +- } +- +- /// Return a human readable interpretation of a WebSocket close code +- /** +- * See https://tools.ietf.org/html/rfc6455#section-7.4 for more details. +- * +- * @since 0.3.0 +- * +- * @param [in] code The code to look up. +- * @return A human readable interpretation of the code. +- */ +- inline std::string get_string(value code) { +- switch (code) { +- case normal: +- return "Normal close"; +- case going_away: +- return "Going away"; +- case protocol_error: +- return "Protocol error"; +- case unsupported_data: +- return "Unsupported data"; +- case no_status: +- return "No status set"; +- case abnormal_close: +- return "Abnormal close"; +- case invalid_payload: +- return "Invalid payload"; +- case policy_violation: +- return "Policy violoation"; +- case message_too_big: +- return "Message too big"; +- case extension_required: +- 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: +- return "Generic subprotocol error"; +- case invalid_subprotocol_data: +- return "Invalid subprotocol data"; +- default: +- return "Unknown"; +- } +- } +-} // namespace status +- +-/// Type used to convert close statuses between integer and wire representations +-union code_converter { +- uint16_t i; +- char c[2]; +-}; +- +-/// Extract a close code value from a close payload +-/** +- * If there is no close value (ie string is empty) status::no_status is +- * returned. If a code couldn't be extracted (usually do to a short or +- * otherwise mangled payload) status::protocol_error is returned and the ec +- * value is flagged as an error. Note that this case is different than the case +- * where protocol error is received over the wire. +- * +- * If the value is in an invalid or reserved range ec is set accordingly. +- * +- * @param [in] payload Close frame payload value received over the wire. +- * @param [out] ec Set to indicate what error occurred, if any. +- * @return The extracted value +- */ +-inline status::value extract_code(std::string const & payload, lib::error_code +- & ec) +-{ +- ec = lib::error_code(); +- +- if (payload.size() == 0) { +- return status::no_status; +- } else if (payload.size() == 1) { +- ec = make_error_code(error::bad_close_code); +- return status::protocol_error; +- } +- +- code_converter val; +- +- val.c[0] = payload[0]; +- val.c[1] = payload[1]; +- +- status::value code(ntohs(val.i)); +- +- if (status::invalid(code)) { +- ec = make_error_code(error::invalid_close_code); +- } +- +- if (status::reserved(code)) { +- ec = make_error_code(error::reserved_close_code); +- } +- +- return code; +-} +- +-/// Extract the reason string from a close payload +-/** +- * The string should be a valid UTF8 message. error::invalid_utf8 will be set if +- * the function extracts a reason that is not valid UTF8. +- * +- * @param [in] payload The payload string to extract a reason from. +- * @param [out] ec Set to indicate what error occurred, if any. +- * @return The reason string. +- */ +-inline std::string extract_reason(std::string const & payload, lib::error_code +- & ec) +-{ +- std::string reason; +- ec = lib::error_code(); +- +- if (payload.size() > 2) { +- reason.append(payload.begin()+2,payload.end()); +- } +- +- if (!ws_websocketpp::utf8_validator::validate(reason)) { +- ec = make_error_code(error::invalid_utf8); +- } +- +- return reason; +-} +- +-} // namespace close +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CLOSE_HPP +diff --git a/src/lib/websocketpp/common/asio.hpp b/src/lib/websocketpp/common/asio.hpp +deleted file mode 100644 +index 977211e..0000000 +--- a/src/lib/websocketpp/common/asio.hpp ++++ /dev/null +@@ -1,141 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_ASIO_HPP +-#define WEBSOCKETPP_COMMON_ASIO_HPP +- +-// This file goes to some length to preserve compatibility with versions of +-// boost older than 1.49 (where the first modern steady_timer timer based on +-// boost/std chrono was introduced. +-// +-// For the versions older than 1.49, the deadline_timer is used instead. this +-// brings in dependencies on boost date_time and it has a different interface +-// that is normalized by the `lib::asio::is_neg` and `lib::asio::milliseconds` +-// wrappers provided by this file. +-// +-// The primary reason for this continued support is that boost 1.48 is the +-// default and not easily changeable version of boost supplied by the package +-// manager of popular Linux distributions like Ubuntu 12.04 LTS. Once the need +-// for this has passed this should be cleaned up and simplified. +- +-#ifdef ASIO_STANDALONE +- #include +- +- #if (ASIO_VERSION/100000) == 1 && ((ASIO_VERSION/100)%1000) < 8 +- static_assert(false, "The minimum version of standalone Asio is 1.8.0"); +- #endif +- +- #include +- #include +- #include +-#else +- #include +- +- // See note above about boost <1.49 compatibility. If we are running on +- // boost > 1.48 pull in the steady timer and chrono library +- #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48 +- #include +- #include +- #endif +- +- #include +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef ASIO_STANDALONE +- namespace asio { +- using namespace ::asio; +- // Here we assume that we will be using std::error_code with standalone +- // Asio. This is probably a good assumption, but it is possible in rare +- // cases that local Asio versions would be used. +- using std::errc; +- +- // See note above about boost <1.49 compatibility. Because we require +- // a standalone Asio version of 1.8+ we are guaranteed to have +- // steady_timer available. By convention we require the chrono library +- // (either boost or std) for use with standalone Asio. +- template +- bool is_neg(T duration) { +- return duration.count() < 0; +- } +- inline lib::chrono::milliseconds milliseconds(long duration) { +- return lib::chrono::milliseconds(duration); +- } +- } // namespace asio +- +-#else +- namespace asio { +- using namespace boost::asio; +- +- // See note above about boost <1.49 compatibility +- #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 48 +- // Using boost::asio >=1.49 so we use chrono and steady_timer +- template +- bool is_neg(T duration) { +- return duration.count() < 0; +- } +- +- // 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 +- // appropriately. +- typedef boost::asio::deadline_timer steady_timer; +- +- template +- bool is_neg(T duration) { +- return duration.is_negative(); +- } +- inline boost::posix_time::time_duration milliseconds(long duration) { +- return boost::posix_time::milliseconds(duration); +- } +- #endif +- +- using boost::system::error_code; +- namespace errc = boost::system::errc; +- } // namespace asio +-#endif +- +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_ASIO_HPP +diff --git a/src/lib/websocketpp/common/asio_ssl.hpp b/src/lib/websocketpp/common/asio_ssl.hpp +deleted file mode 100644 +index 6989283..0000000 +--- a/src/lib/websocketpp/common/asio_ssl.hpp ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_ASIO_SSL_HPP +-#define WEBSOCKETPP_COMMON_ASIO_SSL_HPP +- +-// NOTE: This file must be included before common/asio.hpp +- +-#ifdef ASIO_STANDALONE +- #include +-#else +- #include +-#endif +- +-#endif // WEBSOCKETPP_COMMON_ASIO_SSL_HPP +diff --git a/src/lib/websocketpp/common/chrono.hpp b/src/lib/websocketpp/common/chrono.hpp +deleted file mode 100644 +index 67c5261..0000000 +--- a/src/lib/websocketpp/common/chrono.hpp ++++ /dev/null +@@ -1,68 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_CHRONO_HPP +-#define WEBSOCKETPP_COMMON_CHRONO_HPP +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 functional header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_ +- #ifndef _WEBSOCKETPP_CPP11_CHRONO_ +- #define _WEBSOCKETPP_CPP11_CHRONO_ +- #endif +-#endif +- +-// If we're on Visual Studio 2012 or higher and haven't explicitly disabled +-// the use of C++11 chrono header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1700 && !defined _WEBSOCKETPP_NO_CPP11_CHRONO_ +- #ifndef _WEBSOCKETPP_CPP11_CHRONO_ +- #define _WEBSOCKETPP_CPP11_CHRONO_ +- #endif +-#endif +- +-#ifdef _WEBSOCKETPP_CPP11_CHRONO_ +- #include +-#else +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_CHRONO_ +- namespace chrono = std::chrono; +-#else +- namespace chrono = boost::chrono; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_CHRONO_HPP +diff --git a/src/lib/websocketpp/common/connection_hdl.hpp b/src/lib/websocketpp/common/connection_hdl.hpp +deleted file mode 100644 +index 1eb2135..0000000 +--- a/src/lib/websocketpp/common/connection_hdl.hpp ++++ /dev/null +@@ -1,52 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP +-#define WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP +- +-#include +- +-namespace ws_websocketpp { +- +-/// A handle to uniquely identify a connection. +-/** +- * This type uniquely identifies a connection. It is implemented as a weak +- * pointer to the connection in question. This provides uniqueness across +- * multiple endpoints and ensures that IDs never conflict or run out. +- * +- * It is safe to make copies of this handle, store those copies in containers, +- * and use them from other threads. +- * +- * This handle can be upgraded to a full shared_ptr using +- * `endpoint::get_con_from_hdl()` from within a handler fired by the connection +- * that owns the handler. +- */ +-typedef lib::weak_ptr connection_hdl; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_CONNECTION_HDL_HPP +diff --git a/src/lib/websocketpp/common/cpp11.hpp b/src/lib/websocketpp/common/cpp11.hpp +deleted file mode 100644 +index 492a3b8..0000000 +--- a/src/lib/websocketpp/common/cpp11.hpp ++++ /dev/null +@@ -1,162 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_CPP11_HPP +-#define WEBSOCKETPP_COMMON_CPP11_HPP +- +-/** +- * This header sets up some constants based on the state of C++11 support +- */ +- +-// Hide clang feature detection from other compilers +-#ifndef __has_feature // Optional of course. +- #define __has_feature(x) 0 // Compatibility with non-clang compilers. +-#endif +-#ifndef __has_extension +- #define __has_extension __has_feature // Compatibility with pre-3.0 compilers. +-#endif +- +-// The code below attempts to use information provided by the build system or +-// user supplied defines to selectively enable C++11 language and library +-// features. In most cases features that are targeted individually may also be +-// selectively disabled via an associated _WEBSOCKETPP_NOXXX_ define. +- +-#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_) +- // This check tests for blanket c++11 coverage. It can be activated in one +- // of three ways. Either the compiler itself reports that it is a full +- // C++11 compiler via the __cplusplus macro or the user/build system +- // supplies one of the two preprocessor defines below: +- +- // This is defined to allow other WebSocket++ common headers to enable +- // C++11 features when they are detected by this file rather than +- // duplicating the above logic in every common header. +- #define _WEBSOCKETPP_CPP11_INTERNAL_ +- +- // _WEBSOCKETPP_CPP11_STRICT_ +- // +- // This define reports to WebSocket++ that 100% of the language and library +- // features of C++11 are available. Using this define on a non-C++11 +- // compiler will result in problems. +- +- // _WEBSOCKETPP_CPP11_STL_ +- // +- // This define enables *most* C++11 options that were implemented early on +- // by compilers. It is typically used for compilers that have many, but not +- // all C++11 features. It should be safe to use on GCC 4.7-4.8 and perhaps +- // earlier. +- #ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_ +- #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept +- #endif +- #ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_ +- #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr +- #endif +- #ifndef _WEBSOCKETPP_INITIALIZER_LISTS_ +- #define _WEBSOCKETPP_INITIALIZER_LISTS_ +- #endif +- #ifndef _WEBSOCKETPP_NULLPTR_TOKEN_ +- #define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr +- #endif +- #ifndef _WEBSOCKETPP_MOVE_SEMANTICS_ +- #define _WEBSOCKETPP_MOVE_SEMANTICS_ +- #endif +- #ifndef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- #define _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- #endif +- +- #ifndef __GNUC__ +- // GCC as of version 4.9 (latest) does not support std::put_time yet. +- // so ignore it +- #define _WEBSOCKETPP_PUTTIME_ +- #endif +-#else +- // In the absence of a blanket define, try to use compiler versions or +- // feature testing macros to selectively enable what we can. +- +- // Test for noexcept +- #ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_ +- #ifdef _WEBSOCKETPP_NOEXCEPT_ +- // build system says we have noexcept +- #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept +- #else +- #if __has_feature(cxx_noexcept) +- // clang feature detect says we have noexcept +- #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept +- #elif defined(_MSC_VER) && _MSC_VER >= 1900 +- // Visual Studio 2015+ has noexcept +- #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept +- #else +- // assume we don't have noexcept +- #define _WEBSOCKETPP_NOEXCEPT_TOKEN_ +- #endif +- #endif +- #endif +- +- // Test for constexpr +- #ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_ +- #ifdef _WEBSOCKETPP_CONSTEXPR_ +- // build system says we have constexpr +- #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr +- #else +- #if __has_feature(cxx_constexpr) +- // clang feature detect says we have constexpr +- #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr +- #elif defined(_MSC_VER) && _MSC_VER >= 1900 +- // Visual Studio 2015+ has constexpr +- #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ constexpr +- #else +- // assume we don't have constexpr +- #define _WEBSOCKETPP_CONSTEXPR_TOKEN_ +- #endif +- #endif +- #endif +- +- // Enable initializer lists on clang when available. +- #if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_) +- #define _WEBSOCKETPP_INITIALIZER_LISTS_ +- #endif +- +- // Test for nullptr +- #ifndef _WEBSOCKETPP_NULLPTR_TOKEN_ +- #ifdef _WEBSOCKETPP_NULLPTR_ +- // build system says we have nullptr +- #define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr +- #else +- #if __has_feature(cxx_nullptr) +- // clang feature detect says we have nullptr +- #define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr +- #elif defined(_MSC_VER) &&_MSC_VER >= 1600 +- // Visual Studio version that has nullptr +- #define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr +- #else +- // assume we don't have nullptr +- #define _WEBSOCKETPP_NULLPTR_TOKEN_ 0 +- #endif +- #endif +- #endif +-#endif +- +-#endif // WEBSOCKETPP_COMMON_CPP11_HPP +diff --git a/src/lib/websocketpp/common/functional.hpp b/src/lib/websocketpp/common/functional.hpp +deleted file mode 100644 +index dbb1f02..0000000 +--- a/src/lib/websocketpp/common/functional.hpp ++++ /dev/null +@@ -1,105 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_FUNCTIONAL_HPP +-#define WEBSOCKETPP_COMMON_FUNCTIONAL_HPP +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 functional header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_ +- #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- #define _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- #endif +-#endif +- +-// If we're on Visual Studio 2010 or higher and haven't explicitly disabled +-// the use of C++11 functional header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_FUNCTIONAL_ +- #ifndef _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- #define _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- #endif +-#endif +- +- +- +-#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- #include +-#else +- #include +- #include +- #include +-#endif +- +- +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_FUNCTIONAL_ +- using std::function; +- using std::bind; +- using std::ref; +- namespace placeholders = std::placeholders; +- +- // There are some cases where a C++11 compiler balks at using std::ref +- // but a C++03 compiler using boost function requires boost::ref. As such +- // lib::ref is not useful in these cases. Instead this macro allows the use +- // of boost::ref in the case of a boost compile or no reference wrapper at +- // all in the case of a C++11 compile +- #define _WEBSOCKETPP_REF(x) x +- +- template +- void clear_function(T & x) { +- x = nullptr; +- } +-#else +- using boost::function; +- using boost::bind; +- using boost::ref; +- namespace placeholders { +- /// \todo this feels hacky, is there a better way? +- using ::_1; +- using ::_2; +- using ::_3; +- } +- +- // See above definition for more details on what this is and why it exists +- #define _WEBSOCKETPP_REF(x) boost::ref(x) +- +- template +- void clear_function(T & x) { +- x.clear(); +- } +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_FUNCTIONAL_HPP +diff --git a/src/lib/websocketpp/common/md5.hpp b/src/lib/websocketpp/common/md5.hpp +deleted file mode 100644 +index 0ef0477..0000000 +--- a/src/lib/websocketpp/common/md5.hpp ++++ /dev/null +@@ -1,448 +0,0 @@ +-/* +- 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 +- +- */ +-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ +-/* +- Independent implementation of MD5 (RFC 1321). +- +- This code implements the MD5 Algorithm defined in RFC 1321, whose +- text is available at +- http://www.ietf.org/rfc/rfc1321.txt +- The code is derived from the text of the RFC, including the test suite +- (section A.5) but excluding the rest of Appendix A. It does not include +- any code or documentation that is identified in the RFC as being +- copyrighted. +- +- The original and principal author of md5.h is L. Peter Deutsch +- . Other authors are noted in the change history +- that follows (in reverse chronological order): +- +- 2002-04-13 lpd Removed support for non-ANSI compilers; removed +- references to Ghostscript; clarified derivation from RFC 1321; +- now handles byte order either statically or dynamically. +- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. +- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); +- added conditionalization for C++ compilation from Martin +- Purschke . +- 1999-05-03 lpd Original version. +- */ +- +-#ifndef WEBSOCKETPP_COMMON_MD5_HPP +-#define WEBSOCKETPP_COMMON_MD5_HPP +- +-/* +- * This package supports both compile-time and run-time determination of CPU +- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be +- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is +- * defined as non-zero, the code will be compiled to run only on big-endian +- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to +- * run on either big- or little-endian CPUs, but will run slightly less +- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. +- */ +- +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-/// Provides MD5 hashing functionality +-namespace md5 { +- +-typedef unsigned char md5_byte_t; /* 8-bit byte */ +-typedef unsigned int md5_word_t; /* 32-bit word */ +- +-/* Define the state of the MD5 Algorithm. */ +-typedef struct md5_state_s { +- md5_word_t count[2]; /* message length in bits, lsw first */ +- md5_word_t abcd[4]; /* digest buffer */ +- md5_byte_t buf[64]; /* accumulate block */ +-} md5_state_t; +- +-/* Initialize the algorithm. */ +-inline void md5_init(md5_state_t *pms); +- +-/* Append a string to the message. */ +-inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes); +- +-/* Finish the message and return the digest. */ +-inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); +- +-#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +-#ifdef ARCH_IS_BIG_ENDIAN +-# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +-#else +-# define ZSW_MD5_BYTE_ORDER 0 +-#endif +- +-#define ZSW_MD5_T_MASK ((md5_word_t)~0) +-#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87) +-#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9) +-#define ZSW_MD5_T3 0x242070db +-#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111) +-#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050) +-#define ZSW_MD5_T6 0x4787c62a +-#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec) +-#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe) +-#define ZSW_MD5_T9 0x698098d8 +-#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850) +-#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e) +-#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841) +-#define ZSW_MD5_T13 0x6b901122 +-#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c) +-#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71) +-#define ZSW_MD5_T16 0x49b40821 +-#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d) +-#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf) +-#define ZSW_MD5_T19 0x265e5a51 +-#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855) +-#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2) +-#define ZSW_MD5_T22 0x02441453 +-#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e) +-#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437) +-#define ZSW_MD5_T25 0x21e1cde6 +-#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829) +-#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278) +-#define ZSW_MD5_T28 0x455a14ed +-#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa) +-#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07) +-#define ZSW_MD5_T31 0x676f02d9 +-#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375) +-#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd) +-#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e) +-#define ZSW_MD5_T35 0x6d9d6122 +-#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3) +-#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb) +-#define ZSW_MD5_T38 0x4bdecfa9 +-#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f) +-#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f) +-#define ZSW_MD5_T41 0x289b7ec6 +-#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805) +-#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a) +-#define ZSW_MD5_T44 0x04881d05 +-#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6) +-#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a) +-#define ZSW_MD5_T47 0x1fa27cf8 +-#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a) +-#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb) +-#define ZSW_MD5_T50 0x432aff97 +-#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58) +-#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6) +-#define ZSW_MD5_T53 0x655b59c3 +-#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d) +-#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82) +-#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e) +-#define ZSW_MD5_T57 0x6fa87e4f +-#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f) +-#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb) +-#define ZSW_MD5_T60 0x4e0811a1 +-#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d) +-#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca) +-#define ZSW_MD5_T63 0x2ad7d2bb +-#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e) +- +-static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) { +- md5_word_t +- a = pms->abcd[0], b = pms->abcd[1], +- c = pms->abcd[2], d = pms->abcd[3]; +- md5_word_t t; +-#if ZSW_MD5_BYTE_ORDER > 0 +- /* Define storage only for big-endian CPUs. */ +- md5_word_t X[16]; +-#else +- /* Define storage for little-endian or both types of CPUs. */ +- md5_word_t xbuf[16]; +- md5_word_t const * X; +-#endif +- +- { +-#if ZSW_MD5_BYTE_ORDER == 0 +- /* +- * Determine dynamically whether this is a big-endian or +- * little-endian machine, since we can use a more efficient +- * algorithm on the latter. +- */ +- static int const w = 1; +- +- if (*((md5_byte_t const *)&w)) /* dynamic little-endian */ +-#endif +-#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */ +- { +- /* +- * On little-endian machines, we can process properly aligned +- * data without copying it. +- */ +- if (!((data - (md5_byte_t const *)0) & 3)) { +- /* data are properly aligned */ +- X = (md5_word_t const *)data; +- } else { +- /* not aligned */ +- std::memcpy(xbuf, data, 64); +- X = xbuf; +- } +- } +-#endif +-#if ZSW_MD5_BYTE_ORDER == 0 +- else /* dynamic big-endian */ +-#endif +-#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */ +- { +- /* +- * On big-endian machines, we must arrange the bytes in the +- * right order. +- */ +- const md5_byte_t *xp = data; +- int i; +- +-# if ZSW_MD5_BYTE_ORDER == 0 +- X = xbuf; /* (dynamic only) */ +-# else +-# define xbuf X /* (static only) */ +-# endif +- for (i = 0; i < 16; ++i, xp += 4) +- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); +- } +-#endif +- } +- +-#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +- +- /* Round 1. */ +- /* Let [abcd k s i] denote the operation +- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +-#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z))) +-#define SET(a, b, c, d, k, s, Ti)\ +- t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\ +- a = ZSW_MD5_ROTATE_LEFT(t, s) + b +- /* Do the following 16 operations. */ +- SET(a, b, c, d, 0, 7, ZSW_MD5_T1); +- SET(d, a, b, c, 1, 12, ZSW_MD5_T2); +- SET(c, d, a, b, 2, 17, ZSW_MD5_T3); +- SET(b, c, d, a, 3, 22, ZSW_MD5_T4); +- SET(a, b, c, d, 4, 7, ZSW_MD5_T5); +- SET(d, a, b, c, 5, 12, ZSW_MD5_T6); +- SET(c, d, a, b, 6, 17, ZSW_MD5_T7); +- SET(b, c, d, a, 7, 22, ZSW_MD5_T8); +- SET(a, b, c, d, 8, 7, ZSW_MD5_T9); +- SET(d, a, b, c, 9, 12, ZSW_MD5_T10); +- SET(c, d, a, b, 10, 17, ZSW_MD5_T11); +- SET(b, c, d, a, 11, 22, ZSW_MD5_T12); +- SET(a, b, c, d, 12, 7, ZSW_MD5_T13); +- SET(d, a, b, c, 13, 12, ZSW_MD5_T14); +- SET(c, d, a, b, 14, 17, ZSW_MD5_T15); +- SET(b, c, d, a, 15, 22, ZSW_MD5_T16); +-#undef SET +- +- /* Round 2. */ +- /* Let [abcd k s i] denote the operation +- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +-#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +-#define SET(a, b, c, d, k, s, Ti)\ +- t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\ +- a = ZSW_MD5_ROTATE_LEFT(t, s) + b +- /* Do the following 16 operations. */ +- SET(a, b, c, d, 1, 5, ZSW_MD5_T17); +- SET(d, a, b, c, 6, 9, ZSW_MD5_T18); +- SET(c, d, a, b, 11, 14, ZSW_MD5_T19); +- SET(b, c, d, a, 0, 20, ZSW_MD5_T20); +- SET(a, b, c, d, 5, 5, ZSW_MD5_T21); +- SET(d, a, b, c, 10, 9, ZSW_MD5_T22); +- SET(c, d, a, b, 15, 14, ZSW_MD5_T23); +- SET(b, c, d, a, 4, 20, ZSW_MD5_T24); +- SET(a, b, c, d, 9, 5, ZSW_MD5_T25); +- SET(d, a, b, c, 14, 9, ZSW_MD5_T26); +- SET(c, d, a, b, 3, 14, ZSW_MD5_T27); +- SET(b, c, d, a, 8, 20, ZSW_MD5_T28); +- SET(a, b, c, d, 13, 5, ZSW_MD5_T29); +- SET(d, a, b, c, 2, 9, ZSW_MD5_T30); +- SET(c, d, a, b, 7, 14, ZSW_MD5_T31); +- SET(b, c, d, a, 12, 20, ZSW_MD5_T32); +-#undef SET +- +- /* Round 3. */ +- /* Let [abcd k s t] denote the operation +- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +-#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z)) +-#define SET(a, b, c, d, k, s, Ti)\ +- t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\ +- a = ZSW_MD5_ROTATE_LEFT(t, s) + b +- /* Do the following 16 operations. */ +- SET(a, b, c, d, 5, 4, ZSW_MD5_T33); +- SET(d, a, b, c, 8, 11, ZSW_MD5_T34); +- SET(c, d, a, b, 11, 16, ZSW_MD5_T35); +- SET(b, c, d, a, 14, 23, ZSW_MD5_T36); +- SET(a, b, c, d, 1, 4, ZSW_MD5_T37); +- SET(d, a, b, c, 4, 11, ZSW_MD5_T38); +- SET(c, d, a, b, 7, 16, ZSW_MD5_T39); +- SET(b, c, d, a, 10, 23, ZSW_MD5_T40); +- SET(a, b, c, d, 13, 4, ZSW_MD5_T41); +- SET(d, a, b, c, 0, 11, ZSW_MD5_T42); +- SET(c, d, a, b, 3, 16, ZSW_MD5_T43); +- SET(b, c, d, a, 6, 23, ZSW_MD5_T44); +- SET(a, b, c, d, 9, 4, ZSW_MD5_T45); +- SET(d, a, b, c, 12, 11, ZSW_MD5_T46); +- SET(c, d, a, b, 15, 16, ZSW_MD5_T47); +- SET(b, c, d, a, 2, 23, ZSW_MD5_T48); +-#undef SET +- +- /* Round 4. */ +- /* Let [abcd k s t] denote the operation +- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +-#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) +-#define SET(a, b, c, d, k, s, Ti)\ +- t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\ +- a = ZSW_MD5_ROTATE_LEFT(t, s) + b +- /* Do the following 16 operations. */ +- SET(a, b, c, d, 0, 6, ZSW_MD5_T49); +- SET(d, a, b, c, 7, 10, ZSW_MD5_T50); +- SET(c, d, a, b, 14, 15, ZSW_MD5_T51); +- SET(b, c, d, a, 5, 21, ZSW_MD5_T52); +- SET(a, b, c, d, 12, 6, ZSW_MD5_T53); +- SET(d, a, b, c, 3, 10, ZSW_MD5_T54); +- SET(c, d, a, b, 10, 15, ZSW_MD5_T55); +- SET(b, c, d, a, 1, 21, ZSW_MD5_T56); +- SET(a, b, c, d, 8, 6, ZSW_MD5_T57); +- SET(d, a, b, c, 15, 10, ZSW_MD5_T58); +- SET(c, d, a, b, 6, 15, ZSW_MD5_T59); +- SET(b, c, d, a, 13, 21, ZSW_MD5_T60); +- SET(a, b, c, d, 4, 6, ZSW_MD5_T61); +- SET(d, a, b, c, 11, 10, ZSW_MD5_T62); +- SET(c, d, a, b, 2, 15, ZSW_MD5_T63); +- SET(b, c, d, a, 9, 21, ZSW_MD5_T64); +-#undef SET +- +- /* Then perform the following additions. (That is increment each +- of the four registers by the value it had before this block +- was started.) */ +- pms->abcd[0] += a; +- pms->abcd[1] += b; +- pms->abcd[2] += c; +- pms->abcd[3] += d; +-} +- +-void md5_init(md5_state_t *pms) { +- pms->count[0] = pms->count[1] = 0; +- pms->abcd[0] = 0x67452301; +- pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476; +- pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301; +- pms->abcd[3] = 0x10325476; +-} +- +-void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) { +- md5_byte_t const * p = data; +- size_t left = nbytes; +- int offset = (pms->count[0] >> 3) & 63; +- md5_word_t nbits = (md5_word_t)(nbytes << 3); +- +- if (nbytes <= 0) +- return; +- +- /* Update the message length. */ +- pms->count[1] += nbytes >> 29; +- pms->count[0] += nbits; +- if (pms->count[0] < nbits) +- pms->count[1]++; +- +- /* Process an initial partial block. */ +- if (offset) { +- int copy = (offset + nbytes > 64 ? 64 - offset : static_cast(nbytes)); +- +- std::memcpy(pms->buf + offset, p, copy); +- if (offset + copy < 64) +- return; +- p += copy; +- left -= copy; +- md5_process(pms, pms->buf); +- } +- +- /* Process full blocks. */ +- for (; left >= 64; p += 64, left -= 64) +- md5_process(pms, p); +- +- /* Process a final partial block. */ +- if (left) +- std::memcpy(pms->buf, p, left); +-} +- +-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { +- static md5_byte_t const pad[64] = { +- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +- }; +- md5_byte_t data[8]; +- int i; +- +- /* Save the length before padding. */ +- for (i = 0; i < 8; ++i) +- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); +- /* Pad to 56 bytes mod 64. */ +- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); +- /* Append the length. */ +- md5_append(pms, data, 8); +- for (i = 0; i < 16; ++i) +- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +-} +- +-// some convenience c++ functions +-inline std::string md5_hash_string(std::string const & s) { +- char digest[16]; +- +- md5_state_t state; +- +- md5_init(&state); +- md5_append(&state, (md5_byte_t const *)s.c_str(), s.size()); +- md5_finish(&state, (md5_byte_t *)digest); +- +- std::string ret; +- ret.resize(16); +- std::copy(digest,digest+16,ret.begin()); +- +- return ret; +-} +- +-const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; +- +-inline std::string md5_hash_hex(std::string const & input) { +- std::string hash = md5_hash_string(input); +- std::string hex; +- +- for (size_t i = 0; i < hash.size(); i++) { +- hex.push_back(hexval[((hash[i] >> 4) & 0xF)]); +- hex.push_back(hexval[(hash[i]) & 0x0F]); +- } +- +- return hex; +-} +- +-} // md5 +-} // websocketpp +- +-#endif // WEBSOCKETPP_COMMON_MD5_HPP +diff --git a/src/lib/websocketpp/common/memory.hpp b/src/lib/websocketpp/common/memory.hpp +deleted file mode 100644 +index 677680f..0000000 +--- a/src/lib/websocketpp/common/memory.hpp ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_MEMORY_HPP +-#define WEBSOCKETPP_COMMON_MEMORY_HPP +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 memory header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_ +- #ifndef _WEBSOCKETPP_CPP11_MEMORY_ +- #define _WEBSOCKETPP_CPP11_MEMORY_ +- #endif +-#endif +- +-// If we're on Visual Studio 2010 or higher and haven't explicitly disabled +-// the use of C++11 functional header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_ +- #ifndef _WEBSOCKETPP_CPP11_MEMORY_ +- #define _WEBSOCKETPP_CPP11_MEMORY_ +- #endif +-#endif +- +- +- +-#ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- #include +-#else +- #include +- #include +- #include +- #include +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- using std::shared_ptr; +- using std::weak_ptr; +- using std::enable_shared_from_this; +- using std::static_pointer_cast; +- using std::make_shared; +- using std::unique_ptr; +- +- typedef std::unique_ptr unique_ptr_uchar_array; +-#else +- using boost::shared_ptr; +- using boost::weak_ptr; +- using std::auto_ptr; +- using boost::enable_shared_from_this; +- using boost::static_pointer_cast; +- using boost::make_shared; +- +- typedef boost::scoped_array unique_ptr_uchar_array; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_MEMORY_HPP +diff --git a/src/lib/websocketpp/common/network.hpp b/src/lib/websocketpp/common/network.hpp +deleted file mode 100644 +index a9c03d5..0000000 +--- a/src/lib/websocketpp/common/network.hpp ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_NETWORK_HPP +-#define WEBSOCKETPP_COMMON_NETWORK_HPP +- +-// For ntohs and htons +-#if defined(_WIN32) +- #include +-#else +- //#include +- #include +-#endif +- +-#include +- +-namespace ws_websocketpp { +-namespace lib { +-namespace net { +- +-inline bool is_little_endian() { +- short int val = 0x1; +- char *ptr = reinterpret_cast(&val); +- return (ptr[0] == 1); +-} +- +-#define TYP_INIT 0 +-#define TYP_SMLE 1 +-#define TYP_BIGE 2 +- +-/// Convert 64 bit value to network byte order +-/** +- * This method is prefixed to avoid conflicts with operating system level +- * macros for this functionality. +- * +- * TODO: figure out if it would be beneficial to use operating system level +- * macros for this. +- * +- * @param src The integer in host byte order +- * @return src converted to network byte order +- */ +-inline uint64_t _htonll(uint64_t src) { +- static int typ = TYP_INIT; +- unsigned char c; +- union { +- uint64_t ull; +- unsigned char c[8]; +- } x; +- if (typ == TYP_INIT) { +- x.ull = 0x01; +- typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE; +- } +- if (typ == TYP_BIGE) +- return src; +- x.ull = src; +- c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c; +- c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c; +- c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c; +- c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c; +- return x.ull; +-} +- +-/// Convert 64 bit value to host byte order +-/** +- * This method is prefixed to avoid conflicts with operating system level +- * macros for this functionality. +- * +- * TODO: figure out if it would be beneficial to use operating system level +- * macros for this. +- * +- * @param src The integer in network byte order +- * @return src converted to host byte order +- */ +-inline uint64_t _ntohll(uint64_t src) { +- return _htonll(src); +-} +- +-} // net +-} // lib +-} // websocketpp +- +-#endif // WEBSOCKETPP_COMMON_NETWORK_HPP +diff --git a/src/lib/websocketpp/common/platforms.hpp b/src/lib/websocketpp/common/platforms.hpp +deleted file mode 100644 +index 8779857..0000000 +--- a/src/lib/websocketpp/common/platforms.hpp ++++ /dev/null +@@ -1,46 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_PLATFORMS_HPP +-#define WEBSOCKETPP_COMMON_PLATFORMS_HPP +- +-/** +- * This header contains any platform specific preprocessor adjustments that +- * don't fit somewhere else better. +- */ +- +-#if defined(_WIN32) && !defined(NOMINMAX) +- // don't define min and max macros that conflict with std::min and std::max +- #define NOMINMAX +-#endif +- +-// Bump up the variadic parameter max for Visual Studio 2012 +-#if defined(_MSC_VER) && _MSC_VER == 1700 +- #define _VARIADIC_MAX 8 +-#endif +- +-#endif // WEBSOCKETPP_COMMON_PLATFORMS_HPP +diff --git a/src/lib/websocketpp/common/random.hpp b/src/lib/websocketpp/common/random.hpp +deleted file mode 100644 +index 2119dc2..0000000 +--- a/src/lib/websocketpp/common/random.hpp ++++ /dev/null +@@ -1,82 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP +-#define WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 random header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_RANDOM_DEVICE_ +- #ifndef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ +- #define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ +- #endif +-#endif +- +- +-// If we're on Visual Studio 2010 or higher and haven't explicitly disabled +-// the use of C++11 random header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_MEMORY_ +- #ifndef _WEBSOCKETPP_CPP11_MEMORY_ +- #define _WEBSOCKETPP_CPP11_MEMORY_ +- #endif +-#endif +- +- +- +-#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ +- #include +-#else +- #include +- +- #if (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) > 46 +- #include +- #include +- #elif (BOOST_VERSION/100000) == 1 && ((BOOST_VERSION/100)%1000) >= 43 +- #include +- #else +- // TODO: static_assert(false, "Could not find a suitable random_device") +- #endif +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ +- using std::random_device; +- using std::uniform_int_distribution; +-#else +- using boost::random::random_device; +- using boost::random::uniform_int_distribution; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_RANDOM_DEVICE_HPP +diff --git a/src/lib/websocketpp/common/regex.hpp b/src/lib/websocketpp/common/regex.hpp +deleted file mode 100644 +index 7a51dc9..0000000 +--- a/src/lib/websocketpp/common/regex.hpp ++++ /dev/null +@@ -1,59 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_REGEX_HPP +-#define WEBSOCKETPP_COMMON_REGEX_HPP +- +-#if defined _WEBSOCKETPP_CPP11_STL_ && !defined _WEBSOCKETPP_NO_CPP11_REGEX_ +- #ifndef _WEBSOCKETPP_CPP11_REGEX_ +- #define _WEBSOCKETPP_CPP11_REGEX_ +- #endif +-#endif +- +-#ifdef _WEBSOCKETPP_CPP11_REGEX_ +- #include +-#else +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_REGEX_ +- using std::cmatch; +- using std::regex; +- using std::regex_match; +-#else +- using boost::cmatch; +- using boost::regex; +- using boost::regex_match; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_REGEX_HPP +diff --git a/src/lib/websocketpp/common/stdint.hpp b/src/lib/websocketpp/common/stdint.hpp +deleted file mode 100644 +index ec48ea7..0000000 +--- a/src/lib/websocketpp/common/stdint.hpp ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_STDINT_HPP +-#define WEBSOCKETPP_COMMON_STDINT_HPP +- +-#ifndef __STDC_LIMIT_MACROS +- #define __STDC_LIMIT_MACROS 1 +-#endif +- +-#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600) +- #include +- +- using boost::int8_t; +- using boost::int_least8_t; +- using boost::int_fast8_t; +- using boost::uint8_t; +- using boost::uint_least8_t; +- using boost::uint_fast8_t; +- +- using boost::int16_t; +- using boost::int_least16_t; +- using boost::int_fast16_t; +- using boost::uint16_t; +- using boost::uint_least16_t; +- using boost::uint_fast16_t; +- +- using boost::int32_t; +- using boost::int_least32_t; +- using boost::int_fast32_t; +- using boost::uint32_t; +- using boost::uint_least32_t; +- using boost::uint_fast32_t; +- +- #ifndef BOOST_NO_INT64_T +- using boost::int64_t; +- using boost::int_least64_t; +- using boost::int_fast64_t; +- using boost::uint64_t; +- using boost::uint_least64_t; +- using boost::uint_fast64_t; +- #endif +- using boost::intmax_t; +- using boost::uintmax_t; +-#else +- #include +-#endif +- +-#endif // WEBSOCKETPP_COMMON_STDINT_HPP +diff --git a/src/lib/websocketpp/common/system_error.hpp b/src/lib/websocketpp/common/system_error.hpp +deleted file mode 100644 +index 7b431a7..0000000 +--- a/src/lib/websocketpp/common/system_error.hpp ++++ /dev/null +@@ -1,84 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP +-#define WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP +- +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 system_error header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_ +- #ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- #endif +-#endif +- +-// If we're on Visual Studio 2010 or higher and haven't explicitly disabled +-// the use of C++11 system_error header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1600 && !defined _WEBSOCKETPP_NO_CPP11_SYSTEM_ERROR_ +- #ifndef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- #endif +-#endif +- +- +- +-#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- #include +-#else +- #include +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +- using std::errc; +- using std::error_code; +- using std::error_category; +- using std::error_condition; +- using std::system_error; +- #define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace std { +- #define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ } +-#else +- namespace errc = boost::system::errc; +- using boost::system::error_code; +- using boost::system::error_category; +- using boost::system::error_condition; +- using boost::system::system_error; +- #define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ namespace boost { namespace system { +- #define _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ }} +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_SYSTEM_ERROR_HPP +diff --git a/src/lib/websocketpp/common/thread.hpp b/src/lib/websocketpp/common/thread.hpp +deleted file mode 100644 +index 535222a..0000000 +--- a/src/lib/websocketpp/common/thread.hpp ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_THREAD_HPP +-#define WEBSOCKETPP_COMMON_THREAD_HPP +- +-#include +- +-// If we autodetect C++11 and haven't been explicitly instructed to not use +-// C++11 threads, then set the defines that instructs the rest of this header +-// to use C++11 and +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_THREAD_ +- // MinGW by default does not support C++11 thread/mutex so even if the +- // internal check for C++11 passes, ignore it if we are on MinGW +- #if (!defined(__MINGW32__) && !defined(__MINGW64__)) +- #ifndef _WEBSOCKETPP_CPP11_THREAD_ +- #define _WEBSOCKETPP_CPP11_THREAD_ +- #endif +- #endif +-#endif +- +-// If we're on Visual Studio 2013 or higher and haven't explicitly disabled +-// the use of C++11 thread header then prefer it to boost. +-#if defined(_MSC_VER) && _MSC_VER >= 1800 && !defined _WEBSOCKETPP_NO_CPP11_THREAD_ +- #ifndef _WEBSOCKETPP_CPP11_THREAD_ +- #define _WEBSOCKETPP_CPP11_THREAD_ +- #endif +-#endif +- +-#if defined(_WEBSOCKETPP_MINGW_THREAD_) +- #include +- #include +- #include +-#elif defined(_WEBSOCKETPP_CPP11_THREAD_) +- #include +- #include +- #include +-#else +- #include +- #include +- #include +-#endif +- +-namespace ws_websocketpp { +-namespace lib { +- +-#if defined(_WEBSOCKETPP_CPP11_THREAD_) || defined(_WEBSOCKETPP_MINGW_THREAD_) +- using std::mutex; +- using std::lock_guard; +- using std::thread; +- using std::unique_lock; +- using std::condition_variable; +-#else +- using boost::mutex; +- using boost::lock_guard; +- using boost::thread; +- using boost::unique_lock; +- using boost::condition_variable; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_THREAD_HPP +diff --git a/src/lib/websocketpp/common/time.hpp b/src/lib/websocketpp/common/time.hpp +deleted file mode 100644 +index 968fdff..0000000 +--- a/src/lib/websocketpp/common/time.hpp ++++ /dev/null +@@ -1,56 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_TIME_HPP +-#define WEBSOCKETPP_COMMON_TIME_HPP +- +-#include +- +-namespace ws_websocketpp { +-namespace lib { +- +-// Code in this header was inspired by the following article and includes some +-// code from the related project g2log. The g2log code is public domain licensed +-// http://kjellkod.wordpress.com/2013/01/22/exploring-c11-part-2-localtime-and-time-again/ +- +-/// Thread safe cross platform localtime +-inline std::tm localtime(std::time_t const & time) { +- std::tm tm_snapshot; +-#if (defined(__MINGW32__) || defined(__MINGW64__)) +- memcpy(&tm_snapshot, ::localtime(&time), sizeof(std::tm)); +-#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) +- localtime_s(&tm_snapshot, &time); +-#else +- localtime_r(&time, &tm_snapshot); // POSIX +-#endif +- return tm_snapshot; +-} +- +-} // lib +-} // websocketpp +- +-#endif // WEBSOCKETPP_COMMON_TIME_HPP +diff --git a/src/lib/websocketpp/common/type_traits.hpp b/src/lib/websocketpp/common/type_traits.hpp +deleted file mode 100644 +index 708292e..0000000 +--- a/src/lib/websocketpp/common/type_traits.hpp ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP +-#define WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP +- +-#include +- +-// If we've determined that we're in full C++11 mode and the user hasn't +-// explicitly disabled the use of C++11 functional header, then prefer it to +-// boost. +-#if defined _WEBSOCKETPP_CPP11_INTERNAL_ && !defined _WEBSOCKETPP_NO_CPP11_TYPE_TRAITS_ +- #ifndef _WEBSOCKETPP_CPP11_TYPE_TRAITS_ +- #define _WEBSOCKETPP_CPP11_TYPE_TRAITS_ +- #endif +-#endif +- +- +-#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_ +- #include +-#else +- #include +-#endif +- +- +- +-namespace ws_websocketpp { +-namespace lib { +- +-#ifdef _WEBSOCKETPP_CPP11_TYPE_TRAITS_ +- using std::aligned_storage; +- using std::is_same; +-#else +- using boost::aligned_storage; +- using boost::is_same; +-#endif +- +-} // namespace lib +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_COMMON_TYPE_TRAITS_HPP +diff --git a/src/lib/websocketpp/concurrency/basic.hpp b/src/lib/websocketpp/concurrency/basic.hpp +deleted file mode 100644 +index 70afdb0..0000000 +--- a/src/lib/websocketpp/concurrency/basic.hpp ++++ /dev/null +@@ -1,46 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONCURRENCY_BASIC_HPP +-#define WEBSOCKETPP_CONCURRENCY_BASIC_HPP +- +-#include +- +-namespace ws_websocketpp { +-namespace concurrency { +- +-/// Concurrency policy that uses std::mutex / boost::mutex +-class basic { +-public: +- typedef lib::mutex mutex_type; +- typedef lib::lock_guard scoped_lock_type; +-}; +- +-} // namespace concurrency +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONCURRENCY_BASIC_HPP +diff --git a/src/lib/websocketpp/concurrency/none.hpp b/src/lib/websocketpp/concurrency/none.hpp +deleted file mode 100644 +index 9c8485a..0000000 +--- a/src/lib/websocketpp/concurrency/none.hpp ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONCURRENCY_NONE_HPP +-#define WEBSOCKETPP_CONCURRENCY_NONE_HPP +- +-namespace ws_websocketpp { +- +-/// Concurrency handling support +-namespace concurrency { +- +-/// Implementation for no-op locking primitives +-namespace none_impl { +-/// A fake mutex implementation that does nothing +-class fake_mutex { +-public: +- fake_mutex() {} +- ~fake_mutex() {} +-}; +- +-/// A fake lock guard implementation that does nothing +-class fake_lock_guard { +-public: +- explicit fake_lock_guard(fake_mutex) {} +- ~fake_lock_guard() {} +-}; +-} // namespace none_impl +- +-/// Stub concurrency policy that implements the interface using no-ops. +-/** +- * This policy documents the concurrency policy interface using no-ops. It can +- * be used as a reference or base for building a new concurrency policy. It can +- * also be used as is to disable all locking for endpoints used in purely single +- * threaded programs. +- */ +-class none { +-public: +- /// The type of a mutex primitive +- /** +- * std::mutex is an example. +- */ +- typedef none_impl::fake_mutex mutex_type; +- +- /// The type of a scoped/RAII lock primitive. +- /** +- * The scoped lock constructor should take a mutex_type as a parameter, +- * acquire that lock, and release it in its destructor. std::lock_guard is +- * an example. +- */ +- typedef none_impl::fake_lock_guard scoped_lock_type; +-}; +- +-} // namespace concurrency +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONCURRENCY_ASYNC_HPP +diff --git a/src/lib/websocketpp/config/asio.hpp b/src/lib/websocketpp/config/asio.hpp +deleted file mode 100644 +index 460b07d..0000000 +--- a/src/lib/websocketpp/config/asio.hpp ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_TLS_HPP +- +-#include +-#include +-#include +- +-// Pull in non-tls config +-#include +- +-// Define TLS config +-namespace ws_websocketpp { +-namespace config { +- +-/// Server config with asio transport and TLS enabled +-struct asio_tls : public core { +- typedef asio_tls type; +- typedef core base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::tls_socket::endpoint socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_HPP +diff --git a/src/lib/websocketpp/config/asio_client.hpp b/src/lib/websocketpp/config/asio_client.hpp +deleted file mode 100644 +index 2c5d4e9..0000000 +--- a/src/lib/websocketpp/config/asio_client.hpp ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP +- +-#include +-#include +-#include +- +-// Pull in non-tls config +-#include +- +-// Define TLS config +-namespace ws_websocketpp { +-namespace config { +- +-/// Client config with asio transport and TLS enabled +-struct asio_tls_client : public core_client { +- typedef asio_tls_client type; +- typedef core_client base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::tls_socket::endpoint socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_CLIENT_HPP +diff --git a/src/lib/websocketpp/config/asio_no_tls.hpp b/src/lib/websocketpp/config/asio_no_tls.hpp +deleted file mode 100644 +index 2ad9b8b..0000000 +--- a/src/lib/websocketpp/config/asio_no_tls.hpp ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Server config with asio transport and TLS disabled +-struct asio : public core { +- typedef asio type; +- typedef core base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::basic_socket::endpoint +- socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_HPP +diff --git a/src/lib/websocketpp/config/asio_no_tls_client.hpp b/src/lib/websocketpp/config/asio_no_tls_client.hpp +deleted file mode 100644 +index fa4fc48..0000000 +--- a/src/lib/websocketpp/config/asio_no_tls_client.hpp ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Client config with asio transport and TLS disabled +-struct asio_client : public core_client { +- typedef asio_client type; +- typedef core_client base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::basic_socket::endpoint +- socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_CLIENT_HPP +diff --git a/src/lib/websocketpp/config/boost_config.hpp b/src/lib/websocketpp/config/boost_config.hpp +deleted file mode 100644 +index 57671cc..0000000 +--- a/src/lib/websocketpp/config/boost_config.hpp ++++ /dev/null +@@ -1,72 +0,0 @@ +-/* +- * 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. +- * +- */ +- +- // This header defines WebSocket++ macros for C++11 compatibility based on the +- // Boost.Config library. This will correctly configure most target platforms +- // simply by including this header before any other WebSocket++ header. +- +-#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP +-#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP +- +-#include +- +-// _WEBSOCKETPP_CPP11_MEMORY_ and _WEBSOCKETPP_CPP11_FUNCTIONAL_ presently +-// only work if either both or neither is defined. +-#if !defined BOOST_NO_CXX11_SMART_PTR && !defined BOOST_NO_CXX11_HDR_FUNCTIONAL +- #define _WEBSOCKETPP_CPP11_MEMORY_ +- #define _WEBSOCKETPP_CPP11_FUNCTIONAL_ +-#endif +- +-#ifdef BOOST_ASIO_HAS_STD_CHRONO +- #define _WEBSOCKETPP_CPP11_CHRONO_ +-#endif +- +-#ifndef BOOST_NO_CXX11_HDR_RANDOM +- #define _WEBSOCKETPP_CPP11_RANDOM_DEVICE_ +-#endif +- +-#ifndef BOOST_NO_CXX11_HDR_REGEX +- #define _WEBSOCKETPP_CPP11_REGEX_ +-#endif +- +-#ifndef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +- #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_ +-#endif +- +-#ifndef BOOST_NO_CXX11_HDR_THREAD +- #define _WEBSOCKETPP_CPP11_THREAD_ +-#endif +- +-#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +- #define _WEBSOCKETPP_INITIALIZER_LISTS_ +-#endif +- +-#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT +-#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR +-// TODO: nullptr support +- +-#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP +diff --git a/src/lib/websocketpp/config/core.hpp b/src/lib/websocketpp/config/core.hpp +deleted file mode 100644 +index ffab7c4..0000000 +--- a/src/lib/websocketpp/config/core.hpp ++++ /dev/null +@@ -1,297 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_CORE_HPP +-#define WEBSOCKETPP_CONFIG_CORE_HPP +- +-// Non-Policy common stuff +-#include +-#include +-#include +- +-// Concurrency +-#include +- +-// Transport +-#include +- +-// HTTP +-#include +-#include +- +-// Messages +-#include +-#include +- +-// Loggers +-#include +-#include +- +-// RNG +-#include +- +-// User stub base classes +-#include +-#include +- +-// Extensions +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Server config with iostream transport +-struct core { +- typedef core type; +- +- // Concurrency policy +- typedef ws_websocketpp::concurrency::basic concurrency_type; +- +- // HTTP Parser Policies +- typedef http::parser::request request_type; +- typedef http::parser::response response_type; +- +- // Message Policies +- typedef message_buffer::message +- message_type; +- typedef message_buffer::alloc::con_msg_manager +- con_msg_manager_type; +- typedef message_buffer::alloc::endpoint_msg_manager +- endpoint_msg_manager_type; +- +- /// Logging policies +- typedef ws_websocketpp::log::basic elog_type; +- typedef ws_websocketpp::log::basic alog_type; +- +- /// RNG policies +- typedef ws_websocketpp::random::none::int_generator rng_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- struct transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::elog_type elog_type; +- typedef type::alog_type alog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- /// Default timer values (in ms) +- +- /// Length of time to wait for socket pre-initialization +- /** +- * Exactly what this includes depends on the socket policy in use +- */ +- static const long timeout_socket_pre_init = 5000; +- +- /// Length of time to wait before a proxy handshake is aborted +- static const long timeout_proxy = 5000; +- +- /// Length of time to wait for socket post-initialization +- /** +- * Exactly what this includes depends on the socket policy in use. +- * Often this means the TLS handshake +- */ +- static const long timeout_socket_post_init = 5000; +- +- /// Length of time to wait for dns resolution +- static const long timeout_dns_resolve = 5000; +- +- /// Length of time to wait for TCP connect +- static const long timeout_connect = 5000; +- +- /// Length of time to wait for socket shutdown +- static const long timeout_socket_shutdown = 5000; +- }; +- +- /// Transport Endpoint Component +- typedef ws_websocketpp::transport::iostream::endpoint +- transport_type; +- +- /// User overridable Endpoint base class +- typedef ws_websocketpp::endpoint_base endpoint_base; +- /// User overridable Connection base class +- typedef ws_websocketpp::connection_base connection_base; +- +- /// Default timer values (in ms) +- +- /// Length of time before an opening handshake is aborted +- static const long timeout_open_handshake = 5000; +- /// Length of time before a closing handshake is aborted +- static const long timeout_close_handshake = 5000; +- /// Length of time to wait for a pong after a ping +- static const long timeout_pong = 5000; +- +- /// WebSocket Protocol version to use as a client +- /** +- * What version of the WebSocket Protocol to use for outgoing client +- * connections. Setting this to a value other than 13 (RFC6455) is not +- * recommended. +- */ +- static const int client_version = 13; // RFC6455 +- +- /// Default static error logging channels +- /** +- * Which error logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level errors +- */ +- static const ws_websocketpp::log::level elog_level = +- ws_websocketpp::log::elevel::all ^ ws_websocketpp::log::elevel::devel; +- +- /// Default static access logging channels +- /** +- * Which access logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level access messages +- */ +- static const ws_websocketpp::log::level alog_level = +- ws_websocketpp::log::alevel::all ^ ws_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. +- /** +- * Drop connections on protocol error rather than sending a close frame. +- * Off by default. This may result in legit messages near the error being +- * dropped as well. It may free up resources otherwise spent dealing with +- * misbehaving clients. +- */ +- static const bool drop_on_protocol_error = false; +- +- /// Suppresses the return of detailed connection close information +- /** +- * Silence close suppresses the return of detailed connection close +- * information during the closing handshake. This information is useful +- * for debugging and presenting useful errors to end users but may be +- * undesirable for security reasons in some production environments. +- * Close reasons could be used by an attacker to confirm that the endpoint +- * is out of resources or be used to identify the WebSocket implementation +- * in use. +- * +- * Note: this will suppress *all* close codes, including those explicitly +- * sent by local applications. +- */ +- static const bool silent_close = false; +- +- /// Default maximum message size +- /** +- * Default value for the processor's maximum message size. Maximum message size +- * determines the point at which the library will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is 32MB +- * +- * @since 0.3.0 +- */ +- static const size_t max_message_size = 32000000; +- +- /// Default maximum http body size +- /** +- * Default value for the http parser's maximum body size. Maximum body size +- * determines the point at which the library will abort reading an HTTP +- * connection with the 413/request entity too large error. +- * +- * The default is 32MB +- * +- * @since 0.5.0 +- */ +- static const size_t max_http_body_size = 32000000; +- +- /// Global flag for enabling/disabling extensions +- static const bool enable_extensions = true; +- +- /// Extension specific settings: +- +- /// permessage_compress extension +- struct permessage_deflate_config { +- typedef core::request_type request_type; +- +- /// If the remote endpoint requests that we reset the compression +- /// context after each message should we honor the request? +- static const bool allow_disabling_context_takeover = true; +- +- /// If the remote endpoint requests that we reduce the size of the +- /// LZ77 sliding window size this is the lowest value that will be +- /// allowed. Values range from 8 to 15. A value of 8 means we will +- /// allow any possible window size. A value of 15 means do not allow +- /// negotiation of the window size (ie require the default). +- static const uint8_t minimum_outgoing_window_bits = 8; +- }; +- +- typedef ws_websocketpp::extensions::permessage_deflate::disabled +- permessage_deflate_type; +- +- /// Autonegotiate permessage-deflate +- /** +- * Automatically enables the permessage-deflate extension. +- * +- * For clients this results in a permessage-deflate extension request being +- * sent with every request rather than requiring it to be requested manually +- * +- * For servers this results in accepting the first set of extension settings +- * requested by the client that we understand being used. The alternative is +- * requiring the extension to be manually negotiated in `validate`. With +- * auto-negotiate on, you may still override the auto-negotiate manually if +- * needed. +- */ +- //static const bool autonegotiate_compression = false; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_CORE_HPP +diff --git a/src/lib/websocketpp/config/core_client.hpp b/src/lib/websocketpp/config/core_client.hpp +deleted file mode 100644 +index 6f683fa..0000000 +--- a/src/lib/websocketpp/config/core_client.hpp ++++ /dev/null +@@ -1,294 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP +-#define WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP +- +-// Non-Policy common stuff +-#include +-#include +-#include +- +-// Concurrency +-#ifndef _WEBSOCKETPP_NO_THREADING_ +-#include +-#else +-#include +-#endif +- +-// Transport +-#include +- +-// HTTP +-#include +-#include +- +-// Messages +-#include +-#include +- +-// Loggers +-#include +- +-// RNG +-#include +- +-// User stub base classes +-#include +-#include +- +-// Extensions +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Client config with iostream transport +-struct core_client { +- typedef core_client type; +- +- // Concurrency policy +-#ifndef _WEBSOCKETPP_NO_THREADING_ +- typedef ws_websocketpp::concurrency::basic concurrency_type; +-#else +- typedef ws_websocketpp::concurrency::none concurrency_type; +-#endif +- +- // HTTP Parser Policies +- typedef http::parser::request request_type; +- typedef http::parser::response response_type; +- +- // Message Policies +- typedef message_buffer::message +- message_type; +- typedef message_buffer::alloc::con_msg_manager +- con_msg_manager_type; +- typedef message_buffer::alloc::endpoint_msg_manager +- endpoint_msg_manager_type; +- +- /// Logging policies +- typedef ws_websocketpp::log::basic elog_type; +- typedef ws_websocketpp::log::basic alog_type; +- +- /// RNG policies +- typedef ws_websocketpp::random::random_device::int_generator rng_type; +- +- /// Controls compile time enabling/disabling of thread syncronization code +- /// Disabling can provide a minor performance improvement to single threaded +- /// applications +- static bool const enable_multithreading = true; +- +- struct transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::elog_type elog_type; +- typedef type::alog_type alog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- /// Default timer values (in ms) +- +- /// Length of time to wait for socket pre-initialization +- /** +- * Exactly what this includes depends on the socket policy in use +- */ +- static const long timeout_socket_pre_init = 5000; +- +- /// Length of time to wait before a proxy handshake is aborted +- static const long timeout_proxy = 5000; +- +- /// Length of time to wait for socket post-initialization +- /** +- * Exactly what this includes depends on the socket policy in use. +- * Often this means the TLS handshake +- */ +- static const long timeout_socket_post_init = 5000; +- +- /// Length of time to wait for dns resolution +- static const long timeout_dns_resolve = 5000; +- +- /// Length of time to wait for TCP connect +- static const long timeout_connect = 5000; +- +- /// Length of time to wait for socket shutdown +- static const long timeout_socket_shutdown = 5000; +- }; +- +- /// Transport Endpoint Component +- typedef ws_websocketpp::transport::iostream::endpoint +- transport_type; +- +- /// User overridable Endpoint base class +- typedef ws_websocketpp::endpoint_base endpoint_base; +- /// User overridable Connection base class +- typedef ws_websocketpp::connection_base connection_base; +- +- /// Default timer values (in ms) +- +- /// Length of time before an opening handshake is aborted +- static const long timeout_open_handshake = 5000; +- /// Length of time before a closing handshake is aborted +- static const long timeout_close_handshake = 5000; +- /// Length of time to wait for a pong after a ping +- static const long timeout_pong = 5000; +- +- /// WebSocket Protocol version to use as a client +- /** +- * What version of the WebSocket Protocol to use for outgoing client +- * connections. Setting this to a value other than 13 (RFC6455) is not +- * recommended. +- */ +- static const int client_version = 13; // RFC6455 +- +- /// Default static error logging channels +- /** +- * Which error logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level errors +- */ +- static const ws_websocketpp::log::level elog_level = +- ws_websocketpp::log::elevel::all ^ ws_websocketpp::log::elevel::devel; +- +- /// Default static access logging channels +- /** +- * Which access logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level access messages +- */ +- static const ws_websocketpp::log::level alog_level = +- ws_websocketpp::log::alevel::all ^ ws_websocketpp::log::alevel::devel; +- +- /// +- static const size_t connection_read_buffer_size = 16384; +- +- /// Drop connections immediately on protocol error. +- /** +- * Drop connections on protocol error rather than sending a close frame. +- * Off by default. This may result in legit messages near the error being +- * dropped as well. It may free up resources otherwise spent dealing with +- * misbehaving clients. +- */ +- static const bool drop_on_protocol_error = false; +- +- /// Suppresses the return of detailed connection close information +- /** +- * Silence close suppresses the return of detailed connection close +- * information during the closing handshake. This information is useful +- * for debugging and presenting useful errors to end users but may be +- * undesirable for security reasons in some production environments. +- * Close reasons could be used by an attacker to confirm that the endpoint +- * is out of resources or be used to identify the WebSocket implementation +- * in use. +- * +- * Note: this will suppress *all* close codes, including those explicitly +- * sent by local applications. +- */ +- static const bool silent_close = false; +- +- /// Default maximum message size +- /** +- * Default value for the processor's maximum message size. Maximum message size +- * determines the point at which the library will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is 32MB +- * +- * @since 0.3.0 +- */ +- static const size_t max_message_size = 32000000; +- +- /// Default maximum http body size +- /** +- * Default value for the http parser's maximum body size. Maximum body size +- * determines the point at which the library will abort reading an HTTP +- * connection with the 413/request entity too large error. +- * +- * The default is 32MB +- * +- * @since 0.5.0 +- */ +- static const size_t max_http_body_size = 32000000; +- +- /// Global flag for enabling/disabling extensions +- static const bool enable_extensions = true; +- +- /// Extension specific settings: +- +- /// permessage_deflate extension +- struct permessage_deflate_config { +- typedef core_client::request_type request_type; +- +- /// If the remote endpoint requests that we reset the compression +- /// context after each message should we honor the request? +- static const bool allow_disabling_context_takeover = true; +- +- /// If the remote endpoint requests that we reduce the size of the +- /// LZ77 sliding window size this is the lowest value that will be +- /// allowed. Values range from 8 to 15. A value of 8 means we will +- /// allow any possible window size. A value of 15 means do not allow +- /// negotiation of the window size (ie require the default). +- static const uint8_t minimum_outgoing_window_bits = 8; +- }; +- +- typedef ws_websocketpp::extensions::permessage_deflate::disabled +- permessage_deflate_type; +- +- /// Autonegotiate permessage-compress +- /** +- * Automatically enables the permessage-compress extension. +- * +- * For clients this results in a permessage-compress extension request being +- * sent with every request rather than requiring it to be requested manually +- * +- * For servers this results in accepting the first set of extension settings +- * requested by the client that we understand being used. The alternative is +- * requiring the extension to be manually negotiated in `validate`. With +- * auto-negotiate on, you may still override the auto-negotiate manually if +- * needed. +- */ +- //static const bool autonegotiate_compression = false; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_CORE_CLIENT_HPP +diff --git a/src/lib/websocketpp/config/debug.hpp b/src/lib/websocketpp/config/debug.hpp +deleted file mode 100644 +index 5bd6b15..0000000 +--- a/src/lib/websocketpp/config/debug.hpp ++++ /dev/null +@@ -1,286 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_DEBUG_HPP +-#define WEBSOCKETPP_CONFIG_DEBUG_HPP +- +- +- +-// Non-Policy common stuff +-#include +-#include +- +-// Concurrency +-#include +- +-// Transport +-#include +- +-// HTTP +-#include +-#include +- +-// Messages +-#include +-#include +- +-// Loggers +-#include +- +-// RNG +-#include +- +-// User stub base classes +-#include +-#include +- +-// Extensions +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Client/Server debug config with iostream transport +-struct debug_core { +- typedef debug_core type; +- +- // Concurrency policy +- typedef ws_websocketpp::concurrency::basic concurrency_type; +- +- // HTTP Parser Policies +- typedef http::parser::request request_type; +- typedef http::parser::response response_type; +- +- // Message Policies +- typedef message_buffer::message +- message_type; +- typedef message_buffer::alloc::con_msg_manager +- con_msg_manager_type; +- typedef message_buffer::alloc::endpoint_msg_manager +- endpoint_msg_manager_type; +- +- /// Logging policies +- typedef ws_websocketpp::log::basic elog_type; +- typedef ws_websocketpp::log::basic alog_type; +- +- /// RNG policies +- typedef ws_websocketpp::random::none::int_generator rng_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- struct transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::elog_type elog_type; +- typedef type::alog_type alog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- /// Default timer values (in ms) +- +- /// Length of time to wait for socket pre-initialization +- /** +- * Exactly what this includes depends on the socket policy in use +- */ +- static const long timeout_socket_pre_init = 5000; +- +- /// Length of time to wait before a proxy handshake is aborted +- static const long timeout_proxy = 5000; +- +- /// Length of time to wait for socket post-initialization +- /** +- * Exactly what this includes depends on the socket policy in use. +- * Often this means the TLS handshake +- */ +- static const long timeout_socket_post_init = 5000; +- +- /// Length of time to wait for dns resolution +- static const long timeout_dns_resolve = 5000; +- +- /// Length of time to wait for TCP connect +- static const long timeout_connect = 5000; +- +- /// Length of time to wait for socket shutdown +- static const long timeout_socket_shutdown = 5000; +- }; +- +- /// Transport Endpoint Component +- typedef ws_websocketpp::transport::iostream::endpoint +- transport_type; +- +- /// User overridable Endpoint base class +- typedef ws_websocketpp::endpoint_base endpoint_base; +- /// User overridable Connection base class +- typedef ws_websocketpp::connection_base connection_base; +- +- /// Default timer values (in ms) +- +- /// Length of time before an opening handshake is aborted +- static const long timeout_open_handshake = 5000; +- /// Length of time before a closing handshake is aborted +- static const long timeout_close_handshake = 5000; +- /// Length of time to wait for a pong after a ping +- static const long timeout_pong = 5000; +- +- /// WebSocket Protocol version to use as a client +- /** +- * What version of the WebSocket Protocol to use for outgoing client +- * connections. Setting this to a value other than 13 (RFC6455) is not +- * recommended. +- */ +- static const int client_version = 13; // RFC6455 +- +- /// Default static error logging channels +- /** +- * Which error logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level errors +- */ +- static const ws_websocketpp::log::level elog_level = +- ws_websocketpp::log::elevel::all; +- +- /// Default static access logging channels +- /** +- * Which access logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level access messages +- */ +- static const ws_websocketpp::log::level alog_level = +- ws_websocketpp::log::alevel::all; +- +- /// +- static const size_t connection_read_buffer_size = 16384; +- +- /// Drop connections immediately on protocol error. +- /** +- * Drop connections on protocol error rather than sending a close frame. +- * Off by default. This may result in legit messages near the error being +- * dropped as well. It may free up resources otherwise spent dealing with +- * misbehaving clients. +- */ +- static const bool drop_on_protocol_error = false; +- +- /// Suppresses the return of detailed connection close information +- /** +- * Silence close suppresses the return of detailed connection close +- * information during the closing handshake. This information is useful +- * for debugging and presenting useful errors to end users but may be +- * undesirable for security reasons in some production environments. +- * Close reasons could be used by an attacker to confirm that the endpoint +- * is out of resources or be used to identify the WebSocket implementation +- * in use. +- * +- * Note: this will suppress *all* close codes, including those explicitly +- * sent by local applications. +- */ +- static const bool silent_close = false; +- +- /// Default maximum message size +- /** +- * Default value for the processor's maximum message size. Maximum message size +- * determines the point at which the library will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is 32MB +- * +- * @since 0.3.0 +- */ +- static const size_t max_message_size = 32000000; +- +- /// Default maximum http body size +- /** +- * Default value for the http parser's maximum body size. Maximum body size +- * determines the point at which the library will abort reading an HTTP +- * connection with the 413/request entity too large error. +- * +- * The default is 32MB +- * +- * @since 0.5.0 +- */ +- static const size_t max_http_body_size = 32000000; +- +- /// Global flag for enabling/disabling extensions +- static const bool enable_extensions = true; +- +- /// Extension specific settings: +- +- /// permessage_compress extension +- struct permessage_deflate_config { +- typedef type::request_type request_type; +- +- /// If the remote endpoint requests that we reset the compression +- /// context after each message should we honor the request? +- static const bool allow_disabling_context_takeover = true; +- +- /// If the remote endpoint requests that we reduce the size of the +- /// LZ77 sliding window size this is the lowest value that will be +- /// allowed. Values range from 8 to 15. A value of 8 means we will +- /// allow any possible window size. A value of 15 means do not allow +- /// negotiation of the window size (ie require the default). +- static const uint8_t minimum_outgoing_window_bits = 8; +- }; +- +- typedef ws_websocketpp::extensions::permessage_deflate::disabled +- permessage_deflate_type; +- +- /// Autonegotiate permessage-deflate +- /** +- * Automatically enables the permessage-deflate extension. +- * +- * For clients this results in a permessage-deflate extension request being +- * sent with every request rather than requiring it to be requested manually +- * +- * For servers this results in accepting the first set of extension settings +- * requested by the client that we understand being used. The alternative is +- * requiring the extension to be manually negotiated in `validate`. With +- * auto-negotiate on, you may still override the auto-negotiate manually if +- * needed. +- */ +- //static const bool autonegotiate_compression = false; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_CORE_HPP +diff --git a/src/lib/websocketpp/config/debug_asio.hpp b/src/lib/websocketpp/config/debug_asio.hpp +deleted file mode 100644 +index 63c72da..0000000 +--- a/src/lib/websocketpp/config/debug_asio.hpp ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP +- +-#include +-#include +-#include +- +-// Pull in non-tls config +-#include +- +-// Define TLS config +-namespace ws_websocketpp { +-namespace config { +- +-/// Client/Server debug config with asio transport and TLS enabled +-struct debug_asio_tls : public debug_core { +- typedef debug_asio_tls type; +- typedef debug_core base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::tls_socket::endpoint socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_TLS_DEBUG_HPP +diff --git a/src/lib/websocketpp/config/debug_asio_no_tls.hpp b/src/lib/websocketpp/config/debug_asio_no_tls.hpp +deleted file mode 100644 +index c8ab743..0000000 +--- a/src/lib/websocketpp/config/debug_asio_no_tls.hpp ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP +-#define WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Client/Server debug config with asio transport and TLS disabled +-struct debug_asio : public debug_core { +- typedef debug_asio type; +- typedef debug_core base; +- +- typedef base::concurrency_type concurrency_type; +- +- typedef base::request_type request_type; +- typedef base::response_type response_type; +- +- typedef base::message_type message_type; +- typedef base::con_msg_manager_type con_msg_manager_type; +- typedef base::endpoint_msg_manager_type endpoint_msg_manager_type; +- +- typedef base::alog_type alog_type; +- typedef base::elog_type elog_type; +- +- typedef base::rng_type rng_type; +- +- struct transport_config : public base::transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::alog_type alog_type; +- typedef type::elog_type elog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- typedef ws_websocketpp::transport::asio::basic_socket::endpoint +- socket_type; +- }; +- +- typedef ws_websocketpp::transport::asio::endpoint +- transport_type; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_ASIO_DEBUG_HPP +diff --git a/src/lib/websocketpp/config/minimal_client.hpp b/src/lib/websocketpp/config/minimal_client.hpp +deleted file mode 100644 +index 6d09d58..0000000 +--- a/src/lib/websocketpp/config/minimal_client.hpp ++++ /dev/null +@@ -1,72 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP +-#define WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP +- +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Client config with minimal dependencies +-/** +- * This config strips out as many dependencies as possible. It is suitable for +- * use as a base class for custom configs that want to implement or choose their +- * own policies for components that even the core config includes. +- * +- * NOTE: this config stubs out enough that it cannot be used directly. You must +- * supply at least a transport policy and a cryptographically secure random +- * number generation policy for a config based on `minimal_client` to do +- * anything useful. +- * +- * Present dependency list for minimal_server config: +- * +- * C++98 STL: +- * +- * +- * +- * +- * +- * +- * C++11 STL or Boost +- * +- * +- * +- * +- * Operating System: +- * or +- * or (for ntohl.. could potentially bundle this) +- * +- * @since 0.4.0-dev +- */ +-typedef minimal_server minimal_client; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP +diff --git a/src/lib/websocketpp/config/minimal_server.hpp b/src/lib/websocketpp/config/minimal_server.hpp +deleted file mode 100644 +index 1252403..0000000 +--- a/src/lib/websocketpp/config/minimal_server.hpp ++++ /dev/null +@@ -1,312 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONFIG_MINIMAL_HPP +-#define WEBSOCKETPP_CONFIG_MINIMAL_HPP +- +-// Non-Policy common stuff +-#include +-#include +-#include +- +-// Concurrency +-#include +- +-// Transport +-#include +- +-// HTTP +-#include +-#include +- +-// Messages +-#include +-#include +- +-// Loggers +-#include +- +-// RNG +-#include +- +-// User stub base classes +-#include +-#include +- +-// Extensions +-#include +- +-namespace ws_websocketpp { +-namespace config { +- +-/// Server config with minimal dependencies +-/** +- * This config strips out as many dependencies as possible. It is suitable for +- * use as a base class for custom configs that want to implement or choose their +- * own policies for components that even the core config includes. +- * +- * NOTE: this config stubs out enough that it cannot be used directly. You must +- * supply at least a transport policy for a config based on `minimal_server` to +- * do anything useful. +- * +- * Present dependency list for minimal_server config: +- * +- * C++98 STL: +- * +- * +- * +- * +- * +- * +- * C++11 STL or Boost +- * +- * +- * +- * +- * Operating System: +- * or +- * or (for ntohl.. could potentially bundle this) +- * +- * @since 0.4.0-dev +- */ +-struct minimal_server { +- typedef minimal_server type; +- +- // Concurrency policy +- typedef ws_websocketpp::concurrency::none concurrency_type; +- +- // HTTP Parser Policies +- typedef http::parser::request request_type; +- typedef http::parser::response response_type; +- +- // Message Policies +- typedef message_buffer::message +- message_type; +- typedef message_buffer::alloc::con_msg_manager +- con_msg_manager_type; +- typedef message_buffer::alloc::endpoint_msg_manager +- endpoint_msg_manager_type; +- +- /// Logging policies +- typedef ws_websocketpp::log::stub elog_type; +- typedef ws_websocketpp::log::stub alog_type; +- +- /// RNG policies +- typedef ws_websocketpp::random::none::int_generator rng_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- struct transport_config { +- typedef type::concurrency_type concurrency_type; +- typedef type::elog_type elog_type; +- typedef type::alog_type alog_type; +- typedef type::request_type request_type; +- typedef type::response_type response_type; +- +- /// Controls compile time enabling/disabling of thread syncronization +- /// code Disabling can provide a minor performance improvement to single +- /// threaded applications +- static bool const enable_multithreading = true; +- +- /// Default timer values (in ms) +- +- /// Length of time to wait for socket pre-initialization +- /** +- * Exactly what this includes depends on the socket policy in use +- */ +- static const long timeout_socket_pre_init = 5000; +- +- /// Length of time to wait before a proxy handshake is aborted +- static const long timeout_proxy = 5000; +- +- /// Length of time to wait for socket post-initialization +- /** +- * Exactly what this includes depends on the socket policy in use. +- * Often this means the TLS handshake +- */ +- static const long timeout_socket_post_init = 5000; +- +- /// Length of time to wait for dns resolution +- static const long timeout_dns_resolve = 5000; +- +- /// Length of time to wait for TCP connect +- static const long timeout_connect = 5000; +- +- /// Length of time to wait for socket shutdown +- static const long timeout_socket_shutdown = 5000; +- }; +- +- /// Transport Endpoint Component +- typedef ws_websocketpp::transport::stub::endpoint +- transport_type; +- +- /// User overridable Endpoint base class +- typedef ws_websocketpp::endpoint_base endpoint_base; +- /// User overridable Connection base class +- typedef ws_websocketpp::connection_base connection_base; +- +- /// Default timer values (in ms) +- +- /// Length of time before an opening handshake is aborted +- static const long timeout_open_handshake = 5000; +- /// Length of time before a closing handshake is aborted +- static const long timeout_close_handshake = 5000; +- /// Length of time to wait for a pong after a ping +- static const long timeout_pong = 5000; +- +- /// WebSocket Protocol version to use as a client +- /** +- * What version of the WebSocket Protocol to use for outgoing client +- * connections. Setting this to a value other than 13 (RFC6455) is not +- * recommended. +- */ +- static const int client_version = 13; // RFC6455 +- +- /// Default static error logging channels +- /** +- * Which error logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level errors +- */ +- static const ws_websocketpp::log::level elog_level = +- ws_websocketpp::log::elevel::none; +- +- /// Default static access logging channels +- /** +- * Which access logging channels to enable at compile time. Channels not +- * enabled here will be unable to be selected by programs using the library. +- * This option gives an optimizing compiler the ability to remove entirely +- * code to test whether or not to print out log messages on a certain +- * channel +- * +- * Default is all except for development/debug level access messages +- */ +- static const ws_websocketpp::log::level alog_level = +- ws_websocketpp::log::alevel::none; +- +- /// +- static const size_t connection_read_buffer_size = 16384; +- +- /// Drop connections immediately on protocol error. +- /** +- * Drop connections on protocol error rather than sending a close frame. +- * Off by default. This may result in legit messages near the error being +- * dropped as well. It may free up resources otherwise spent dealing with +- * misbehaving clients. +- */ +- static const bool drop_on_protocol_error = false; +- +- /// Suppresses the return of detailed connection close information +- /** +- * Silence close suppresses the return of detailed connection close +- * information during the closing handshake. This information is useful +- * for debugging and presenting useful errors to end users but may be +- * undesirable for security reasons in some production environments. +- * Close reasons could be used by an attacker to confirm that the endpoint +- * is out of resources or be used to identify the WebSocket implementation +- * in use. +- * +- * Note: this will suppress *all* close codes, including those explicitly +- * sent by local applications. +- */ +- static const bool silent_close = false; +- +- /// Default maximum message size +- /** +- * Default value for the processor's maximum message size. Maximum message size +- * determines the point at which the library will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is 32MB +- * +- * @since 0.4.0-alpha1 +- */ +- static const size_t max_message_size = 32000000; +- +- /// Default maximum http body size +- /** +- * Default value for the http parser's maximum body size. Maximum body size +- * determines the point at which the library will abort reading an HTTP +- * connection with the 413/request entity too large error. +- * +- * The default is 32MB +- * +- * @since 0.5.0 +- */ +- static const size_t max_http_body_size = 32000000; +- +- /// Global flag for enabling/disabling extensions +- static const bool enable_extensions = true; +- +- /// Extension specific settings: +- +- /// permessage_compress extension +- struct permessage_deflate_config { +- typedef core::request_type request_type; +- +- /// If the remote endpoint requests that we reset the compression +- /// context after each message should we honor the request? +- static const bool allow_disabling_context_takeover = true; +- +- /// If the remote endpoint requests that we reduce the size of the +- /// LZ77 sliding window size this is the lowest value that will be +- /// allowed. Values range from 8 to 15. A value of 8 means we will +- /// allow any possible window size. A value of 15 means do not allow +- /// negotiation of the window size (ie require the default). +- static const uint8_t minimum_outgoing_window_bits = 8; +- }; +- +- typedef ws_websocketpp::extensions::permessage_deflate::disabled +- permessage_deflate_type; +- +- /// Autonegotiate permessage-deflate +- /** +- * Automatically enables the permessage-deflate extension. +- * +- * For clients this results in a permessage-deflate extension request being +- * sent with every request rather than requiring it to be requested manually +- * +- * For servers this results in accepting the first set of extension settings +- * requested by the client that we understand being used. The alternative is +- * requiring the extension to be manually negotiated in `validate`. With +- * auto-negotiate on, you may still override the auto-negotiate manually if +- * needed. +- */ +- //static const bool autonegotiate_compression = false; +-}; +- +-} // namespace config +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONFIG_MINIMAL_HPP +diff --git a/src/lib/websocketpp/connection.hpp b/src/lib/websocketpp/connection.hpp +deleted file mode 100644 +index f679152..0000000 +--- a/src/lib/websocketpp/connection.hpp ++++ /dev/null +@@ -1,1642 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONNECTION_HPP +-#define WEBSOCKETPP_CONNECTION_HPP +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +- +-/// The type and function signature of an open handler +-/** +- * The open handler is called once for every successful WebSocket connection +- * attempt. Either the fail handler or the open handler will be called for each +- * WebSocket connection attempt. HTTP Connections that did not attempt to +- * upgrade the connection to the WebSocket protocol will trigger the http +- * handler instead of fail/open. +- */ +-typedef lib::function open_handler; +- +-/// The type and function signature of a close handler +-/** +- * The close handler is called once for every successfully established +- * connection after it is no longer capable of sending or receiving new messages +- * +- * The close handler will be called exactly once for every connection for which +- * the open handler was called. +- */ +-typedef lib::function close_handler; +- +-/// The type and function signature of a fail handler +-/** +- * The fail handler is called once for every unsuccessful WebSocket connection +- * attempt. Either the fail handler or the open handler will be called for each +- * WebSocket connection attempt. HTTP Connections that did not attempt to +- * upgrade the connection to the WebSocket protocol will trigger the http +- * handler instead of fail/open. +- */ +-typedef lib::function fail_handler; +- +-/// The type and function signature of an interrupt handler +-/** +- * The interrupt handler is called when a connection receives an interrupt +- * request from the application. Interrupts allow the application to trigger a +- * handler to be run in the absense of a WebSocket level handler trigger (like +- * a new message). +- * +- * This is typically used by another application thread to schedule some tasks +- * that can only be run from within the handler chain for thread safety reasons. +- */ +-typedef lib::function interrupt_handler; +- +-/// The type and function signature of a ping handler +-/** +- * The ping handler is called when the connection receives a WebSocket ping +- * control frame. The string argument contains the ping payload. The payload is +- * a binary string up to 126 bytes in length. The ping handler returns a bool, +- * true if a pong response should be sent, false if the pong response should be +- * suppressed. +- */ +-typedef lib::function ping_handler; +- +-/// The type and function signature of a pong handler +-/** +- * The pong handler is called when the connection receives a WebSocket pong +- * control frame. The string argument contains the pong payload. The payload is +- * a binary string up to 126 bytes in length. +- */ +-typedef lib::function pong_handler; +- +-/// The type and function signature of a pong timeout handler +-/** +- * The pong timeout handler is called when a ping goes unanswered by a pong for +- * longer than the locally specified timeout period. +- */ +-typedef lib::function pong_timeout_handler; +- +-/// The type and function signature of a validate handler +-/** +- * The validate handler is called after a WebSocket handshake has been received +- * and processed but before it has been accepted. This gives the application a +- * chance to implement connection details specific policies for accepting +- * connections and the ability to negotiate extensions and subprotocols. +- * +- * The validate handler return value indicates whether or not the connection +- * should be accepted. Additional methods may be called during the function to +- * set response headers, set HTTP return/error codes, etc. +- */ +-typedef lib::function validate_handler; +- +-/// The type and function signature of a http handler +-/** +- * The http handler is called when an HTTP connection is made that does not +- * attempt to upgrade the connection to the WebSocket protocol. This allows +- * WebSocket++ servers to respond to these requests with regular HTTP responses. +- * +- * This can be used to deliver error pages & dashboards and to deliver static +- * files such as the base HTML & JavaScript for an otherwise single page +- * WebSocket application. +- * +- * Note: WebSocket++ is designed to be a high performance WebSocket server. It +- * is not tuned to provide a full featured, high performance, HTTP web server +- * solution. The HTTP handler is appropriate only for low volume HTTP traffic. +- * If you expect to serve high volumes of HTTP traffic a dedicated HTTP web +- * server is strongly recommended. +- * +- * The default HTTP handler will return a 426 Upgrade Required error. Custom +- * handlers may override the response status code to deliver any type of +- * response. +- */ +-typedef lib::function http_handler; +- +-// +-typedef lib::function read_handler; +-typedef lib::function write_frame_handler; +- +-// constants related to the default WebSocket protocol versions available +-#ifdef _WEBSOCKETPP_INITIALIZER_LISTS_ // simplified C++11 version +- /// Container that stores the list of protocol versions supported +- /** +- * @todo Move this to configs to allow compile/runtime disabling or enabling +- * of protocol versions +- */ +- static std::vector const versions_supported = {0,7,8,13}; +-#else +- /// Helper array to get around lack of initializer lists pre C++11 +- static int const helper[] = {0,7,8,13}; +- /// Container that stores the list of protocol versions supported +- /** +- * @todo Move this to configs to allow compile/runtime disabling or enabling +- * of protocol versions +- */ +- static std::vector const versions_supported(helper,helper+4); +-#endif +- +-namespace session { +-namespace state { +- // externally visible session state (states based on the RFC) +- enum value { +- connecting = 0, +- open = 1, +- closing = 2, +- closed = 3 +- }; +-} // namespace state +- +- +-namespace fail { +-namespace status { +- enum value { +- GOOD = 0, // no failure yet! +- SYSTEM = 1, // system call returned error, check that code +- WEBSOCKET = 2, // websocket close codes contain error +- UNKNOWN = 3, // No failure information is available +- TIMEOUT_TLS = 4, // TLS handshake timed out +- TIMEOUT_WS = 5 // WS handshake timed out +- }; +-} // namespace status +-} // namespace fail +- +-namespace internal_state { +- // More granular internal states. These are used for multi-threaded +- // connection synchronization and preventing values that are not yet or no +- // longer available from being used. +- +- enum value { +- USER_INIT = 0, +- TRANSPORT_INIT = 1, +- READ_HTTP_REQUEST = 2, +- WRITE_HTTP_REQUEST = 3, +- READ_HTTP_RESPONSE = 4, +- WRITE_HTTP_RESPONSE = 5, +- PROCESS_HTTP_REQUEST = 6, +- PROCESS_CONNECTION = 7 +- }; +-} // namespace internal_state +- +- +-namespace http_state { +- // states to keep track of the progress of http connections +- +- enum value { +- init = 0, +- deferred = 1, +- headers_written = 2, +- body_written = 3, +- closed = 4 +- }; +-} // namespace http_state +- +-} // namespace session +- +-/// Represents an individual WebSocket connection +-template +-class connection +- : public config::transport_type::transport_con_type +- , public config::connection_base +-{ +-public: +- /// Type of this connection +- typedef connection type; +- /// Type of a shared pointer to this connection +- typedef lib::shared_ptr ptr; +- /// Type of a weak pointer to this connection +- typedef lib::weak_ptr weak_ptr; +- +- /// Type of the concurrency component of this connection +- typedef typename config::concurrency_type concurrency_type; +- /// Type of the access logging policy +- typedef typename config::alog_type alog_type; +- /// Type of the error logging policy +- typedef typename config::elog_type elog_type; +- +- /// Type of the transport component of this connection +- typedef typename config::transport_type::transport_con_type +- transport_con_type; +- /// Type of a shared pointer to the transport component of this connection +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- typedef lib::function termination_handler; +- +- typedef typename concurrency_type::scoped_lock_type scoped_lock_type; +- typedef typename concurrency_type::mutex_type mutex_type; +- +- typedef typename config::request_type request_type; +- typedef typename config::response_type response_type; +- +- typedef typename config::message_type message_type; +- typedef typename message_type::ptr message_ptr; +- +- typedef typename config::con_msg_manager_type con_msg_manager_type; +- typedef typename con_msg_manager_type::ptr con_msg_manager_ptr; +- +- /// Type of RNG +- typedef typename config::rng_type rng_type; +- +- typedef processor::processor processor_type; +- typedef lib::shared_ptr processor_ptr; +- +- // Message handler (needs to know message type) +- typedef lib::function message_handler; +- +- /// Type of a pointer to a transport timer handle +- typedef typename transport_con_type::timer_ptr timer_ptr; +- +- // Misc Convenience Types +- typedef session::internal_state::value istate_type; +- +-private: +- enum terminate_status { +- failed = 1, +- closed, +- unknown +- }; +-public: +- +- explicit connection(bool p_is_server, std::string const & ua, const lib::shared_ptr& alog, +- const lib::shared_ptr& elog, rng_type & rng) +- : transport_con_type(p_is_server, alog, elog) +- , m_handle_read_frame(lib::bind( +- &type::handle_read_frame, +- this, +- lib::placeholders::_1, +- lib::placeholders::_2 +- )) +- , m_write_frame_handler(lib::bind( +- &type::handle_write_frame, +- this, +- lib::placeholders::_1 +- )) +- , m_user_agent(ua) +- , m_open_handshake_timeout_dur(config::timeout_open_handshake) +- , m_close_handshake_timeout_dur(config::timeout_close_handshake) +- , m_pong_timeout_dur(config::timeout_pong) +- , m_max_message_size(config::max_message_size) +- , m_state(session::state::connecting) +- , m_internal_state(session::internal_state::USER_INIT) +- , m_msg_manager(new con_msg_manager_type()) +- , m_send_buffer_size(0) +- , m_write_flag(false) +- , m_read_flag(true) +- , m_is_server(p_is_server) +- , m_alog(alog) +- , m_elog(elog) +- , m_rng(rng) +- , m_local_close_code(close::status::abnormal_close) +- , m_remote_close_code(close::status::abnormal_close) +- , m_is_http(false) +- , m_http_state(session::http_state::init) +- , m_was_clean(false) +- { +- m_alog->write(log::alevel::devel,"connection constructor"); +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return lib::static_pointer_cast(transport_con_type::get_shared()); +- } +- +- /////////////////////////// +- // Set Handler Callbacks // +- /////////////////////////// +- +- /// Set open handler +- /** +- * The open handler is called after the WebSocket handshake is complete and +- * the connection is considered OPEN. +- * +- * @param h The new open_handler +- */ +- void set_open_handler(open_handler h) { +- m_open_handler = h; +- } +- +- /// Set close handler +- /** +- * The close handler is called immediately after the connection is closed. +- * +- * @param h The new close_handler +- */ +- void set_close_handler(close_handler h) { +- m_close_handler = h; +- } +- +- /// Set fail handler +- /** +- * The fail handler is called whenever the connection fails while the +- * handshake is bring processed. +- * +- * @param h The new fail_handler +- */ +- void set_fail_handler(fail_handler h) { +- m_fail_handler = h; +- } +- +- /// Set ping handler +- /** +- * The ping handler is called whenever the connection receives a ping +- * control frame. The ping payload is included. +- * +- * The ping handler's return time controls whether or not a pong is +- * sent in response to this ping. Returning false will suppress the +- * return pong. If no ping handler is set a pong will be sent. +- * +- * @param h The new ping_handler +- */ +- void set_ping_handler(ping_handler h) { +- m_ping_handler = h; +- } +- +- /// Set pong handler +- /** +- * The pong handler is called whenever the connection receives a pong +- * control frame. The pong payload is included. +- * +- * @param h The new pong_handler +- */ +- void set_pong_handler(pong_handler h) { +- m_pong_handler = h; +- } +- +- /// Set pong timeout handler +- /** +- * If the transport component being used supports timers, the pong timeout +- * handler is called whenever a pong control frame is not received with the +- * configured timeout period after the application sends a ping. +- * +- * The config setting `timeout_pong` controls the length of the timeout +- * period. It is specified in milliseconds. +- * +- * This can be used to probe the health of the remote endpoint's WebSocket +- * implementation. This does not guarantee that the remote application +- * itself is still healthy but can be a useful diagnostic. +- * +- * Note: receipt of this callback doesn't mean the pong will never come. +- * This functionality will not suppress delivery of the pong in question +- * should it arrive after the timeout. +- * +- * @param h The new pong_timeout_handler +- */ +- void set_pong_timeout_handler(pong_timeout_handler h) { +- m_pong_timeout_handler = h; +- } +- +- /// Set interrupt handler +- /** +- * The interrupt handler is called whenever the connection is manually +- * interrupted by the application. +- * +- * @param h The new interrupt_handler +- */ +- void set_interrupt_handler(interrupt_handler h) { +- m_interrupt_handler = h; +- } +- +- /// Set http handler +- /** +- * The http handler is called after an HTTP request other than a WebSocket +- * upgrade request is received. It allows a WebSocket++ server to respond +- * to regular HTTP requests on the same port as it processes WebSocket +- * connections. This can be useful for hosting error messages, flash +- * policy files, status pages, and other simple HTTP responses. It is not +- * intended to be used as a primary web server. +- * +- * @param h The new http_handler +- */ +- void set_http_handler(http_handler h) { +- m_http_handler = h; +- } +- +- /// Set validate handler +- /** +- * The validate handler is called after a WebSocket handshake has been +- * parsed but before a response is returned. It provides the application +- * a chance to examine the request and determine whether or not it wants +- * to accept the connection. +- * +- * Returning false from the validate handler will reject the connection. +- * If no validate handler is present, all connections will be allowed. +- * +- * @param h The new validate_handler +- */ +- void set_validate_handler(validate_handler h) { +- m_validate_handler = h; +- } +- +- /// Set message handler +- /** +- * The message handler is called after a new message has been received. +- * +- * @param h The new message_handler +- */ +- void set_message_handler(message_handler h) { +- m_message_handler = h; +- } +- +- ////////////////////////////////////////// +- // Connection timeouts and other limits // +- ////////////////////////////////////////// +- +- /// Set open handshake timeout +- /** +- * Sets the length of time the library will wait after an opening handshake +- * has been initiated before cancelling it. This can be used to prevent +- * excessive wait times for outgoing clients or excessive resource usage +- * from broken clients or DoS attacks on servers. +- * +- * Connections that time out will have their fail handlers called with the +- * open_handshake_timeout error code. +- * +- * The default value is specified via the compile time config value +- * 'timeout_open_handshake'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the open handshake timeout in ms +- */ +- void set_open_handshake_timeout(long dur) { +- m_open_handshake_timeout_dur = dur; +- } +- +- /// Set close handshake timeout +- /** +- * Sets the length of time the library will wait after a closing handshake +- * has been initiated before cancelling it. This can be used to prevent +- * excessive wait times for outgoing clients or excessive resource usage +- * from broken clients or DoS attacks on servers. +- * +- * Connections that time out will have their close handlers called with the +- * close_handshake_timeout error code. +- * +- * The default value is specified via the compile time config value +- * 'timeout_close_handshake'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the close handshake timeout in ms +- */ +- void set_close_handshake_timeout(long dur) { +- m_close_handshake_timeout_dur = dur; +- } +- +- /// Set pong timeout +- /** +- * Sets the length of time the library will wait for a pong response to a +- * ping. This can be used as a keepalive or to detect broken connections. +- * +- * Pong responses that time out will have the pong timeout handler called. +- * +- * The default value is specified via the compile time config value +- * 'timeout_pong'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the pong timeout in ms +- */ +- void set_pong_timeout(long dur) { +- m_pong_timeout_dur = dur; +- } +- +- /// Get maximum message size +- /** +- * Get maximum message size. Maximum message size determines the point at +- * which the connection will fail with the message_too_big protocol error. +- * +- * The default is set by the endpoint that creates the connection. +- * +- * @since 0.3.0 +- */ +- size_t get_max_message_size() const { +- return m_max_message_size; +- } +- +- /// Set maximum message size +- /** +- * Set maximum message size. Maximum message size determines the point at +- * which the connection will fail with the message_too_big protocol error. +- * This value may be changed during the connection. +- * +- * The default is set by the endpoint that creates the connection. +- * +- * @since 0.3.0 +- * +- * @param new_value The value to set as the maximum message size. +- */ +- void set_max_message_size(size_t new_value) { +- m_max_message_size = new_value; +- if (m_processor) { +- m_processor->set_max_message_size(new_value); +- } +- } +- +- /// Get maximum HTTP message body size +- /** +- * Get maximum HTTP message body size. Maximum message body size determines +- * the point at which the connection will stop reading an HTTP request whose +- * body is too large. +- * +- * The default is set by the endpoint that creates the connection. +- * +- * @since 0.5.0 +- * +- * @return The maximum HTTP message body size +- */ +- size_t get_max_http_body_size() const { +- return m_request.get_max_body_size(); +- } +- +- /// Set maximum HTTP message body size +- /** +- * Set maximum HTTP message body size. Maximum message body size determines +- * the point at which the connection will stop reading an HTTP request whose +- * body is too large. +- * +- * The default is set by the endpoint that creates the connection. +- * +- * @since 0.5.0 +- * +- * @param new_value The value to set as the maximum message size. +- */ +- void set_max_http_body_size(size_t new_value) { +- m_request.set_max_body_size(new_value); +- } +- +- ////////////////////////////////// +- // Uncategorized public methods // +- ////////////////////////////////// +- +- /// Get the size of the outgoing write buffer (in payload bytes) +- /** +- * Retrieves the number of bytes in the outgoing write buffer that have not +- * already been dispatched to the transport layer. This represents the bytes +- * that are presently cancelable without uncleanly ending the websocket +- * connection +- * +- * This method invokes the m_write_lock mutex +- * +- * @return The current number of bytes in the outgoing send buffer. +- */ +- size_t get_buffered_amount() const; +- +- /// Get the size of the outgoing write buffer (in payload bytes) +- /** +- * @deprecated use `get_buffered_amount` instead +- */ +- size_t buffered_amount() const { +- return get_buffered_amount(); +- } +- +- //////////////////// +- // Action Methods // +- //////////////////// +- +- /// Create a message and then add it to the outgoing send queue +- /** +- * Convenience method to send a message given a payload string and +- * optionally an opcode. Default opcode is utf8 text. +- * +- * This method locks the m_write_lock mutex +- * +- * @param payload The payload string to generated the message with +- * +- * @param op The opcode to generated the message with. Default is +- * frame::opcode::text +- */ +- lib::error_code send(std::string const & payload, frame::opcode::value op = +- frame::opcode::text); +- +- /// Send a message (raw array overload) +- /** +- * Convenience method to send a message given a raw array and optionally an +- * opcode. Default opcode is binary. +- * +- * This method locks the m_write_lock mutex +- * +- * @param payload A pointer to the array containing the bytes to send. +- * +- * @param len Length of the array. +- * +- * @param op The opcode to generated the message with. Default is +- * frame::opcode::binary +- */ +- lib::error_code send(void const * payload, size_t len, frame::opcode::value +- op = frame::opcode::binary); +- +- /// Add a message to the outgoing send queue +- /** +- * If presented with a prepared message it is added without validation or +- * framing. If presented with an unprepared message it is validated, framed, +- * and then added +- * +- * Errors are returned via an exception +- * \todo make exception system_error rather than error_code +- * +- * This method invokes the m_write_lock mutex +- * +- * @param msg A message_ptr to the message to send. +- */ +- lib::error_code send(message_ptr msg); +- +- /// Asyncronously invoke handler::on_inturrupt +- /** +- * Signals to the connection to asyncronously invoke the on_inturrupt +- * callback for this connection's handler once it is safe to do so. +- * +- * When the on_inturrupt handler callback is called it will be from +- * within the transport event loop with all the thread safety features +- * guaranteed by the transport to regular handlers +- * +- * Multiple inturrupt signals can be active at once on the same connection +- * +- * @return An error code +- */ +- lib::error_code interrupt(); +- +- /// Transport inturrupt callback +- void handle_interrupt(); +- +- /// Pause reading of new data +- /** +- * Signals to the connection to halt reading of new data. While reading is paused, +- * the connection will stop reading from its associated socket. In turn this will +- * result in TCP based flow control kicking in and slowing data flow from the remote +- * endpoint. +- * +- * This is useful for applications that push new requests to a queue to be processed +- * by another thread and need a way to signal when their request queue is full without +- * blocking the network processing thread. +- * +- * Use `resume_reading()` to resume. +- * +- * If supported by the transport this is done asynchronously. As such reading may not +- * stop until the current read operation completes. Typically you can expect to +- * receive no more bytes after initiating a read pause than the size of the read +- * buffer. +- * +- * If reading is paused for this connection already nothing is changed. +- */ +- lib::error_code pause_reading(); +- +- /// Pause reading callback +- void handle_pause_reading(); +- +- /// Resume reading of new data +- /** +- * Signals to the connection to resume reading of new data after it was paused by +- * `pause_reading()`. +- * +- * If reading is not paused for this connection already nothing is changed. +- */ +- lib::error_code resume_reading(); +- +- /// Resume reading callback +- void handle_resume_reading(); +- +- /// Send a ping +- /** +- * Initiates a ping with the given payload/ +- * +- * There is no feedback directly from ping except in cases of immediately +- * detectable errors. Feedback will be provided via on_pong or +- * on_pong_timeout callbacks. +- * +- * Ping locks the m_write_lock mutex +- * +- * @param payload Payload to be used for the ping +- */ +- void ping(std::string const & payload); +- +- /// exception free variant of ping +- void ping(std::string const & payload, lib::error_code & ec); +- +- /// Utility method that gets called back when the ping timer expires +- void handle_pong_timeout(std::string payload, lib::error_code const & ec); +- +- /// Send a pong +- /** +- * Initiates a pong with the given payload. +- * +- * There is no feedback from a pong once sent. +- * +- * Pong locks the m_write_lock mutex +- * +- * @param payload Payload to be used for the pong +- */ +- void pong(std::string const & payload); +- +- /// exception free variant of pong +- void pong(std::string const & payload, lib::error_code & ec); +- +- /// Close the connection +- /** +- * Initiates the close handshake process. +- * +- * If close returns successfully the connection will be in the closing +- * state and no additional messages may be sent. All messages sent prior +- * to calling close will be written out before the connection is closed. +- * +- * If no reason is specified none will be sent. If no code is specified +- * then no code will be sent. +- * +- * The handler's on_close callback will be called once the close handshake +- * is complete. +- * +- * Reasons will be automatically truncated to the maximum length (123 bytes) +- * if necessary. +- * +- * @param code The close code to send +- * @param reason The close reason to send +- */ +- void close(close::status::value const code, std::string const & reason); +- +- /// exception free variant of close +- void close(close::status::value const code, std::string const & reason, +- lib::error_code & ec); +- +- //////////////////////////////////////////////// +- // Pass-through access to the uri information // +- //////////////////////////////////////////////// +- +- /// Returns the secure flag from the connection URI +- /** +- * This value is available after the HTTP request has been fully read and +- * may be called from any thread. +- * +- * @return Whether or not the connection URI is flagged secure. +- */ +- bool get_secure() const; +- +- /// Returns the host component of the connection URI +- /** +- * This value is available after the HTTP request has been fully read and +- * may be called from any thread. +- * +- * @return The host component of the connection URI +- */ +- std::string const & get_host() const; +- +- /// Returns the resource component of the connection URI +- /** +- * This value is available after the HTTP request has been fully read and +- * may be called from any thread. +- * +- * @return The resource component of the connection URI +- */ +- std::string const & get_resource() const; +- +- /// Returns the port component of the connection URI +- /** +- * This value is available after the HTTP request has been fully read and +- * may be called from any thread. +- * +- * @return The port component of the connection URI +- */ +- uint16_t get_port() const; +- +- /// Gets the connection URI +- /** +- * This should really only be called by internal library methods unless you +- * really know what you are doing. +- * +- * @return A pointer to the connection's URI +- */ +- uri_ptr get_uri() const; +- +- /// Sets the connection URI +- /** +- * This should really only be called by internal library methods unless you +- * really know what you are doing. +- * +- * @param uri The new URI to set +- */ +- void set_uri(uri_ptr uri); +- +- ///////////////////////////// +- // Subprotocol negotiation // +- ///////////////////////////// +- +- /// Gets the negotated subprotocol +- /** +- * Retrieves the subprotocol that was negotiated during the handshake. This +- * method is valid in the open handler and later. +- * +- * @return The negotiated subprotocol +- */ +- std::string const & get_subprotocol() const; +- +- /// Gets all of the subprotocols requested by the client +- /** +- * Retrieves the subprotocols that were requested during the handshake. This +- * method is valid in the validate handler and later. +- * +- * @return A vector of the requested subprotocol +- */ +- std::vector const & get_requested_subprotocols() const; +- +- /// Adds the given subprotocol string to the request list (exception free) +- /** +- * Adds a subprotocol to the list to send with the opening handshake. This +- * may be called multiple times to request more than one. If the server +- * supports one of these, it may choose one. If so, it will return it +- * in it's handshake reponse and the value will be available via +- * get_subprotocol(). Subprotocol requests should be added in order of +- * preference. +- * +- * @param request The subprotocol to request +- * @param ec A reference to an error code that will be filled in the case of +- * errors +- */ +- void add_subprotocol(std::string const & request, lib::error_code & ec); +- +- /// Adds the given subprotocol string to the request list +- /** +- * Adds a subprotocol to the list to send with the opening handshake. This +- * may be called multiple times to request more than one. If the server +- * supports one of these, it may choose one. If so, it will return it +- * in it's handshake reponse and the value will be available via +- * get_subprotocol(). Subprotocol requests should be added in order of +- * preference. +- * +- * @param request The subprotocol to request +- */ +- void add_subprotocol(std::string const & request); +- +- /// Select a subprotocol to use (exception free) +- /** +- * Indicates which subprotocol should be used for this connection. Valid +- * only during the validate handler callback. Subprotocol selected must have +- * been requested by the client. Consult get_requested_subprotocols() for a +- * list of valid subprotocols. +- * +- * This member function is valid on server endpoints/connections only +- * +- * @param value The subprotocol to select +- * @param ec A reference to an error code that will be filled in the case of +- * errors +- */ +- void select_subprotocol(std::string const & value, lib::error_code & ec); +- +- /// Select a subprotocol to use +- /** +- * Indicates which subprotocol should be used for this connection. Valid +- * only during the validate handler callback. Subprotocol selected must have +- * been requested by the client. Consult get_requested_subprotocols() for a +- * list of valid subprotocols. +- * +- * This member function is valid on server endpoints/connections only +- * +- * @param value The subprotocol to select +- */ +- void select_subprotocol(std::string const & value); +- +- ///////////////////////////////////////////////////////////// +- // Pass-through access to the request and response objects // +- ///////////////////////////////////////////////////////////// +- +- /// Retrieve a request header +- /** +- * Retrieve the value of a header from the handshake HTTP request. +- * +- * @param key Name of the header to get +- * @return The value of the header +- */ +- std::string const & get_request_header(std::string const & key) const; +- +- /// Retrieve a request body +- /** +- * Retrieve the value of the request body. This value is typically used with +- * PUT and POST requests to upload files or other data. Only HTTP +- * connections will ever have bodies. WebSocket connection's will always +- * have blank bodies. +- * +- * @return The value of the request body. +- */ +- std::string const & get_request_body() const; +- +- /// Retrieve a response header +- /** +- * Retrieve the value of a header from the handshake HTTP request. +- * +- * @param key Name of the header to get +- * @return The value of the header +- */ +- std::string const & get_response_header(std::string const & key) const; +- +- /// Get response HTTP status code +- /** +- * Gets the response status code +- * +- * @since 0.7.0 +- * +- * @return The response status code sent +- */ +- http::status_code::value get_response_code() const { +- return m_response.get_status_code(); +- } +- +- /// Get response HTTP status message +- /** +- * Gets the response status message +- * +- * @since 0.7.0 +- * +- * @return The response status message sent +- */ +- std::string const & get_response_msg() const { +- return m_response.get_status_msg(); +- } +- +- /// Set response status code and message +- /** +- * Sets the response status code to `code` and looks up the corresponding +- * message for standard codes. Non-standard codes will be entered as Unknown +- * use set_status(status_code::value,std::string) overload to set both +- * values explicitly. +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks. +- * +- * @param code Code to set +- * @param msg Message to set +- * @see ws_websocketpp::http::response::set_status +- */ +- void set_status(http::status_code::value code); +- +- /// Set response status code and message +- /** +- * Sets the response status code and message to independent custom values. +- * use set_status(status_code::value) to set the code and have the standard +- * message be automatically set. +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks. +- * +- * @param code Code to set +- * @param msg Message to set +- * @see ws_websocketpp::http::response::set_status +- */ +- void set_status(http::status_code::value code, std::string const & msg); +- +- /// Set response body content +- /** +- * Set the body content of the HTTP response to the parameter string. Note +- * set_body will also set the Content-Length HTTP header to the appropriate +- * value. If you want the Content-Length header to be something else set it +- * to something else after calling set_body +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks. +- * +- * @param value String data to include as the body content. +- * @see ws_websocketpp::http::response::set_body +- */ +- void set_body(std::string const & value); +- +- /// Append a header +- /** +- * If a header with this name already exists the value will be appended to +- * the existing header to form a comma separated list of values. Use +- * `connection::replace_header` to overwrite existing values. +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks, or to a client connection before connect has been called. +- * +- * @param key Name of the header to set +- * @param val Value to add +- * @see replace_header +- * @see ws_websocketpp::http::parser::append_header +- */ +- void append_header(std::string const & key, std::string const & val); +- +- /// Replace a header +- /** +- * If a header with this name already exists the old value will be replaced +- * Use `connection::append_header` to append to a list of existing values. +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks, or to a client connection before connect has been called. +- * +- * @param key Name of the header to set +- * @param val Value to set +- * @see append_header +- * @see ws_websocketpp::http::parser::replace_header +- */ +- void replace_header(std::string const & key, std::string const & val); +- +- /// Remove a header +- /** +- * Removes a header from the response. +- * +- * This member function is valid only from the http() and validate() handler +- * callbacks, or to a client connection before connect has been called. +- * +- * @param key The name of the header to remove +- * @see ws_websocketpp::http::parser::remove_header +- */ +- void remove_header(std::string const & key); +- +- /// Get request object +- /** +- * Direct access to request object. This can be used to call methods of the +- * request object that are not part of the standard request API that +- * connection wraps. +- * +- * Note use of this method involves using behavior specific to the +- * configured HTTP policy. Such behavior may not work with alternate HTTP +- * policies. +- * +- * @since 0.3.0-alpha3 +- * +- * @return A const reference to the raw request object +- */ +- request_type const & get_request() const { +- return m_request; +- } +- +- /// Get response object +- /** +- * Direct access to the HTTP response sent or received as a part of the +- * opening handshake. This can be used to call methods of the response +- * object that are not part of the standard request API that connection +- * wraps. +- * +- * Note use of this method involves using behavior specific to the +- * configured HTTP policy. Such behavior may not work with alternate HTTP +- * policies. +- * +- * @since 0.7.0 +- * +- * @return A const reference to the raw response object +- */ +- response_type const & get_response() const { +- return m_response; +- } +- +- /// Defer HTTP Response until later (Exception free) +- /** +- * Used in the http handler to defer the HTTP response for this connection +- * until later. Handshake timers will be canceled and the connection will be +- * left open until `send_http_response` or an equivalent is called. +- * +- * Warning: deferred connections won't time out and as a result can tie up +- * resources. +- * +- * @since 0.6.0 +- * +- * @return A status code, zero on success, non-zero otherwise +- */ +- lib::error_code defer_http_response(); +- +- /// Send deferred HTTP Response (exception free) +- /** +- * Sends an http response to an HTTP connection that was deferred. This will +- * send a complete response including all headers, status line, and body +- * text. The connection will be closed afterwards. +- * +- * @since 0.6.0 +- * +- * @param ec A status code, zero on success, non-zero otherwise +- */ +- void send_http_response(lib::error_code & ec); +- +- /// Send deferred HTTP Response +- void send_http_response(); +- +- // TODO HTTPNBIO: write_headers +- // function that processes headers + status so far and writes it to the wire +- // beginning the HTTP response body state. This method will ignore anything +- // in the response body. +- +- // TODO HTTPNBIO: write_body_message +- // queues the specified message_buffer for async writing +- +- // TODO HTTPNBIO: finish connection +- // +- +- // TODO HTTPNBIO: write_response +- // Writes the whole response, headers + body and closes the connection +- +- +- +- ///////////////////////////////////////////////////////////// +- // Pass-through access to the other connection information // +- ///////////////////////////////////////////////////////////// +- +- /// Get Connection Handle +- /** +- * The connection handle is a token that can be shared outside the +- * WebSocket++ core for the purposes of identifying a connection and +- * sending it messages. +- * +- * @return A handle to the connection +- */ +- connection_hdl get_handle() const { +- return m_connection_hdl; +- } +- +- /// Get whether or not this connection is part of a server or client +- /** +- * @return whether or not the connection is attached to a server endpoint +- */ +- bool is_server() const { +- return m_is_server; +- } +- +- /// Return the same origin policy origin value from the opening request. +- /** +- * This value is available after the HTTP request has been fully read and +- * may be called from any thread. +- * +- * @return The connection's origin value from the opening handshake. +- */ +- std::string const & get_origin() const; +- +- /// Return the connection state. +- /** +- * Values can be connecting, open, closing, and closed +- * +- * @return The connection's current state. +- */ +- session::state::value get_state() const; +- +- +- /// Get the WebSocket close code sent by this endpoint. +- /** +- * @return The WebSocket close code sent by this endpoint. +- */ +- close::status::value get_local_close_code() const { +- return m_local_close_code; +- } +- +- /// Get the WebSocket close reason sent by this endpoint. +- /** +- * @return The WebSocket close reason sent by this endpoint. +- */ +- std::string const & get_local_close_reason() const { +- return m_local_close_reason; +- } +- +- /// Get the WebSocket close code sent by the remote endpoint. +- /** +- * @return The WebSocket close code sent by the remote endpoint. +- */ +- close::status::value get_remote_close_code() const { +- return m_remote_close_code; +- } +- +- /// Get the WebSocket close reason sent by the remote endpoint. +- /** +- * @return The WebSocket close reason sent by the remote endpoint. +- */ +- std::string const & get_remote_close_reason() const { +- return m_remote_close_reason; +- } +- +- /// Get the internal error code for a closed/failed connection +- /** +- * Retrieves a machine readable detailed error code indicating the reason +- * that the connection was closed or failed. Valid only after the close or +- * fail handler is called. +- * +- * @return Error code indicating the reason the connection was closed or +- * failed +- */ +- lib::error_code get_ec() const { +- return m_ec; +- } +- +- /// Get a message buffer +- /** +- * Warning: The API related to directly sending message buffers may change +- * before the 1.0 release. If you plan to use it, please keep an eye on any +- * breaking changes notifications in future release notes. Also if you have +- * any feedback about usage and capabilities now is a great time to provide +- * it. +- * +- * Message buffers are used to store message payloads and other message +- * metadata. +- * +- * The size parameter is a hint only. Your final payload does not need to +- * match it. There may be some performance benefits if the initial size +- * guess is equal to or slightly higher than the final payload size. +- * +- * @param op The opcode for the new message +- * @param size A hint to optimize the initial allocation of payload space. +- * @return A new message buffer +- */ +- message_ptr get_message(ws_websocketpp::frame::opcode::value op, size_t size) +- const +- { +- return m_msg_manager->get_message(op, size); +- } +- +- //////////////////////////////////////////////////////////////////////// +- // The remaining public member functions are for internal/policy use // +- // only. Do not call from application code unless you understand what // +- // you are doing. // +- //////////////////////////////////////////////////////////////////////// +- +- +- +- void read_handshake(size_t num_bytes); +- +- void handle_read_handshake(lib::error_code const & ec, +- size_t bytes_transferred); +- void handle_read_http_response(lib::error_code const & ec, +- size_t bytes_transferred); +- +- +- void handle_write_http_response(lib::error_code const & ec); +- void handle_send_http_request(lib::error_code const & ec); +- +- void handle_open_handshake_timeout(lib::error_code const & ec); +- void handle_close_handshake_timeout(lib::error_code const & ec); +- +- void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred); +- void read_frame(); +- +- /// Get array of WebSocket protocol versions that this connection supports. +- std::vector const & get_supported_versions() const; +- +- /// Sets the handler for a terminating connection. Should only be used +- /// internally by the endpoint class. +- void set_termination_handler(termination_handler new_handler); +- +- void terminate(lib::error_code const & ec); +- void handle_terminate(terminate_status tstat, lib::error_code const & ec); +- +- /// Checks if there are frames in the send queue and if there are sends one +- /** +- * \todo unit tests +- * +- * This method locks the m_write_lock mutex +- */ +- void write_frame(); +- +- /// Process the results of a frame write operation and start the next write +- /** +- * \todo unit tests +- * +- * This method locks the m_write_lock mutex +- * +- * @param terminate Whether or not to terminate the connection upon +- * completion of this write. +- * +- * @param ec A status code from the transport layer, zero on success, +- * non-zero otherwise. +- */ +- void handle_write_frame(lib::error_code const & ec); +-// protected: +- // This set of methods would really like to be protected, but doing so +- // requires that the endpoint be able to friend the connection. This is +- // allowed with C++11, but not prior versions +- +- /// Start the connection state machine +- void start(); +- +- /// Set Connection Handle +- /** +- * The connection handle is a token that can be shared outside the +- * WebSocket++ core for the purposes of identifying a connection and +- * sending it messages. +- * +- * @param hdl A connection_hdl that the connection will use to refer +- * to itself. +- */ +- void set_handle(connection_hdl hdl) { +- m_connection_hdl = hdl; +- transport_con_type::set_handle(hdl); +- } +-protected: +- void handle_transport_init(lib::error_code const & ec); +- +- /// Set m_processor based on information in m_request. Set m_response +- /// status and return an error code indicating status. +- lib::error_code initialize_processor(); +- +- /// Perform WebSocket handshake validation of m_request using m_processor. +- /// set m_response and return an error code indicating status. +- lib::error_code process_handshake_request(); +-private: +- +- +- /// Completes m_response, serializes it, and sends it out on the wire. +- void write_http_response(lib::error_code const & ec); +- +- /// Sends an opening WebSocket connect request +- void send_http_request(); +- +- /// Alternate path for write_http_response in error conditions +- void write_http_response_error(lib::error_code const & ec); +- +- /// Process control message +- /** +- * +- */ +- void process_control_frame(message_ptr msg); +- +- /// Send close acknowledgement +- /** +- * If no arguments are present no close code/reason will be specified. +- * +- * Note: the close code/reason values provided here may be overrided by +- * other settings (such as silent close). +- * +- * @param code The close code to send +- * @param reason The close reason to send +- * @return A status code, zero on success, non-zero otherwise +- */ +- lib::error_code send_close_ack(close::status::value code = +- close::status::blank, std::string const & reason = std::string()); +- +- /// Send close frame +- /** +- * If no arguments are present no close code/reason will be specified. +- * +- * Note: the close code/reason values provided here may be overrided by +- * other settings (such as silent close). +- * +- * The ack flag determines what to do in the case of a blank status and +- * whether or not to terminate the TCP connection after sending it. +- * +- * @param code The close code to send +- * @param reason The close reason to send +- * @param ack Whether or not this is an acknowledgement close frame +- * @return A status code, zero on success, non-zero otherwise +- */ +- lib::error_code send_close_frame(close::status::value code = +- close::status::blank, std::string const & reason = std::string(), bool ack = false, +- bool terminal = false); +- +- /// Get a pointer to a new WebSocket protocol processor for a given version +- /** +- * @param version Version number of the WebSocket protocol to get a +- * processor for. Negative values indicate invalid/unknown versions and will +- * always return a null ptr +- * +- * @return A shared_ptr to a new instance of the appropriate processor or a +- * null ptr if there is no installed processor that matches the version +- * number. +- */ +- processor_ptr get_processor(int version) const; +- +- /// Add a message to the write queue +- /** +- * Adds a message to the write queue and updates any associated shared state +- * +- * Must be called while holding m_write_lock +- * +- * @todo unit tests +- * +- * @param msg The message to push +- */ +- void write_push(message_ptr msg); +- +- /// Pop a message from the write queue +- /** +- * Removes and returns a message from the write queue and updates any +- * associated shared state. +- * +- * Must be called while holding m_write_lock +- * +- * @todo unit tests +- * +- * @return the message_ptr at the front of the queue +- */ +- message_ptr write_pop(); +- +- /// Prints information about the incoming connection to the access log +- /** +- * Prints information about the incoming connection to the access log. +- * Includes: connection type, websocket version, remote endpoint, user agent +- * path, status code. +- */ +- void log_open_result(); +- +- /// Prints information about a connection being closed to the access log +- /** +- * Includes: local and remote close codes and reasons +- */ +- void log_close_result(); +- +- /// Prints information about a connection being failed to the access log +- /** +- * Includes: error code and message for why it was failed +- */ +- void log_fail_result(); +- +- /// Prints information about HTTP connections +- /** +- * Includes: TODO +- */ +- void log_http_result(); +- +- /// Prints information about an arbitrary error code on the specified channel +- template +- 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()); +- } +- +- // internal handler functions +- read_handler m_handle_read_frame; +- write_frame_handler m_write_frame_handler; +- +- // static settings +- std::string const m_user_agent; +- +- /// Pointer to the connection handle +- connection_hdl m_connection_hdl; +- +- /// Handler objects +- open_handler m_open_handler; +- close_handler m_close_handler; +- fail_handler m_fail_handler; +- ping_handler m_ping_handler; +- pong_handler m_pong_handler; +- pong_timeout_handler m_pong_timeout_handler; +- interrupt_handler m_interrupt_handler; +- http_handler m_http_handler; +- validate_handler m_validate_handler; +- message_handler m_message_handler; +- +- /// constant values +- long m_open_handshake_timeout_dur; +- long m_close_handshake_timeout_dur; +- long m_pong_timeout_dur; +- size_t m_max_message_size; +- +- /// External connection state +- /** +- * Lock: m_connection_state_lock +- */ +- session::state::value m_state; +- +- /// Internal connection state +- /** +- * Lock: m_connection_state_lock +- */ +- istate_type m_internal_state; +- +- mutable mutex_type m_connection_state_lock; +- +- /// The lock used to protect the message queue +- /** +- * Serializes access to the write queue as well as shared state within the +- * processor. +- */ +- mutex_type m_write_lock; +- +- // connection resources +- char m_buf[config::connection_read_buffer_size]; +- size_t m_buf_cursor; +- termination_handler m_termination_handler; +- con_msg_manager_ptr m_msg_manager; +- timer_ptr m_handshake_timer; +- timer_ptr m_ping_timer; +- +- /// @todo this is not memory efficient. this value is not used after the +- /// handshake. +- std::string m_handshake_buffer; +- +- /// Pointer to the processor object for this connection +- /** +- * The processor provides functionality that is specific to the WebSocket +- * protocol version that the client has negotiated. It also contains all of +- * the state necessary to encode and decode the incoming and outgoing +- * WebSocket byte streams +- * +- * Use of the prepare_data_frame method requires lock: m_write_lock +- */ +- processor_ptr m_processor; +- +- /// Queue of unsent outgoing messages +- /** +- * Lock: m_write_lock +- */ +- std::queue m_send_queue; +- +- /// Size in bytes of the outstanding payloads in the write queue +- /** +- * Lock: m_write_lock +- */ +- size_t m_send_buffer_size; +- +- /// buffer holding the various parts of the current message being writen +- /** +- * Lock m_write_lock +- */ +- std::vector m_send_buffer; +- +- /// a list of pointers to hold on to the messages being written to keep them +- /// from going out of scope before the write is complete. +- std::vector m_current_msgs; +- +- /// True if there is currently an outstanding transport write +- /** +- * Lock m_write_lock +- */ +- bool m_write_flag; +- +- /// True if this connection is presently reading new data +- bool m_read_flag; +- +- // connection data +- request_type m_request; +- response_type m_response; +- uri_ptr m_uri; +- std::string m_subprotocol; +- +- // connection data that might not be necessary to keep around for the life +- // of the whole connection. +- std::vector m_requested_subprotocols; +- +- bool const m_is_server; +- const lib::shared_ptr m_alog; +- const lib::shared_ptr m_elog; +- +- rng_type & m_rng; +- +- // Close state +- /// Close code that was sent on the wire by this endpoint +- close::status::value m_local_close_code; +- +- /// Close reason that was sent on the wire by this endpoint +- std::string m_local_close_reason; +- +- /// Close code that was received on the wire from the remote endpoint +- close::status::value m_remote_close_code; +- +- /// Close reason that was received on the wire from the remote endpoint +- std::string m_remote_close_reason; +- +- /// Detailed internal error code +- lib::error_code m_ec; +- +- /// A flag that gets set once it is determined that the connection is an +- /// HTTP connection and not a WebSocket one. +- bool m_is_http; +- +- /// A flag that gets set when the completion of an http connection is +- /// deferred until later. +- session::http_state::value m_http_state; +- +- bool m_was_clean; +-}; +- +-} // namespace ws_websocketpp +- +-#include +- +-#endif // WEBSOCKETPP_CONNECTION_HPP +diff --git a/src/lib/websocketpp/connection_base.hpp b/src/lib/websocketpp/connection_base.hpp +deleted file mode 100644 +index 33cbfb3..0000000 +--- a/src/lib/websocketpp/connection_base.hpp ++++ /dev/null +@@ -1,38 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONNECTION_BASE_HPP +-#define WEBSOCKETPP_CONNECTION_BASE_HPP +- +-namespace ws_websocketpp { +- +-/// Stub for user supplied base class. +-class connection_base {}; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONNECTION_BASE_HPP +diff --git a/src/lib/websocketpp/endpoint.hpp b/src/lib/websocketpp/endpoint.hpp +deleted file mode 100644 +index d4d573d..0000000 +--- a/src/lib/websocketpp/endpoint.hpp ++++ /dev/null +@@ -1,700 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_ENDPOINT_HPP +-#define WEBSOCKETPP_ENDPOINT_HPP +- +-#include +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +- +-/// Creates and manages connections associated with a WebSocket endpoint +-template +-class endpoint : public config::transport_type, public config::endpoint_base { +-public: +- // Import appropriate types from our helper class +- // See endpoint_types for more details. +- typedef endpoint type; +- +- /// Type of the transport component of this endpoint +- typedef typename config::transport_type transport_type; +- /// Type of the concurrency component of this endpoint +- typedef typename config::concurrency_type concurrency_type; +- +- /// Type of the connections that this endpoint creates +- typedef connection connection_type; +- /// Shared pointer to connection_type +- typedef typename connection_type::ptr connection_ptr; +- /// Weak pointer to connection type +- typedef typename connection_type::weak_ptr connection_weak_ptr; +- +- /// Type of the transport component of the connections that this endpoint +- /// creates +- typedef typename transport_type::transport_con_type transport_con_type; +- /// Type of a shared pointer to the transport component of the connections +- /// that this endpoint creates. +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- /// Type of message_handler +- typedef typename connection_type::message_handler message_handler; +- /// Type of message pointers that this endpoint uses +- typedef typename connection_type::message_ptr message_ptr; +- +- /// Type of error logger +- typedef typename config::elog_type elog_type; +- /// Type of access logger +- typedef typename config::alog_type alog_type; +- +- /// Type of our concurrency policy's scoped lock object +- typedef typename concurrency_type::scoped_lock_type scoped_lock_type; +- /// Type of our concurrency policy's mutex object +- typedef typename concurrency_type::mutex_type mutex_type; +- +- /// Type of RNG +- typedef typename config::rng_type rng_type; +- +- // TODO: organize these +- typedef typename connection_type::termination_handler termination_handler; +- +- // This would be ideal. Requires C++11 though +- //friend connection; +- +- explicit endpoint(bool p_is_server) +- : 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(::ws_websocketpp::user_agent) +- , m_open_handshake_timeout_dur(config::timeout_open_handshake) +- , m_close_handshake_timeout_dur(config::timeout_close_handshake) +- , m_pong_timeout_dur(config::timeout_pong) +- , m_max_message_size(config::max_message_size) +- , 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->write(log::alevel::devel, "endpoint constructor"); +- +- transport_type::init_logging(m_alog, m_elog); +- } +- +- +- /// Destructor +- ~endpoint() {} +- +- #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no copy constructor because endpoints are not copyable +- endpoint(endpoint &) = delete; +- +- // no copy assignment operator because endpoints are not copyable +- endpoint & operator=(endpoint const &) = delete; +- #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +- #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ +- /// Move constructor +- endpoint(endpoint && o) +- : config::transport_type(std::move(o)) +- , config::endpoint_base(std::move(o)) +- , m_alog(std::move(o.m_alog)) +- , m_elog(std::move(o.m_elog)) +- , m_user_agent(std::move(o.m_user_agent)) +- , m_open_handler(std::move(o.m_open_handler)) +- +- , m_close_handler(std::move(o.m_close_handler)) +- , m_fail_handler(std::move(o.m_fail_handler)) +- , m_ping_handler(std::move(o.m_ping_handler)) +- , m_pong_handler(std::move(o.m_pong_handler)) +- , m_pong_timeout_handler(std::move(o.m_pong_timeout_handler)) +- , m_interrupt_handler(std::move(o.m_interrupt_handler)) +- , m_http_handler(std::move(o.m_http_handler)) +- , m_validate_handler(std::move(o.m_validate_handler)) +- , m_message_handler(std::move(o.m_message_handler)) +- +- , m_open_handshake_timeout_dur(o.m_open_handshake_timeout_dur) +- , m_close_handshake_timeout_dur(o.m_close_handshake_timeout_dur) +- , m_pong_timeout_dur(o.m_pong_timeout_dur) +- , m_max_message_size(o.m_max_message_size) +- , m_max_http_body_size(o.m_max_http_body_size) +- +- , m_rng(std::move(o.m_rng)) +- , m_is_server(o.m_is_server) +- {} +- +- #ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no move assignment operator because of const member variables +- endpoint & operator=(endpoint &&) = delete; +- #endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +- #endif // _WEBSOCKETPP_MOVE_SEMANTICS_ +- +- +- /// Returns the user agent string that this endpoint will use +- /** +- * Returns the user agent string that this endpoint will use when creating +- * new connections. +- * +- * The default value for this version is stored in ws_websocketpp::user_agent +- * +- * @return The user agent string. +- */ +- std::string get_user_agent() const { +- scoped_lock_type guard(m_mutex); +- return m_user_agent; +- } +- +- /// Sets the user agent string that this endpoint will use +- /** +- * Sets the identifier that this endpoint will use when creating new +- * connections. Changing this value will only affect future connections. +- * For client endpoints this will be sent as the "User-Agent" header in +- * outgoing requests. For server endpoints this will be sent in the "Server" +- * response header. +- * +- * Setting this value to the empty string will suppress the use of the +- * Server and User-Agent headers. This is typically done to hide +- * implementation details for security purposes. +- * +- * For best results set this before accepting or opening connections. +- * +- * The default value for this version is stored in ws_websocketpp::user_agent +- * +- * This can be overridden on an individual connection basis by setting a +- * custom "Server" header during the validate handler or "User-Agent" +- * header on a connection before calling connect(). +- * +- * @param ua The string to set the user agent to. +- */ +- void set_user_agent(std::string const & ua) { +- scoped_lock_type guard(m_mutex); +- m_user_agent = ua; +- } +- +- /// Returns whether or not this endpoint is a server. +- /** +- * @return Whether or not this endpoint is a server +- */ +- bool is_server() const { +- return m_is_server; +- } +- +- /********************************/ +- /* Pass-through logging adaptor */ +- /********************************/ +- +- /// Set Access logging channel +- /** +- * Set the access logger's channel value. The value is a number whose +- * interpretation depends on the logging policy in use. +- * +- * @param channels The channel value(s) to set +- */ +- void set_access_channels(log::level channels) { +- m_alog->set_channels(channels); +- } +- +- /// Clear Access logging channels +- /** +- * Clear the access logger's channel value. The value is a number whose +- * interpretation depends on the logging policy in use. +- * +- * @param channels The channel value(s) to clear +- */ +- void clear_access_channels(log::level channels) { +- m_alog->clear_channels(channels); +- } +- +- /// Set Error logging channel +- /** +- * Set the error logger's channel value. The value is a number whose +- * interpretation depends on the logging policy in use. +- * +- * @param channels The channel value(s) to set +- */ +- void set_error_channels(log::level channels) { +- m_elog->set_channels(channels); +- } +- +- /// Clear Error logging channels +- /** +- * Clear the error logger's channel value. The value is a number whose +- * interpretation depends on the logging policy in use. +- * +- * @param channels The channel value(s) to clear +- */ +- void clear_error_channels(log::level channels) { +- m_elog->clear_channels(channels); +- } +- +- /// Get reference to access logger +- /** +- * @return A reference to the access logger +- */ +- alog_type & get_alog() { +- return *m_alog; +- } +- +- /// Get reference to error logger +- /** +- * @return A reference to the error logger +- */ +- elog_type & get_elog() { +- return *m_elog; +- } +- +- /*************************/ +- /* Set Handler functions */ +- /*************************/ +- +- void set_open_handler(open_handler h) { +- 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"); +- 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"); +- 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"); +- 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"); +- 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"); +- 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"); +- 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"); +- 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"); +- 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"); +- scoped_lock_type guard(m_mutex); +- m_message_handler = h; +- } +- +- ////////////////////////////////////////// +- // Connection timeouts and other limits // +- ////////////////////////////////////////// +- +- /// Set open handshake timeout +- /** +- * Sets the length of time the library will wait after an opening handshake +- * has been initiated before cancelling it. This can be used to prevent +- * excessive wait times for outgoing clients or excessive resource usage +- * from broken clients or DoS attacks on servers. +- * +- * Connections that time out will have their fail handlers called with the +- * open_handshake_timeout error code. +- * +- * The default value is specified via the compile time config value +- * 'timeout_open_handshake'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the open handshake timeout in ms +- */ +- void set_open_handshake_timeout(long dur) { +- scoped_lock_type guard(m_mutex); +- m_open_handshake_timeout_dur = dur; +- } +- +- /// Set close handshake timeout +- /** +- * Sets the length of time the library will wait after a closing handshake +- * has been initiated before cancelling it. This can be used to prevent +- * excessive wait times for outgoing clients or excessive resource usage +- * from broken clients or DoS attacks on servers. +- * +- * Connections that time out will have their close handlers called with the +- * close_handshake_timeout error code. +- * +- * The default value is specified via the compile time config value +- * 'timeout_close_handshake'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the close handshake timeout in ms +- */ +- void set_close_handshake_timeout(long dur) { +- scoped_lock_type guard(m_mutex); +- m_close_handshake_timeout_dur = dur; +- } +- +- /// Set pong timeout +- /** +- * Sets the length of time the library will wait for a pong response to a +- * ping. This can be used as a keepalive or to detect broken connections. +- * +- * Pong responses that time out will have the pong timeout handler called. +- * +- * The default value is specified via the compile time config value +- * 'timeout_pong'. The default value in the core config +- * is 5000ms. A value of 0 will disable the timer entirely. +- * +- * To be effective, the transport you are using must support timers. See +- * the documentation for your transport policy for details about its +- * timer support. +- * +- * @param dur The length of the pong timeout in ms +- */ +- void set_pong_timeout(long dur) { +- scoped_lock_type guard(m_mutex); +- m_pong_timeout_dur = dur; +- } +- +- /// Get default maximum message size +- /** +- * Get the default maximum message size that will be used for new +- * connections created by this endpoint. The maximum message size determines +- * the point at which the connection will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is set by the max_message_size value from the template config +- * +- * @since 0.3.0 +- */ +- size_t get_max_message_size() const { +- return m_max_message_size; +- } +- +- /// Set default maximum message size +- /** +- * Set the default maximum message size that will be used for new +- * connections created by this endpoint. Maximum message size determines the +- * point at which the connection will fail a connection with the +- * message_too_big protocol error. +- * +- * The default is set by the max_message_size value from the template config +- * +- * @since 0.3.0 +- * +- * @param new_value The value to set as the maximum message size. +- */ +- void set_max_message_size(size_t new_value) { +- m_max_message_size = new_value; +- } +- +- /// Get maximum HTTP message body size +- /** +- * Get maximum HTTP message body size. Maximum message body size determines +- * the point at which the connection will stop reading an HTTP request whose +- * body is too large. +- * +- * The default is set by the max_http_body_size value from the template +- * config +- * +- * @since 0.5.0 +- * +- * @return The maximum HTTP message body size +- */ +- size_t get_max_http_body_size() const { +- return m_max_http_body_size; +- } +- +- /// Set maximum HTTP message body size +- /** +- * Set maximum HTTP message body size. Maximum message body size determines +- * the point at which the connection will stop reading an HTTP request whose +- * body is too large. +- * +- * The default is set by the max_http_body_size value from the template +- * config +- * +- * @since 0.5.1 +- * +- * @param new_value The value to set as the maximum message size. +- */ +- void set_max_http_body_size(size_t new_value) { +- m_max_http_body_size = new_value; +- } +- +- /*************************************/ +- /* Connection pass through functions */ +- /*************************************/ +- +- /** +- * These functions act as adaptors to their counterparts in connection. They +- * can produce one additional type of error, the bad_connection error, that +- * indicates that the conversion from connection_hdl to connection_ptr +- * failed due to the connection not existing anymore. Each method has a +- * default and an exception free varient. +- */ +- +- void interrupt(connection_hdl hdl, lib::error_code & ec); +- void interrupt(connection_hdl hdl); +- +- /// Pause reading of new data (exception free) +- /** +- * Signals to the connection to halt reading of new data. While reading is +- * paused, the connection will stop reading from its associated socket. In +- * turn this will result in TCP based flow control kicking in and slowing +- * data flow from the remote endpoint. +- * +- * This is useful for applications that push new requests to a queue to be +- * processed by another thread and need a way to signal when their request +- * queue is full without blocking the network processing thread. +- * +- * Use `resume_reading()` to resume. +- * +- * If supported by the transport this is done asynchronously. As such +- * reading may not stop until the current read operation completes. +- * Typically you can expect to receive no more bytes after initiating a read +- * pause than the size of the read buffer. +- * +- * If reading is paused for this connection already nothing is changed. +- */ +- void pause_reading(connection_hdl hdl, lib::error_code & ec); +- +- /// Pause reading of new data +- void pause_reading(connection_hdl hdl); +- +- /// Resume reading of new data (exception free) +- /** +- * Signals to the connection to resume reading of new data after it was +- * paused by `pause_reading()`. +- * +- * If reading is not paused for this connection already nothing is changed. +- */ +- void resume_reading(connection_hdl hdl, lib::error_code & ec); +- +- /// Resume reading of new data +- void resume_reading(connection_hdl hdl); +- +- /// Send deferred HTTP Response +- /** +- * Sends an http response to an HTTP connection that was deferred. This will +- * send a complete response including all headers, status line, and body +- * text. The connection will be closed afterwards. +- * +- * Exception free variant +- * +- * @since 0.6.0 +- * +- * @param hdl The connection to send the response on +- * @param ec A status code, zero on success, non-zero otherwise +- */ +- void send_http_response(connection_hdl hdl, lib::error_code & ec); +- +- /// Send deferred HTTP Response (exception free) +- /** +- * Sends an http response to an HTTP connection that was deferred. This will +- * send a complete response including all headers, status line, and body +- * text. The connection will be closed afterwards. +- * +- * Exception variant +- * +- * @since 0.6.0 +- * +- * @param hdl The connection to send the response on +- */ +- void send_http_response(connection_hdl hdl); +- +- /// Create a message and add it to the outgoing send queue (exception free) +- /** +- * Convenience method to send a message given a payload string and an opcode +- * +- * @param [in] hdl The handle identifying the connection to send via. +- * @param [in] payload The payload string to generated the message with +- * @param [in] op The opcode to generated the message with. +- * @param [out] ec A code to fill in for errors +- */ +- void send(connection_hdl hdl, std::string const & payload, +- frame::opcode::value op, lib::error_code & ec); +- /// Create a message and add it to the outgoing send queue +- /** +- * Convenience method to send a message given a payload string and an opcode +- * +- * @param [in] hdl The handle identifying the connection to send via. +- * @param [in] payload The payload string to generated the message with +- * @param [in] op The opcode to generated the message with. +- * @param [out] ec A code to fill in for errors +- */ +- void send(connection_hdl hdl, std::string const & payload, +- frame::opcode::value op); +- +- void send(connection_hdl hdl, void const * payload, size_t len, +- frame::opcode::value op, lib::error_code & ec); +- void send(connection_hdl hdl, void const * payload, size_t len, +- frame::opcode::value op); +- +- void send(connection_hdl hdl, message_ptr msg, lib::error_code & ec); +- void send(connection_hdl hdl, message_ptr msg); +- +- void close(connection_hdl hdl, close::status::value const code, +- std::string const & reason, lib::error_code & ec); +- void close(connection_hdl hdl, close::status::value const code, +- std::string const & reason); +- +- /// Send a ping to a specific connection +- /** +- * @since 0.3.0-alpha3 +- * +- * @param [in] hdl The connection_hdl of the connection to send to. +- * @param [in] payload The payload string to send. +- * @param [out] ec A reference to an error code to fill in +- */ +- void ping(connection_hdl hdl, std::string const & payload, +- lib::error_code & ec); +- /// Send a ping to a specific connection +- /** +- * Exception variant of `ping` +- * +- * @since 0.3.0-alpha3 +- * +- * @param [in] hdl The connection_hdl of the connection to send to. +- * @param [in] payload The payload string to send. +- */ +- void ping(connection_hdl hdl, std::string const & payload); +- +- /// Send a pong to a specific connection +- /** +- * @since 0.3.0-alpha3 +- * +- * @param [in] hdl The connection_hdl of the connection to send to. +- * @param [in] payload The payload string to send. +- * @param [out] ec A reference to an error code to fill in +- */ +- void pong(connection_hdl hdl, std::string const & payload, +- lib::error_code & ec); +- /// Send a pong to a specific connection +- /** +- * Exception variant of `pong` +- * +- * @since 0.3.0-alpha3 +- * +- * @param [in] hdl The connection_hdl of the connection to send to. +- * @param [in] payload The payload string to send. +- */ +- void pong(connection_hdl hdl, std::string const & payload); +- +- /// Retrieves a connection_ptr from a connection_hdl (exception free) +- /** +- * Converting a weak pointer to shared_ptr is not thread safe because the +- * pointer could be deleted at any time. +- * +- * NOTE: This method may be called by handler to upgrade its handle to a +- * full connection_ptr. That full connection may then be used safely for the +- * remainder of the handler body. get_con_from_hdl and the resulting +- * connection_ptr are NOT safe to use outside the handler loop. +- * +- * @param hdl The connection handle to translate +- * +- * @return the connection_ptr. May be NULL if the handle was invalid. +- */ +- connection_ptr get_con_from_hdl(connection_hdl hdl, lib::error_code & ec) { +- connection_ptr con = lib::static_pointer_cast( +- hdl.lock()); +- if (!con) { +- ec = error::make_error_code(error::bad_connection); +- } +- return con; +- } +- +- /// Retrieves a connection_ptr from a connection_hdl (exception version) +- connection_ptr get_con_from_hdl(connection_hdl hdl) { +- lib::error_code ec; +- connection_ptr con = this->get_con_from_hdl(hdl,ec); +- if (ec) { +- throw exception(ec); +- } +- return con; +- } +-protected: +- connection_ptr create_connection(); +- +- lib::shared_ptr m_alog; +- lib::shared_ptr m_elog; +-private: +- // dynamic settings +- std::string m_user_agent; +- +- open_handler m_open_handler; +- close_handler m_close_handler; +- fail_handler m_fail_handler; +- ping_handler m_ping_handler; +- pong_handler m_pong_handler; +- pong_timeout_handler m_pong_timeout_handler; +- interrupt_handler m_interrupt_handler; +- http_handler m_http_handler; +- validate_handler m_validate_handler; +- message_handler m_message_handler; +- +- long m_open_handshake_timeout_dur; +- long m_close_handshake_timeout_dur; +- long m_pong_timeout_dur; +- size_t m_max_message_size; +- size_t m_max_http_body_size; +- +- rng_type m_rng; +- +- // static settings +- bool const m_is_server; +- +- // endpoint state +- mutable mutex_type m_mutex; +-}; +- +-} // namespace ws_websocketpp +- +-#include +- +-#endif // WEBSOCKETPP_ENDPOINT_HPP +diff --git a/src/lib/websocketpp/endpoint_base.hpp b/src/lib/websocketpp/endpoint_base.hpp +deleted file mode 100644 +index 99faff3..0000000 +--- a/src/lib/websocketpp/endpoint_base.hpp ++++ /dev/null +@@ -1,38 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_ENDPOINT_BASE_HPP +-#define WEBSOCKETPP_ENDPOINT_BASE_HPP +- +-namespace ws_websocketpp { +- +-/// Stub for user supplied base class. +-class endpoint_base {}; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_ENDPOINT_BASE_HPP +diff --git a/src/lib/websocketpp/error.hpp b/src/lib/websocketpp/error.hpp +deleted file mode 100644 +index 8b6f9a3..0000000 +--- a/src/lib/websocketpp/error.hpp ++++ /dev/null +@@ -1,277 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_ERROR_HPP +-#define WEBSOCKETPP_ERROR_HPP +- +-#include +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +- +-/// Combination error code / string type for returning two values +-typedef std::pair err_str_pair; +- +-/// Library level error codes +-namespace error { +-enum value { +- /// Catch-all library error +- general = 1, +- +- /// send attempted when endpoint write queue was full +- send_queue_full, +- +- /// Attempted an operation using a payload that was improperly formatted +- /// ex: invalid UTF8 encoding on a text message. +- payload_violation, +- +- /// Attempted to open a secure connection with an insecure endpoint +- endpoint_not_secure, +- +- /// Attempted an operation that required an endpoint that is no longer +- /// available. This is usually because the endpoint went out of scope +- /// before a connection that it created. +- endpoint_unavailable, +- +- /// An invalid uri was supplied +- invalid_uri, +- +- /// The endpoint is out of outgoing message buffers +- no_outgoing_buffers, +- +- /// The endpoint is out of incoming message buffers +- no_incoming_buffers, +- +- /// The connection was in the wrong state for this operation +- invalid_state, +- +- /// Unable to parse close code +- bad_close_code, +- +- /// Close code is in a reserved range +- reserved_close_code, +- +- /// Close code is invalid +- invalid_close_code, +- +- /// Invalid UTF-8 +- invalid_utf8, +- +- /// Invalid subprotocol +- invalid_subprotocol, +- +- /// An operation was attempted on a connection that did not exist or was +- /// already deleted. +- bad_connection, +- +- /// Unit testing utility error code +- test, +- +- /// Connection creation attempted failed +- con_creation_failed, +- +- /// Selected subprotocol was not requested by the client +- unrequested_subprotocol, +- +- /// Attempted to use a client specific feature on a server endpoint +- client_only, +- +- /// Attempted to use a server specific feature on a client endpoint +- server_only, +- +- /// HTTP connection ended +- http_connection_ended, +- +- /// WebSocket opening handshake timed out +- open_handshake_timeout, +- +- /// WebSocket close handshake timed out +- close_handshake_timeout, +- +- /// Invalid port in URI +- invalid_port, +- +- /// An async accept operation failed because the underlying transport has been +- /// requested to not listen for new connections anymore. +- async_accept_not_listening, +- +- /// The requested operation was canceled +- operation_canceled, +- +- /// Connection rejected +- rejected, +- +- /// Upgrade Required. This happens if an HTTP request is made to a +- /// WebSocket++ server that doesn't implement an http handler +- upgrade_required, +- +- /// Invalid WebSocket protocol version +- invalid_version, +- +- /// Unsupported WebSocket protocol version +- unsupported_version, +- +- /// HTTP parse error +- http_parse_error, +- +- /// Extension negotiation failed +- extension_neg_failed +-}; // enum value +- +- +-class category : public lib::error_category { +-public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case error::general: +- return "Generic error"; +- case error::send_queue_full: +- return "send queue full"; +- case error::payload_violation: +- return "payload violation"; +- case error::endpoint_not_secure: +- return "endpoint not secure"; +- case error::endpoint_unavailable: +- return "endpoint not available"; +- case error::invalid_uri: +- return "invalid uri"; +- case error::no_outgoing_buffers: +- return "no outgoing message buffers"; +- case error::no_incoming_buffers: +- return "no incoming message buffers"; +- case error::invalid_state: +- return "invalid state"; +- case error::bad_close_code: +- return "Unable to extract close code"; +- case error::invalid_close_code: +- return "Extracted close code is in an invalid range"; +- case error::reserved_close_code: +- return "Extracted close code is in a reserved range"; +- case error::invalid_utf8: +- return "Invalid UTF-8"; +- case error::invalid_subprotocol: +- return "Invalid subprotocol"; +- case error::bad_connection: +- return "Bad Connection"; +- case error::test: +- return "Test Error"; +- case error::con_creation_failed: +- return "Connection creation attempt failed"; +- case error::unrequested_subprotocol: +- return "Selected subprotocol was not requested by the client"; +- case error::client_only: +- return "Feature not available on server endpoints"; +- case error::server_only: +- return "Feature not available on client endpoints"; +- case error::http_connection_ended: +- return "HTTP connection ended"; +- case error::open_handshake_timeout: +- return "The opening handshake timed out"; +- case error::close_handshake_timeout: +- return "The closing handshake timed out"; +- case error::invalid_port: +- return "Invalid URI port"; +- case error::async_accept_not_listening: +- return "Async Accept not listening"; +- case error::operation_canceled: +- return "Operation canceled"; +- case error::rejected: +- return "Connection rejected"; +- case error::upgrade_required: +- return "Upgrade required"; +- case error::invalid_version: +- return "Invalid version"; +- case error::unsupported_version: +- return "Unsupported version"; +- case error::http_parse_error: +- return "HTTP parse error"; +- case error::extension_neg_failed: +- return "Extension negotiation failed"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-inline const lib::error_category& get_category() { +- static category instance; +- return instance; +-} +- +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace ws_websocketpp +- +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-namespace ws_websocketpp { +- +-class exception : public std::exception { +-public: +- exception(std::string const & msg, lib::error_code ec = make_error_code(error::general)) +- : m_msg(msg.empty() ? ec.message() : msg), m_code(ec) +- {} +- +- explicit exception(lib::error_code ec) +- : m_msg(ec.message()), m_code(ec) +- {} +- +- ~exception() throw() {} +- +- virtual char const * what() const throw() { +- return m_msg.c_str(); +- } +- +- lib::error_code code() const throw() { +- return m_code; +- } +- +- const std::string m_msg; +- lib::error_code m_code; +-}; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_ERROR_HPP +diff --git a/src/lib/websocketpp/extensions/extension.hpp b/src/lib/websocketpp/extensions/extension.hpp +deleted file mode 100644 +index 0462508..0000000 +--- a/src/lib/websocketpp/extensions/extension.hpp ++++ /dev/null +@@ -1,102 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_EXTENSION_HPP +-#define WEBSOCKETPP_EXTENSION_HPP +- +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +- +-/** +- * Some generic information about extensions +- * +- * Each extension object has an implemented flag. It can be retrieved by calling +- * is_implemented(). This compile time flag indicates whether or not the object +- * in question actually implements the extension or if it is a placeholder stub +- * +- * Each extension object also has an enabled flag. It can be retrieved by +- * calling is_enabled(). This runtime flag indicates whether or not the +- * extension has been negotiated for this connection. +- */ +-namespace extensions { +- +-namespace error { +-enum value { +- /// Catch all +- general = 1, +- +- /// Extension disabled +- disabled +-}; +- +-class category : public lib::error_category { +-public: +- category() {} +- +- const char *name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.extension"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic extension error"; +- case disabled: +- return "Use of methods from disabled extension"; +- default: +- return "Unknown permessage-compress error"; +- } +- } +-}; +- +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace extensions +-} // namespace ws_websocketpp +- +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +- +-{ +- static const bool value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif // WEBSOCKETPP_EXTENSION_HPP +diff --git a/src/lib/websocketpp/extensions/permessage_deflate/disabled.hpp b/src/lib/websocketpp/extensions/permessage_deflate/disabled.hpp +deleted file mode 100644 +index a5acbcf..0000000 +--- a/src/lib/websocketpp/extensions/permessage_deflate/disabled.hpp ++++ /dev/null +@@ -1,129 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP +-#define WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace extensions { +-namespace permessage_deflate { +- +-/// Stub class for use when disabling permessage_deflate extension +-/** +- * This class is a stub that implements the permessage_deflate interface +- * with minimal dependencies. It is used to disable permessage_deflate +- * functionality at compile time without loading any unnecessary code. +- */ +-template +-class disabled { +- typedef std::pair err_str_pair; +- +-public: +- /// Negotiate extension +- /** +- * The disabled extension always fails the negotiation with a disabled +- * error. +- * +- * @param offer Attribute from client's offer +- * @return Status code and value to return to remote endpoint +- */ +- err_str_pair negotiate(http::attribute_list const &) { +- return make_pair(make_error_code(error::disabled),std::string()); +- } +- +- /// Initialize state +- /** +- * For the disabled extension state initialization is a no-op. +- * +- * @param is_server True to initialize as a server, false for a client. +- * @return A code representing the error that occurred, if any +- */ +- lib::error_code init(bool) { +- return lib::error_code(); +- } +- +- /// Returns true if the extension is capable of providing +- /// permessage_deflate functionality +- bool is_implemented() const { +- return false; +- } +- +- /// Returns true if permessage_deflate functionality is active for this +- /// connection +- bool is_enabled() const { +- return false; +- } +- +- /// Generate extension offer +- /** +- * Creates an offer string to include in the Sec-WebSocket-Extensions +- * header of outgoing client requests. +- * +- * @return A WebSocket extension offer string for this extension +- */ +- std::string generate_offer() const { +- return ""; +- } +- +- /// Compress bytes +- /** +- * @param [in] in String to compress +- * @param [out] out String to append compressed bytes to +- * @return Error or status code +- */ +- lib::error_code compress(std::string const &, std::string &) { +- return make_error_code(error::disabled); +- } +- +- /// Decompress bytes +- /** +- * @param buf Byte buffer to decompress +- * @param len Length of buf +- * @param out String to append decompressed bytes to +- * @return Error or status code +- */ +- lib::error_code decompress(uint8_t const *, size_t, std::string &) { +- return make_error_code(error::disabled); +- } +-}; +- +-} // namespace permessage_deflate +-} // namespace extensions +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_EXTENSION_PERMESSAGE_DEFLATE_DISABLED_HPP +diff --git a/src/lib/websocketpp/extensions/permessage_deflate/enabled.hpp b/src/lib/websocketpp/extensions/permessage_deflate/enabled.hpp +deleted file mode 100644 +index 7c4f155..0000000 +--- a/src/lib/websocketpp/extensions/permessage_deflate/enabled.hpp ++++ /dev/null +@@ -1,817 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP +-#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP +- +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-#include "zlib.h" +- +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace extensions { +- +-/// Implementation of RFC 7692, the permessage-deflate WebSocket extension +-/** +- * ### permessage-deflate interface +- * +- * **init**\n +- * `lib::error_code init(bool is_server)`\n +- * Performs initialization +- * +- * **is_implimented**\n +- * `bool is_implimented()`\n +- * Returns whether or not the object impliments the extension or not +- * +- * **is_enabled**\n +- * `bool is_enabled()`\n +- * Returns whether or not the extension was negotiated for the current +- * connection +- * +- * **generate_offer**\n +- * `std::string generate_offer() const`\n +- * Create an extension offer string based on local policy +- * +- * **validate_response**\n +- * `lib::error_code validate_response(http::attribute_list const & response)`\n +- * Negotiate the parameters of extension use +- * +- * **negotiate**\n +- * `err_str_pair negotiate(http::attribute_list const & attributes)`\n +- * Negotiate the parameters of extension use +- * +- * **compress**\n +- * `lib::error_code compress(std::string const & in, std::string & out)`\n +- * Compress the bytes in `in` and append them to `out` +- * +- * **decompress**\n +- * `lib::error_code decompress(uint8_t const * buf, size_t len, std::string & +- * out)`\n +- * Decompress `len` bytes from `buf` and append them to string `out` +- */ +-namespace permessage_deflate { +- +-/// Permessage deflate error values +-namespace error { +-enum value { +- /// Catch all +- general = 1, +- +- /// Invalid extension attributes +- invalid_attributes, +- +- /// Invalid extension attribute value +- invalid_attribute_value, +- +- /// Invalid megotiation mode +- invalid_mode, +- +- /// Unsupported extension attributes +- unsupported_attributes, +- +- /// Invalid value for max_window_bits +- invalid_max_window_bits, +- +- /// ZLib Error +- zlib_error, +- +- /// Uninitialized +- uninitialized, +-}; +- +-/// Permessage-deflate error category +-class category : public lib::error_category { +-public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.extension.permessage-deflate"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic permessage-compress error"; +- case invalid_attributes: +- return "Invalid extension attributes"; +- case invalid_attribute_value: +- return "Invalid extension attribute value"; +- case invalid_mode: +- return "Invalid permessage-deflate negotiation mode"; +- case unsupported_attributes: +- return "Unsupported extension attributes"; +- case invalid_max_window_bits: +- return "Invalid value for max_window_bits"; +- case zlib_error: +- return "A zlib function returned an error"; +- case uninitialized: +- return "Deflate extension must be initialized before use"; +- default: +- return "Unknown permessage-compress error"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the permessage-deflate error category +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-/// Create an error code in the permessage-deflate category +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace permessage_deflate +-} // namespace extensions +-} // namespace ws_websocketpp +- +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +- +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +-namespace ws_websocketpp { +-namespace extensions { +-namespace permessage_deflate { +- +-/// 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 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 RFC 7692 +-static uint8_t const max_server_max_window_bits = 15; +- +-/// 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 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 RFC 7692 +-static uint8_t const max_client_max_window_bits = 15; +- +-namespace mode { +-enum value { +- /// Accept any value the remote endpoint offers +- accept = 1, +- /// Decline any value the remote endpoint offers. Insist on defaults. +- decline, +- /// Use the largest value common to both offers +- largest, +- /// Use the smallest value common to both offers +- smallest +-}; +-} // namespace mode +- +-template +-class enabled { +-public: +- enabled() +- : m_enabled(false) +- , m_server_no_context_takeover(false) +- , m_client_no_context_takeover(false) +- , m_server_max_window_bits(15) +- , m_client_max_window_bits(15) +- , m_server_max_window_bits_mode(mode::accept) +- , m_client_max_window_bits_mode(mode::accept) +- , m_initialized(false) +- , m_compress_buffer_size(8192) +- { +- m_dstate.zalloc = Z_NULL; +- m_dstate.zfree = Z_NULL; +- m_dstate.opaque = Z_NULL; +- +- m_istate.zalloc = Z_NULL; +- m_istate.zfree = Z_NULL; +- m_istate.opaque = Z_NULL; +- m_istate.avail_in = 0; +- m_istate.next_in = Z_NULL; +- } +- +- ~enabled() { +- if (!m_initialized) { +- return; +- } +- +- int ret = deflateEnd(&m_dstate); +- +- if (ret != Z_OK) { +- //std::cout << "error cleaning up zlib compression state" +- // << std::endl; +- } +- +- ret = inflateEnd(&m_istate); +- +- if (ret != Z_OK) { +- //std::cout << "error cleaning up zlib decompression state" +- // << std::endl; +- } +- } +- +- /// Initialize zlib state +- /** +- * Note: this should be called *after* the negotiation methods. It will use +- * information from the negotiation to determine how to initialize the zlib +- * data structures. +- * +- * @todo memory level, strategy, etc are hardcoded +- * +- * @param is_server True to initialize as a server, false for a client. +- * @return A code representing the error that occurred, if any +- */ +- lib::error_code init(bool is_server) { +- uint8_t deflate_bits; +- uint8_t inflate_bits; +- +- if (is_server) { +- deflate_bits = m_server_max_window_bits; +- inflate_bits = m_client_max_window_bits; +- } else { +- deflate_bits = m_client_max_window_bits; +- inflate_bits = m_server_max_window_bits; +- } +- +- int ret = deflateInit2( +- &m_dstate, +- Z_DEFAULT_COMPRESSION, +- Z_DEFLATED, +- -1*deflate_bits, +- 4, // memory level 1-9 +- Z_DEFAULT_STRATEGY +- ); +- +- if (ret != Z_OK) { +- return make_error_code(error::zlib_error); +- } +- +- ret = inflateInit2( +- &m_istate, +- -1*inflate_bits +- ); +- +- if (ret != Z_OK) { +- return make_error_code(error::zlib_error); +- } +- +- 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)) +- { +- m_flush = Z_FULL_FLUSH; +- } else { +- m_flush = Z_SYNC_FLUSH; +- } +- m_initialized = true; +- return lib::error_code(); +- } +- +- /// Test if this object implements the permessage-deflate specification +- /** +- * Because this object does implieent it, it will always return true. +- * +- * @return Whether or not this object implements permessage-deflate +- */ +- bool is_implemented() const { +- return true; +- } +- +- /// Test if the extension was negotiated for this connection +- /** +- * Retrieves whether or not this extension is in use based on the initial +- * handshake extension negotiations. +- * +- * @return Whether or not the extension is in use +- */ +- bool is_enabled() const { +- return m_enabled; +- } +- +- /// Reset server's outgoing LZ77 sliding window for each new message +- /** +- * Enabling this setting will cause the server's compressor to reset the +- * compression state (the LZ77 sliding window) for every message. This +- * means that the compressor will not look back to patterns in previous +- * messages to improve compression. This will reduce the compression +- * efficiency for large messages somewhat and small messages drastically. +- * +- * This option may reduce server compressor memory usage and client +- * decompressor memory usage. +- * @todo Document to what extent memory usage will be reduced +- * +- * For clients, this option is dependent on server support. Enabling it +- * via this method does not guarantee that it will be successfully +- * negotiated, only that it will be requested. +- * +- * For servers, no client support is required. Enabling this option on a +- * server will result in its use. The server will signal to clients that +- * the option will be in use so they can optimize resource usage if they +- * are able. +- */ +- void enable_server_no_context_takeover() { +- m_server_no_context_takeover = true; +- } +- +- /// Reset client's outgoing LZ77 sliding window for each new message +- /** +- * Enabling this setting will cause the client's compressor to reset the +- * compression state (the LZ77 sliding window) for every message. This +- * means that the compressor will not look back to patterns in previous +- * messages to improve compression. This will reduce the compression +- * efficiency for large messages somewhat and small messages drastically. +- * +- * This option may reduce client compressor memory usage and server +- * decompressor memory usage. +- * @todo Document to what extent memory usage will be reduced +- * +- * This option is supported by all compliant clients and servers. Enabling +- * it via either endpoint should be sufficient to ensure it is used. +- */ +- void enable_client_no_context_takeover() { +- m_client_no_context_takeover = true; +- } +- +- /// Limit server LZ77 sliding window size +- /** +- * 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 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB +- * window. The default setting is 15. +- * +- * Mode Options: +- * - accept: Accept whatever the remote endpoint offers. +- * - decline: Decline any offers to deviate from the defaults +- * - largest: Accept largest window size acceptable to both endpoints +- * - smallest: Accept smallest window size acceptiable to both endpoints +- * +- * This setting is dependent on server support. A client requesting this +- * setting may be rejected by the server or have the exact value used +- * 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 +- */ +- lib::error_code set_server_max_window_bits(uint8_t bits, mode::value mode) { +- 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; +- +- return lib::error_code(); +- } +- +- /// 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 9 +- * to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window. +- * The default setting is 15. +- * +- * Mode Options: +- * - accept: Accept whatever the remote endpoint offers. +- * - decline: Decline any offers to deviate from the defaults +- * - largest: Accept largest window size acceptable to both endpoints +- * - smallest: Accept smallest window size acceptiable to both endpoints +- * +- * This setting is dependent on client support. A client may limit its own +- * 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 +- */ +- lib::error_code set_client_max_window_bits(uint8_t bits, mode::value mode) { +- 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; +- +- return lib::error_code(); +- } +- +- /// Generate extension offer +- /** +- * Creates an offer string to include in the Sec-WebSocket-Extensions +- * header of outgoing client requests. +- * +- * @return A WebSocket extension offer string for this extension +- */ +- std::string generate_offer() const { +- // TODO: this should be dynamically generated based on user settings +- return "permessage-deflate; client_no_context_takeover; client_max_window_bits"; +- } +- +- /// Validate extension response +- /** +- * Confirm that the server has negotiated settings compatible with our +- * original offer and apply those settings to the extension state. +- * +- * @param response The server response attribute list to validate +- * @return Validation error or 0 on success +- */ +- lib::error_code validate_offer(http::attribute_list const &) { +- return lib::error_code(); +- } +- +- /// Negotiate extension +- /** +- * Confirm that the client's extension negotiation offer has settings +- * compatible with local policy. If so, generate a reply and apply those +- * settings to the extension state. +- * +- * @param offer Attribute from client's offer +- * @return Status code and value to return to remote endpoint +- */ +- err_str_pair negotiate(http::attribute_list const & offer) { +- err_str_pair ret; +- +- http::attribute_list::const_iterator it; +- for (it = offer.begin(); it != offer.end(); ++it) { +- if (it->first == "server_no_context_takeover") { +- negotiate_server_no_context_takeover(it->second,ret.first); +- } else if (it->first == "client_no_context_takeover") { +- negotiate_client_no_context_takeover(it->second,ret.first); +- } else if (it->first == "server_max_window_bits") { +- negotiate_server_max_window_bits(it->second,ret.first); +- } else if (it->first == "client_max_window_bits") { +- negotiate_client_max_window_bits(it->second,ret.first); +- } else { +- ret.first = make_error_code(error::invalid_attributes); +- } +- +- if (ret.first) { +- break; +- } +- } +- +- if (ret.first == lib::error_code()) { +- m_enabled = true; +- ret.second = generate_response(); +- } +- +- return ret; +- } +- +- /// Compress bytes +- /** +- * @todo: avail_in/out is 32 bit, need to fix for cases of >32 bit frames +- * on 64 bit machines. +- * +- * @param [in] in String to compress +- * @param [out] out String to append compressed bytes to +- * @return Error or status code +- */ +- lib::error_code compress(std::string const & in, std::string & out) { +- if (!m_initialized) { +- return make_error_code(error::uninitialized); +- } +- +- size_t output; +- +- if (in.empty()) { +- uint8_t buf[6] = {0x02, 0x00, 0x00, 0x00, 0xff, 0xff}; +- out.append((char *)(buf),6); +- return lib::error_code(); +- } +- +- m_dstate.avail_in = in.size(); +- m_dstate.next_in = (unsigned char *)(const_cast(in.data())); +- +- do { +- // Output to local buffer +- m_dstate.avail_out = m_compress_buffer_size; +- m_dstate.next_out = m_compress_buffer.get(); +- +- deflate(&m_dstate, m_flush); +- +- output = m_compress_buffer_size - m_dstate.avail_out; +- +- out.append((char *)(m_compress_buffer.get()),output); +- } while (m_dstate.avail_out == 0); +- +- return lib::error_code(); +- } +- +- /// Decompress bytes +- /** +- * @param buf Byte buffer to decompress +- * @param len Length of buf +- * @param out String to append decompressed bytes to +- * @return Error or status code +- */ +- lib::error_code decompress(uint8_t const * buf, size_t len, std::string & +- out) +- { +- if (!m_initialized) { +- return make_error_code(error::uninitialized); +- } +- +- int ret; +- +- m_istate.avail_in = len; +- m_istate.next_in = const_cast(buf); +- +- do { +- m_istate.avail_out = m_compress_buffer_size; +- m_istate.next_out = m_decompress_buffer.get(); +- +- ret = inflate(&m_istate, Z_SYNC_FLUSH); +- +- if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { +- return make_error_code(error::zlib_error); +- } +- +- out.append( +- reinterpret_cast(m_decompress_buffer.get()), +- m_compress_buffer_size - m_istate.avail_out +- ); +- } while (m_istate.avail_out == 0); +- +- return lib::error_code(); +- } +-private: +- /// Generate negotiation response +- /** +- * @return Generate extension negotiation reponse string to send to client +- */ +- std::string generate_response() { +- std::string ret = "permessage-deflate"; +- +- if (m_server_no_context_takeover) { +- ret += "; server_no_context_takeover"; +- } +- +- if (m_client_no_context_takeover) { +- ret += "; client_no_context_takeover"; +- } +- +- if (m_server_max_window_bits < default_server_max_window_bits) { +- std::stringstream s; +- s << int(m_server_max_window_bits); +- ret += "; server_max_window_bits="+s.str(); +- } +- +- if (m_client_max_window_bits < default_client_max_window_bits) { +- std::stringstream s; +- s << int(m_client_max_window_bits); +- ret += "; client_max_window_bits="+s.str(); +- } +- +- return ret; +- } +- +- /// Negotiate server_no_context_takeover attribute +- /** +- * @param [in] value The value of the attribute from the offer +- * @param [out] ec A reference to the error code to return errors via +- */ +- void negotiate_server_no_context_takeover(std::string const & value, +- lib::error_code & ec) +- { +- if (!value.empty()) { +- ec = make_error_code(error::invalid_attribute_value); +- return; +- } +- +- m_server_no_context_takeover = true; +- } +- +- /// Negotiate client_no_context_takeover attribute +- /** +- * @param [in] value The value of the attribute from the offer +- * @param [out] ec A reference to the error code to return errors via +- */ +- void negotiate_client_no_context_takeover(std::string const & value, +- lib::error_code & ec) +- { +- if (!value.empty()) { +- ec = make_error_code(error::invalid_attribute_value); +- return; +- } +- +- m_client_no_context_takeover = true; +- } +- +- /// Negotiate server_max_window_bits attribute +- /** +- * When this method starts, m_server_max_window_bits will contain the server's +- * preferred value and m_server_max_window_bits_mode will contain the mode the +- * server wants to use to for negotiation. `value` contains the value the +- * client requested that we use. +- * +- * options: +- * - 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 +- */ +- void negotiate_server_max_window_bits(std::string const & value, +- lib::error_code & ec) +- { +- uint8_t bits = uint8_t(atoi(value.c_str())); +- +- if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) { +- ec = make_error_code(error::invalid_attribute_value); +- m_server_max_window_bits = default_server_max_window_bits; +- return; +- } +- +- switch (m_server_max_window_bits_mode) { +- case mode::decline: +- m_server_max_window_bits = default_server_max_window_bits; +- break; +- case mode::accept: +- m_server_max_window_bits = bits; +- break; +- case mode::largest: +- m_server_max_window_bits = std::min(bits,m_server_max_window_bits); +- break; +- case mode::smallest: +- m_server_max_window_bits = min_server_max_window_bits; +- break; +- default: +- 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 +- /** +- * When this method starts, m_client_max_window_bits and m_c2s_max_window_mode +- * will contain the server's preferred values for window size and +- * negotiation mode. +- * +- * options: +- * - 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 +- */ +- void negotiate_client_max_window_bits(std::string const & value, +- lib::error_code & ec) +- { +- uint8_t bits = uint8_t(atoi(value.c_str())); +- +- if (value.empty()) { +- bits = default_client_max_window_bits; +- } else if (bits < min_client_max_window_bits || +- bits > max_client_max_window_bits) +- { +- ec = make_error_code(error::invalid_attribute_value); +- m_client_max_window_bits = default_client_max_window_bits; +- return; +- } +- +- switch (m_client_max_window_bits_mode) { +- case mode::decline: +- m_client_max_window_bits = default_client_max_window_bits; +- break; +- case mode::accept: +- m_client_max_window_bits = bits; +- break; +- case mode::largest: +- m_client_max_window_bits = std::min(bits,m_client_max_window_bits); +- break; +- case mode::smallest: +- m_client_max_window_bits = min_client_max_window_bits; +- break; +- default: +- 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; +- bool m_server_no_context_takeover; +- bool m_client_no_context_takeover; +- uint8_t m_server_max_window_bits; +- uint8_t m_client_max_window_bits; +- mode::value m_server_max_window_bits_mode; +- mode::value m_client_max_window_bits_mode; +- +- bool m_initialized; +- 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; +-}; +- +-} // namespace permessage_deflate +-} // namespace extensions +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP +diff --git a/src/lib/websocketpp/frame.hpp b/src/lib/websocketpp/frame.hpp +deleted file mode 100644 +index 7e17a3e..0000000 +--- a/src/lib/websocketpp/frame.hpp ++++ /dev/null +@@ -1,864 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_FRAME_HPP +-#define WEBSOCKETPP_FRAME_HPP +- +-#include +-#include +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-/// Data structures and utility functions for manipulating WebSocket frames +-/** +- * namespace frame provides a number of data structures and utility functions +- * for reading, writing, and manipulating binary encoded WebSocket frames. +- */ +-namespace frame { +- +-/// Minimum length of a WebSocket frame header. +-static unsigned int const BASIC_HEADER_LENGTH = 2; +-/// Maximum length of a WebSocket header +-static unsigned int const MAX_HEADER_LENGTH = 14; +-/// Maximum length of the variable portion of the WebSocket header +-static unsigned int const MAX_EXTENDED_HEADER_LENGTH = 12; +- +-/// Two byte conversion union +-union uint16_converter { +- uint16_t i; +- uint8_t c[2]; +-}; +- +-/// Four byte conversion union +-union uint32_converter { +- uint32_t i; +- uint8_t c[4]; +-}; +- +-/// Eight byte conversion union +-union uint64_converter { +- uint64_t i; +- uint8_t c[8]; +-}; +- +-/// Constants and utility functions related to WebSocket opcodes +-/** +- * WebSocket Opcodes are 4 bits. See RFC6455 section 5.2. +- */ +-namespace opcode { +- enum value { +- continuation = 0x0, +- text = 0x1, +- binary = 0x2, +- rsv3 = 0x3, +- rsv4 = 0x4, +- rsv5 = 0x5, +- rsv6 = 0x6, +- rsv7 = 0x7, +- close = 0x8, +- ping = 0x9, +- pong = 0xA, +- control_rsvb = 0xB, +- control_rsvc = 0xC, +- control_rsvd = 0xD, +- control_rsve = 0xE, +- control_rsvf = 0xF, +- +- CONTINUATION = 0x0, +- TEXT = 0x1, +- BINARY = 0x2, +- RSV3 = 0x3, +- RSV4 = 0x4, +- RSV5 = 0x5, +- RSV6 = 0x6, +- RSV7 = 0x7, +- CLOSE = 0x8, +- PING = 0x9, +- PONG = 0xA, +- CONTROL_RSVB = 0xB, +- CONTROL_RSVC = 0xC, +- CONTROL_RSVD = 0xD, +- CONTROL_RSVE = 0xE, +- CONTROL_RSVF = 0xF +- }; +- +- /// Check if an opcode is reserved +- /** +- * @param v The opcode to test. +- * @return Whether or not the opcode is reserved. +- */ +- inline bool reserved(value v) { +- return (v >= rsv3 && v <= rsv7) || +- (v >= control_rsvb && v <= control_rsvf); +- } +- +- /// Check if an opcode is invalid +- /** +- * Invalid opcodes are negative or require greater than 4 bits to store. +- * +- * @param v The opcode to test. +- * @return Whether or not the opcode is invalid. +- */ +- inline bool invalid(value v) { +- return (v > 0xF || v < 0); +- } +- +- /// Check if an opcode is for a control frame +- /** +- * @param v The opcode to test. +- * @return Whether or not the opcode is a control opcode. +- */ +- inline bool is_control(value v) { +- return v >= 0x8; +- } +-} +- +-/// Constants related to frame and payload limits +-namespace limits { +- /// Minimum length of a WebSocket frame header. +- static unsigned int const basic_header_length = 2; +- +- /// Maximum length of a WebSocket header +- static unsigned int const max_header_length = 14; +- +- /// Maximum length of the variable portion of the WebSocket header +- static unsigned int const max_extended_header_length = 12; +- +- /// Maximum size of a basic WebSocket payload +- static uint8_t const payload_size_basic = 125; +- +- /// Maximum size of an extended WebSocket payload (basic payload = 126) +- static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535 +- +- /// Maximum size of a jumbo WebSocket payload (basic payload = 127) +- static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL;//2^63 +- +- /// Maximum size of close frame reason +- /** +- * This is payload_size_basic - 2 bytes (as first two bytes are used for +- * the close code +- */ +- static uint8_t const close_reason_size = 123; +-} +- +- +-// masks for fields in the basic header +-static uint8_t const BHB0_OPCODE = 0x0F; +-static uint8_t const BHB0_RSV3 = 0x10; +-static uint8_t const BHB0_RSV2 = 0x20; +-static uint8_t const BHB0_RSV1 = 0x40; +-static uint8_t const BHB0_FIN = 0x80; +- +-static uint8_t const BHB1_PAYLOAD = 0x7F; +-static uint8_t const BHB1_MASK = 0x80; +- +-static uint8_t const payload_size_code_16bit = 0x7E; // 126 +-static uint8_t const payload_size_code_64bit = 0x7F; // 127 +- +-typedef uint32_converter masking_key_type; +- +-/// The constant size component of a WebSocket frame header +-struct basic_header { +- basic_header() : b0(0x00),b1(0x00) {} +- +- basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {} +- +- basic_header(opcode::value op, uint64_t size, bool fin, bool mask, +- bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00), +- b1(0x00) +- { +- if (fin) { +- b0 |= BHB0_FIN; +- } +- if (rsv1) { +- b0 |= BHB0_RSV1; +- } +- if (rsv2) { +- b0 |= BHB0_RSV2; +- } +- if (rsv3) { +- b0 |= BHB0_RSV3; +- } +- b0 |= (op & BHB0_OPCODE); +- +- if (mask) { +- b1 |= BHB1_MASK; +- } +- +- uint8_t basic_value; +- +- if (size <= limits::payload_size_basic) { +- basic_value = static_cast(size); +- } else if (size <= limits::payload_size_extended) { +- basic_value = payload_size_code_16bit; +- } else { +- basic_value = payload_size_code_64bit; +- } +- +- +- b1 |= basic_value; +- } +- +- uint8_t b0; +- uint8_t b1; +-}; +- +-/// The variable size component of a WebSocket frame header +-struct extended_header { +- extended_header() { +- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); +- } +- +- extended_header(uint64_t payload_size) { +- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); +- +- copy_payload(payload_size); +- } +- +- extended_header(uint64_t payload_size, uint32_t masking_key) { +- std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00); +- +- // Copy payload size +- int offset = copy_payload(payload_size); +- +- // Copy Masking Key +- uint32_converter temp32; +- temp32.i = masking_key; +- std::copy(temp32.c,temp32.c+4,bytes+offset); +- } +- +- uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH]; +-private: +- int copy_payload(uint64_t payload_size) { +- int payload_offset = 0; +- +- if (payload_size <= limits::payload_size_basic) { +- payload_offset = 8; +- } else if (payload_size <= limits::payload_size_extended) { +- payload_offset = 6; +- } +- +- uint64_converter temp64; +- temp64.i = lib::net::_htonll(payload_size); +- std::copy(temp64.c+payload_offset,temp64.c+8,bytes); +- +- return 8-payload_offset; +- } +-}; +- +-bool get_fin(basic_header const &h); +-void set_fin(basic_header &h, bool value); +-bool get_rsv1(basic_header const &h); +-void set_rsv1(basic_header &h, bool value); +-bool get_rsv2(basic_header const &h); +-void set_rsv2(basic_header &h, bool value); +-bool get_rsv3(basic_header const &h); +-void set_rsv3(basic_header &h, bool value); +-opcode::value get_opcode(basic_header const &h); +-bool get_masked(basic_header const &h); +-void set_masked(basic_header &h, bool value); +-uint8_t get_basic_size(basic_header const &); +-size_t get_header_len(basic_header const &); +-unsigned int get_masking_key_offset(basic_header const &); +- +-std::string write_header(basic_header const &, extended_header const &); +-masking_key_type get_masking_key(basic_header const &, extended_header const &); +-uint16_t get_extended_size(extended_header const &); +-uint64_t get_jumbo_size(extended_header const &); +-uint64_t get_payload_size(basic_header const &, extended_header const &); +- +-size_t prepare_masking_key(masking_key_type const & key); +-size_t circshift_prepared_key(size_t prepared_key, size_t offset); +- +-// Functions for performing xor based masking and unmasking +-template +-void byte_mask(input_iter b, input_iter e, output_iter o, masking_key_type +- const & key, size_t key_offset = 0); +-template +-void byte_mask(iter_type b, iter_type e, masking_key_type const & key, +- size_t key_offset = 0); +-void word_mask_exact(uint8_t * input, uint8_t * output, size_t length, +- masking_key_type const & key); +-void word_mask_exact(uint8_t * data, size_t length, masking_key_type const & +- key); +-size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length, +- size_t prepared_key); +-size_t word_mask_circ(uint8_t * data, size_t length, size_t prepared_key); +- +-/// Check whether the frame's FIN bit is set. +-/** +- * @param [in] h The basic header to extract from. +- * @return True if the header's fin bit is set. +- */ +-inline bool get_fin(basic_header const & h) { +- return ((h.b0 & BHB0_FIN) == BHB0_FIN); +-} +- +-/// Set the frame's FIN bit +-/** +- * @param [out] h Header to set. +- * @param [in] value Value to set it to. +- */ +-inline void set_fin(basic_header & h, bool value) { +- h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN); +-} +- +-/// check whether the frame's RSV1 bit is set +-/** +- * @param [in] h The basic header to extract from. +- * @return True if the header's RSV1 bit is set. +- */ +-inline bool get_rsv1(const basic_header &h) { +- return ((h.b0 & BHB0_RSV1) == BHB0_RSV1); +-} +- +-/// Set the frame's RSV1 bit +-/** +- * @param [out] h Header to set. +- * @param [in] value Value to set it to. +- */ +-inline void set_rsv1(basic_header &h, bool value) { +- h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1); +-} +- +-/// check whether the frame's RSV2 bit is set +-/** +- * @param [in] h The basic header to extract from. +- * @return True if the header's RSV2 bit is set. +- */ +-inline bool get_rsv2(const basic_header &h) { +- return ((h.b0 & BHB0_RSV2) == BHB0_RSV2); +-} +- +-/// Set the frame's RSV2 bit +-/** +- * @param [out] h Header to set. +- * @param [in] value Value to set it to. +- */ +-inline void set_rsv2(basic_header &h, bool value) { +- h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2); +-} +- +-/// check whether the frame's RSV3 bit is set +-/** +- * @param [in] h The basic header to extract from. +- * @return True if the header's RSV3 bit is set. +- */ +-inline bool get_rsv3(const basic_header &h) { +- return ((h.b0 & BHB0_RSV3) == BHB0_RSV3); +-} +- +-/// Set the frame's RSV3 bit +-/** +- * @param [out] h Header to set. +- * @param [in] value Value to set it to. +- */ +-inline void set_rsv3(basic_header &h, bool value) { +- h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3); +-} +- +-/// Extract opcode from basic header +-/** +- * @param [in] h The basic header to extract from. +- * @return The opcode value of the header. +- */ +-inline opcode::value get_opcode(const basic_header &h) { +- return opcode::value(h.b0 & BHB0_OPCODE); +-} +- +-/// check whether the frame is masked +-/** +- * @param [in] h The basic header to extract from. +- * @return True if the header mask bit is set. +- */ +-inline bool get_masked(basic_header const & h) { +- return ((h.b1 & BHB1_MASK) == BHB1_MASK); +-} +- +-/// Set the frame's MASK bit +-/** +- * @param [out] h Header to set. +- * @param value Value to set it to. +- */ +-inline void set_masked(basic_header & h, bool value) { +- h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK); +-} +- +-/// Extracts the raw payload length specified in the basic header +-/** +- * A basic WebSocket frame header contains a 7 bit value that represents the +- * payload size. There are two reserved values that are used to indicate that +- * the actual payload size will not fit in 7 bits and that the full payload +- * size is included in a separate field. The values are as follows: +- * +- * PAYLOAD_SIZE_CODE_16BIT (0x7E) indicates that the actual payload is less +- * than 16 bit +- * +- * PAYLOAD_SIZE_CODE_64BIT (0x7F) indicates that the actual payload is less +- * than 63 bit +- * +- * @param [in] h Basic header to read value from. +- * @return The exact size encoded in h. +- */ +-inline uint8_t get_basic_size(const basic_header &h) { +- return h.b1 & BHB1_PAYLOAD; +-} +- +-/// Calculates the full length of the header based on the first bytes. +-/** +- * A WebSocket frame header always has at least two bytes. Encoded within the +- * first two bytes is all the information necessary to calculate the full +- * (variable) header length. get_header_len() calculates the full header +- * length for the given two byte basic header. +- * +- * @param h Basic frame header to extract size from. +- * @return Full length of the extended header. +- */ +-inline size_t get_header_len(basic_header const & h) { +- // TODO: check extensions? +- +- // masking key offset represents the space used for the extended length +- // fields +- size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h); +- +- // If the header is masked there is a 4 byte masking key +- if (get_masked(h)) { +- size += 4; +- } +- +- return size; +-} +- +-/// Calculate the offset location of the masking key within the extended header +-/** +- * Calculate the offset location of the masking key within the extended header +- * using information from its corresponding basic header +- * +- * @param h Corresponding basic header to calculate from. +- * +- * @return byte offset of the first byte of the masking key +- */ +-inline unsigned int get_masking_key_offset(const basic_header &h) { +- if (get_basic_size(h) == payload_size_code_16bit) { +- return 2; +- } else if (get_basic_size(h) == payload_size_code_64bit) { +- return 8; +- } else { +- return 0; +- } +-} +- +-/// Generate a properly sized contiguous string that encodes a full frame header +-/** +- * Copy the basic header h and extended header e into a properly sized +- * contiguous frame header string for the purposes of writing out to the wire. +- * +- * @param h The basic header to include +- * @param e The extended header to include +- * +- * @return A contiguous string containing h and e +- */ +-inline std::string prepare_header(const basic_header &h, const +- extended_header &e) +-{ +- std::string ret; +- +- ret.push_back(char(h.b0)); +- ret.push_back(char(h.b1)); +- ret.append( +- reinterpret_cast(e.bytes), +- get_header_len(h)-BASIC_HEADER_LENGTH +- ); +- +- return ret; +-} +- +-/// Extract the masking key from a frame header +-/** +- * Note that while read and written as an integer at times, this value is not +- * an integer and should never be interpreted as one. Big and little endian +- * machines will generate and store masking keys differently without issue as +- * long as the integer values remain irrelivant. +- * +- * @param h The basic header to extract from +- * @param e The extended header to extract from +- * +- * @return The masking key as an integer. +- */ +-inline masking_key_type get_masking_key(const basic_header &h, const +- extended_header &e) +-{ +- masking_key_type temp32; +- +- if (!get_masked(h)) { +- temp32.i = 0; +- } else { +- unsigned int offset = get_masking_key_offset(h); +- std::copy(e.bytes+offset,e.bytes+offset+4,temp32.c); +- } +- +- return temp32; +-} +- +-/// Extract the extended size field from an extended header +-/** +- * It is the responsibility of the caller to verify that e is a valid extended +- * header. This function assumes that e contains an extended payload size. +- * +- * @param e The extended header to extract from +- * +- * @return The size encoded in the extended header in host byte order +- */ +-inline uint16_t get_extended_size(const extended_header &e) { +- uint16_converter temp16; +- std::copy(e.bytes,e.bytes+2,temp16.c); +- return ntohs(temp16.i); +-} +- +-/// Extract the jumbo size field from an extended header +-/** +- * It is the responsibility of the caller to verify that e is a valid extended +- * header. This function assumes that e contains a jumbo payload size. +- * +- * @param e The extended header to extract from +- * +- * @return The size encoded in the extended header in host byte order +- */ +-inline uint64_t get_jumbo_size(const extended_header &e) { +- uint64_converter temp64; +- std::copy(e.bytes,e.bytes+8,temp64.c); +- return lib::net::_ntohll(temp64.i); +-} +- +-/// Extract the full payload size field from a WebSocket header +-/** +- * It is the responsibility of the caller to verify that h and e together +- * represent a valid WebSocket frame header. This function assumes only that h +- * and e are valid. It uses information in the basic header to determine where +- * to look for the payload_size +- * +- * @param h The basic header to extract from +- * @param e The extended header to extract from +- * +- * @return The size encoded in the combined header in host byte order. +- */ +-inline uint64_t get_payload_size(const basic_header &h, const +- extended_header &e) +-{ +- uint8_t val = get_basic_size(h); +- +- if (val <= limits::payload_size_basic) { +- return val; +- } else if (val == payload_size_code_16bit) { +- return get_extended_size(e); +- } else { +- return get_jumbo_size(e); +- } +-} +- +-/// Extract a masking key into a value the size of a machine word. +-/** +- * Machine word size must be 4 or 8. +- * +- * @param key Masking key to extract from +- * +- * @return prepared key as a machine word +- */ +-inline size_t prepare_masking_key(const masking_key_type& key) { +- size_t low_bits = static_cast(key.i); +- +- if (sizeof(size_t) == 8) { +- uint64_t high_bits = static_cast(key.i); +- return static_cast((high_bits << 32) | low_bits); +- } else { +- return low_bits; +- } +-} +- +-/// circularly shifts the supplied prepared masking key by offset bytes +-/** +- * Prepared_key must be the output of prepare_masking_key with the associated +- * restrictions on the machine word size. offset must be greater than or equal +- * 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; +- } else { +- size_t temp = prepared_key >> (sizeof(size_t)-offset)*8; +- return (prepared_key << offset*8) | temp; +- } +-} +- +-/// Byte by byte mask/unmask +-/** +- * Iterator based byte by byte masking and unmasking for WebSocket payloads. +- * Performs masking in place using the supplied key offset by the supplied +- * offset number of bytes. +- * +- * This function is simple and can be done in place on input with arbitrary +- * lengths and does not vary based on machine word size. It is slow. +- * +- * @param b Beginning iterator to start masking +- * +- * @param e Ending iterator to end masking +- * +- * @param o Beginning iterator to store masked results +- * +- * @param key 32 bit key to mask with. +- * +- * @param key_offset offset value to start masking at. +- */ +-template +-void byte_mask(input_iter first, input_iter last, output_iter result, +- masking_key_type const & key, size_t key_offset) +-{ +- size_t key_index = key_offset%4; +- while (first != last) { +- *result = *first ^ key.c[key_index++]; +- key_index %= 4; +- ++result; +- ++first; +- } +-} +- +-/// Byte by byte mask/unmask (in place) +-/** +- * Iterator based byte by byte masking and unmasking for WebSocket payloads. +- * Performs masking in place using the supplied key offset by the supplied +- * offset number of bytes. +- * +- * This function is simple and can be done in place on input with arbitrary +- * lengths and does not vary based on machine word size. It is slow. +- * +- * @param b Beginning iterator to start masking +- * +- * @param e Ending iterator to end masking +- * +- * @param key 32 bit key to mask with. +- * +- * @param key_offset offset value to start masking at. +- */ +-template +-void byte_mask(iter_type b, iter_type e, masking_key_type const & key, +- size_t key_offset) +-{ +- byte_mask(b,e,b,key,key_offset); +-} +- +-/// Exact word aligned mask/unmask +-/** +- * Balanced combination of byte by byte and circular word by word masking. +- * Best used to mask complete messages at once. Has much higher setup costs than +- * word_mask_circ but works with exact sized buffers. +- * +- * Buffer based word by word masking and unmasking for WebSocket payloads. +- * Masking is done in word by word chunks with the remainder not divisible by +- * the word size done byte by byte. +- * +- * input and output must both be at least length bytes. Exactly length bytes +- * will be written. +- * +- * @param input buffer to mask or unmask +- * +- * @param output buffer to store the output. May be the same as input. +- * +- * @param length length of data buffer +- * +- * @param key Masking key to use +- */ +-inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length, +- const masking_key_type& key) +-{ +- size_t prepared_key = prepare_masking_key(key); +- size_t n = length/sizeof(size_t); +- size_t* input_word = reinterpret_cast(input); +- size_t* output_word = reinterpret_cast(output); +- +- for (size_t i = 0; i < n; i++) { +- output_word[i] = input_word[i] ^ prepared_key; +- } +- +- for (size_t i = n*sizeof(size_t); i < length; i++) { +- output[i] = input[i] ^ key.c[i%4]; +- } +-} +- +-/// Exact word aligned mask/unmask (in place) +-/** +- * In place version of word_mask_exact +- * +- * @see word_mask_exact +- * +- * @param data buffer to read and write from +- * +- * @param length length of data buffer +- * +- * @param key Masking key to use +- */ +-inline void word_mask_exact(uint8_t* data, size_t length, const +- masking_key_type& key) +-{ +- word_mask_exact(data,data,length,key); +-} +- +-/// Circular word aligned mask/unmask +-/** +- * Performs a circular mask/unmask in word sized chunks using pre-prepared keys +- * that store state between calls. Best for providing streaming masking or +- * unmasking of small chunks at a time of a larger message. Requires that the +- * underlying allocated size of the data buffer be a multiple of the word size. +- * Data in the buffer after `length` will be overwritten only with the same +- * values that were originally present. +- * +- * Buffer based word by word masking and unmasking for WebSocket payloads. +- * Performs masking in place using the supplied key. Casts the data buffer to +- * an array of size_t's and performs masking word by word. The underlying +- * buffer size must be a muliple of the word size. +- * +- * word_mask returns a copy of prepared_key circularly shifted based on the +- * length value. The returned value may be fed back into word_mask when more +- * data is available. +- * +- * input and output must both have length at least: +- * ceil(length/sizeof(size_t))*sizeof(size_t) +- * Exactly that many bytes will be written, although only exactly length bytes +- * will be changed (trailing bytes will be replaced without masking) +- * +- * @param data Character buffer to mask +- * +- * @param length Length of data +- * +- * @param prepared_key Prepared key to use. +- * +- * @return the prepared_key shifted to account for the input length +- */ +-inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length, +- size_t prepared_key) +-{ +- size_t n = length / sizeof(size_t); // whole words +- size_t l = length - (n * sizeof(size_t)); // remaining bytes +- size_t * input_word = reinterpret_cast(input); +- size_t * output_word = reinterpret_cast(output); +- +- // mask word by word +- for (size_t i = 0; i < n; i++) { +- output_word[i] = input_word[i] ^ prepared_key; +- } +- +- // mask partial word at the end +- size_t start = length - l; +- uint8_t * byte_key = reinterpret_cast(&prepared_key); +- for (size_t i = 0; i < l; ++i) { +- output[start+i] = input[start+i] ^ byte_key[i]; +- } +- +- return circshift_prepared_key(prepared_key,l); +-} +- +-/// Circular word aligned mask/unmask (in place) +-/** +- * In place version of word_mask_circ +- * +- * @see word_mask_circ +- * +- * @param data Character buffer to read from and write to +- * +- * @param length Length of data +- * +- * @param prepared_key Prepared key to use. +- * +- * @return the prepared_key shifted to account for the input length +- */ +-inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){ +- return word_mask_circ(data,data,length,prepared_key); +-} +- +-/// Circular byte aligned mask/unmask +-/** +- * Performs a circular mask/unmask in byte sized chunks using pre-prepared keys +- * that store state between calls. Best for providing streaming masking or +- * unmasking of small chunks at a time of a larger message. Requires that the +- * underlying allocated size of the data buffer be a multiple of the word size. +- * Data in the buffer after `length` will be overwritten only with the same +- * values that were originally present. +- * +- * word_mask returns a copy of prepared_key circularly shifted based on the +- * length value. The returned value may be fed back into byte_mask when more +- * data is available. +- * +- * @param data Character buffer to mask +- * +- * @param length Length of data +- * +- * @param prepared_key Prepared key to use. +- * +- * @return the prepared_key shifted to account for the input length +- */ +-inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length, +- size_t prepared_key) +-{ +- uint32_converter key; +- key.i = prepared_key; +- +- for (size_t i = 0; i < length; ++i) { +- output[i] = input[i] ^ key.c[i % 4]; +- } +- +- return circshift_prepared_key(prepared_key,length % 4); +-} +- +-/// Circular byte aligned mask/unmask (in place) +-/** +- * In place version of byte_mask_circ +- * +- * @see byte_mask_circ +- * +- * @param data Character buffer to read from and write to +- * +- * @param length Length of data +- * +- * @param prepared_key Prepared key to use. +- * +- * @return the prepared_key shifted to account for the input length +- */ +-inline size_t byte_mask_circ(uint8_t* data, size_t length, size_t prepared_key){ +- return byte_mask_circ(data,data,length,prepared_key); +-} +- +-} // namespace frame +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_FRAME_HPP +diff --git a/src/lib/websocketpp/http/constants.hpp b/src/lib/websocketpp/http/constants.hpp +deleted file mode 100644 +index 27b6954..0000000 +--- a/src/lib/websocketpp/http/constants.hpp ++++ /dev/null +@@ -1,308 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_CONSTANTS_HPP +-#define HTTP_CONSTANTS_HPP +- +-#include +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-/// HTTP handling support +-namespace http { +- /// The type of an HTTP attribute list +- /** +- * The attribute list is an unordered key/value map. Encoded attribute +- * values are delimited by semicolons. +- */ +- typedef std::map attribute_list; +- +- /// The type of an HTTP parameter list +- /** +- * The parameter list is an ordered pairing of a parameter and its +- * associated attribute list. Encoded parameter values are delimited by +- * commas. +- */ +- typedef std::vector< std::pair > parameter_list; +- +- /// Literal value of the HTTP header delimiter +- static char const header_delimiter[] = "\r\n"; +- +- /// Literal value of the HTTP header separator +- static char const header_separator[] = ":"; +- +- /// Literal value of an empty header +- static std::string const empty_header; +- +- /// Maximum size in bytes before rejecting an HTTP header as too big. +- size_t const max_header_size = 16000; +- +- /// Default Maximum size in bytes for HTTP message bodies. +- size_t const max_body_size = 32000000; +- +- /// Number of bytes to use for temporary istream read buffers +- size_t const istream_buffer = 512; +- +- /// invalid HTTP token characters +- /** +- * 0x00 - 0x32, 0x7f-0xff +- * ( ) < > @ , ; : \ " / [ ] ? = { } +- */ +- static char const header_token[] = { +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..0f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 10..1f +- 0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0, // 20..2f +- 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 30..3f +- 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 40..4f +- 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1, // 50..5f +- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 60..6f +- 1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0, // 70..7f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 80..8f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 90..9f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // a0..af +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // b0..bf +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // c0..cf +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // d0..df +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // e0..ef +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // f0..ff +- }; +- +- /// Is the character a token +- inline bool is_token_char(unsigned char c) { +- return (header_token[c] == 1); +- } +- +- /// Is the character a non-token +- inline bool is_not_token_char(unsigned char c) { +- return !header_token[c]; +- } +- +- /// Is the character whitespace +- /** +- * whitespace is space (32) or horizontal tab (9) +- */ +- inline bool is_whitespace_char(unsigned char c) { +- return (c == 9 || c == 32); +- } +- +- /// Is the character non-whitespace +- inline bool is_not_whitespace_char(unsigned char c) { +- return (c != 9 && c != 32); +- } +- +- /// HTTP Status codes +- namespace status_code { +- enum value { +- uninitialized = 0, +- +- continue_code = 100, +- switching_protocols = 101, +- +- ok = 200, +- created = 201, +- accepted = 202, +- non_authoritative_information = 203, +- no_content = 204, +- reset_content = 205, +- partial_content = 206, +- +- multiple_choices = 300, +- moved_permanently = 301, +- found = 302, +- see_other = 303, +- not_modified = 304, +- use_proxy = 305, +- temporary_redirect = 307, +- +- bad_request = 400, +- unauthorized = 401, +- payment_required = 402, +- forbidden = 403, +- not_found = 404, +- method_not_allowed = 405, +- not_acceptable = 406, +- proxy_authentication_required = 407, +- request_timeout = 408, +- conflict = 409, +- gone = 410, +- length_required = 411, +- precondition_failed = 412, +- request_entity_too_large = 413, +- request_uri_too_long = 414, +- unsupported_media_type = 415, +- request_range_not_satisfiable = 416, +- expectation_failed = 417, +- im_a_teapot = 418, +- upgrade_required = 426, +- precondition_required = 428, +- too_many_requests = 429, +- request_header_fields_too_large = 431, +- +- internal_server_error = 500, +- not_implemented = 501, +- bad_gateway = 502, +- service_unavailable = 503, +- gateway_timeout = 504, +- http_version_not_supported = 505, +- not_extended = 510, +- network_authentication_required = 511 +- }; +- +- // TODO: should this be inline? +- inline std::string get_string(value c) { +- switch (c) { +- case uninitialized: +- return "Uninitialized"; +- case continue_code: +- return "Continue"; +- case switching_protocols: +- return "Switching Protocols"; +- case ok: +- return "OK"; +- case created: +- return "Created"; +- case accepted: +- return "Accepted"; +- case non_authoritative_information: +- return "Non Authoritative Information"; +- case no_content: +- return "No Content"; +- case reset_content: +- return "Reset Content"; +- case partial_content: +- return "Partial Content"; +- case multiple_choices: +- return "Multiple Choices"; +- case moved_permanently: +- return "Moved Permanently"; +- case found: +- return "Found"; +- case see_other: +- return "See Other"; +- case not_modified: +- return "Not Modified"; +- case use_proxy: +- return "Use Proxy"; +- case temporary_redirect: +- return "Temporary Redirect"; +- case bad_request: +- return "Bad Request"; +- case unauthorized: +- return "Unauthorized"; +- case payment_required: +- return "Payment Required"; +- case forbidden: +- return "Forbidden"; +- case not_found: +- return "Not Found"; +- case method_not_allowed: +- return "Method Not Allowed"; +- case not_acceptable: +- return "Not Acceptable"; +- case proxy_authentication_required: +- return "Proxy Authentication Required"; +- case request_timeout: +- return "Request Timeout"; +- case conflict: +- return "Conflict"; +- case gone: +- return "Gone"; +- case length_required: +- return "Length Required"; +- case precondition_failed: +- return "Precondition Failed"; +- case request_entity_too_large: +- return "Request Entity Too Large"; +- case request_uri_too_long: +- return "Request-URI Too Long"; +- case unsupported_media_type: +- return "Unsupported Media Type"; +- case request_range_not_satisfiable: +- return "Requested Range Not Satisfiable"; +- case expectation_failed: +- return "Expectation Failed"; +- case im_a_teapot: +- return "I'm a teapot"; +- case upgrade_required: +- return "Upgrade Required"; +- case precondition_required: +- return "Precondition Required"; +- case too_many_requests: +- return "Too Many Requests"; +- case request_header_fields_too_large: +- return "Request Header Fields Too Large"; +- case internal_server_error: +- return "Internal Server Error"; +- case not_implemented: +- return "Not Implemented"; +- case bad_gateway: +- return "Bad Gateway"; +- case service_unavailable: +- return "Service Unavailable"; +- case gateway_timeout: +- return "Gateway Timeout"; +- case http_version_not_supported: +- return "HTTP Version Not Supported"; +- case not_extended: +- return "Not Extended"; +- case network_authentication_required: +- return "Network Authentication Required"; +- default: +- return "Unknown"; +- } +- } +- } +- +- class exception : public std::exception { +- public: +- exception(const std::string& log_msg, +- status_code::value error_code, +- const std::string& error_msg = std::string(), +- const std::string& body = std::string()) +- : m_msg(log_msg) +- , m_error_msg(error_msg) +- , m_body(body) +- , m_error_code(error_code) {} +- +- ~exception() throw() {} +- +- virtual const char* what() const throw() { +- return m_msg.c_str(); +- } +- +- std::string m_msg; +- std::string m_error_msg; +- std::string m_body; +- status_code::value m_error_code; +- }; +-} +-} +- +-#endif // HTTP_CONSTANTS_HPP +diff --git a/src/lib/websocketpp/http/impl/parser.hpp b/src/lib/websocketpp/http/impl/parser.hpp +deleted file mode 100644 +index 4b347a9..0000000 +--- a/src/lib/websocketpp/http/impl/parser.hpp ++++ /dev/null +@@ -1,200 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_IMPL_HPP +-#define HTTP_PARSER_IMPL_HPP +- +-#include +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-inline void parser::set_version(std::string const & version) { +- m_version = version; +-} +- +-inline std::string const & parser::get_header(std::string const & key) const { +- header_list::const_iterator h = m_headers.find(key); +- +- if (h == m_headers.end()) { +- return empty_header; +- } else { +- return h->second; +- } +-} +- +-inline bool parser::get_header_as_plist(std::string const & key, +- parameter_list & out) const +-{ +- header_list::const_iterator it = m_headers.find(key); +- +- if (it == m_headers.end() || it->second.size() == 0) { +- return false; +- } +- +- return this->parse_parameter_list(it->second,out); +-} +- +-inline void parser::append_header(std::string const & key, std::string const & +- val) +-{ +- if (std::find_if(key.begin(),key.end(),is_not_token_char) != key.end()) { +- throw exception("Invalid header name",status_code::bad_request); +- } +- +- if (this->get_header(key).empty()) { +- m_headers[key] = val; +- } else { +- m_headers[key] += ", " + val; +- } +-} +- +-inline void parser::replace_header(std::string const & key, std::string const & +- val) +-{ +- m_headers[key] = val; +-} +- +-inline void parser::remove_header(std::string const & key) { +- m_headers.erase(key); +-} +- +-inline void parser::set_body(std::string const & value) { +- if (value.size() == 0) { +- remove_header("Content-Length"); +- m_body.clear(); +- return; +- } +- +- // TODO: should this method respect the max size? If so how should errors +- // be indicated? +- +- std::stringstream len; +- len << value.size(); +- replace_header("Content-Length", len.str()); +- m_body = value; +-} +- +-inline bool parser::parse_parameter_list(std::string const & in, +- parameter_list & out) const +-{ +- if (in.size() == 0) { +- return false; +- } +- +- std::string::const_iterator it; +- it = extract_parameters(in.begin(),in.end(),out); +- return (it == in.begin()); +-} +- +-inline bool parser::prepare_body() { +- if (!get_header("Content-Length").empty()) { +- std::string const & cl_header = get_header("Content-Length"); +- char * end; +- +- // TODO: not 100% sure what the compatibility of this method is. Also, +- // I believe this will only work up to 32bit sizes. Is there a need for +- // > 4GiB HTTP payloads? +- m_body_bytes_needed = std::strtoul(cl_header.c_str(),&end,10); +- +- if (m_body_bytes_needed > m_body_bytes_max) { +- throw exception("HTTP message body too large", +- status_code::request_entity_too_large); +- } +- +- m_body_encoding = body_encoding::plain; +- return true; +- } else if (get_header("Transfer-Encoding") == "chunked") { +- // TODO +- //m_body_encoding = body_encoding::chunked; +- return false; +- } else { +- return false; +- } +-} +- +-inline size_t parser::process_body(char const * buf, size_t len) { +- if (m_body_encoding == body_encoding::plain) { +- size_t processed = (std::min)(m_body_bytes_needed,len); +- m_body.append(buf,processed); +- m_body_bytes_needed -= processed; +- return processed; +- } else if (m_body_encoding == body_encoding::chunked) { +- // TODO: +- throw exception("Unexpected body encoding", +- status_code::internal_server_error); +- } else { +- throw exception("Unexpected body encoding", +- status_code::internal_server_error); +- } +-} +- +-inline void parser::process_header(std::string::iterator begin, +- std::string::iterator end) +-{ +- std::string::iterator cursor = std::search( +- begin, +- end, +- header_separator, +- header_separator + sizeof(header_separator) - 1 +- ); +- +- if (cursor == end) { +- throw exception("Invalid header line",status_code::bad_request); +- } +- +- append_header(strip_lws(std::string(begin,cursor)), +- strip_lws(std::string(cursor+sizeof(header_separator)-1,end))); +-} +- +-inline header_list const & parser::get_headers() const { +- return m_headers; +-} +- +-inline std::string parser::raw_headers() const { +- std::stringstream raw; +- +- header_list::const_iterator it; +- for (it = m_headers.begin(); it != m_headers.end(); it++) { +- raw << it->first << ": " << it->second << "\r\n"; +- } +- +- return raw.str(); +-} +- +- +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#endif // HTTP_PARSER_IMPL_HPP +diff --git a/src/lib/websocketpp/http/impl/request.hpp b/src/lib/websocketpp/http/impl/request.hpp +deleted file mode 100644 +index b40377f..0000000 +--- a/src/lib/websocketpp/http/impl/request.hpp ++++ /dev/null +@@ -1,191 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_REQUEST_IMPL_HPP +-#define HTTP_PARSER_REQUEST_IMPL_HPP +- +-#include +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-inline size_t request::consume(char const * buf, size_t len) { +- size_t bytes_processed; +- +- if (m_ready) {return 0;} +- +- if (m_body_bytes_needed > 0) { +- bytes_processed = process_body(buf,len); +- if (body_ready()) { +- m_ready = true; +- } +- return bytes_processed; +- } +- +- // copy new header bytes into buffer +- m_buf->append(buf,len); +- +- // Search for delimiter in buf. If found read until then. If not read all +- std::string::iterator begin = m_buf->begin(); +- std::string::iterator end; +- +- for (;;) { +- // search for line delimiter +- end = std::search( +- begin, +- m_buf->end(), +- header_delimiter, +- header_delimiter+sizeof(header_delimiter)-1 +- ); +- +- m_header_bytes += (end-begin+sizeof(header_delimiter)); +- +- if (m_header_bytes > max_header_size) { +- // exceeded max header size +- throw exception("Maximum header size exceeded.", +- status_code::request_header_fields_too_large); +- } +- +- if (end == m_buf->end()) { +- // we are out of bytes. Discard the processed bytes and copy the +- // remaining unprecessed bytes to the beginning of the buffer +- std::copy(begin,end,m_buf->begin()); +- m_buf->resize(static_cast(end-begin)); +- m_header_bytes -= m_buf->size(); +- +- return len; +- } +- +- //the range [begin,end) now represents a line to be processed. +- if (end-begin == 0) { +- // we got a blank line +- if (m_method.empty() || get_header("Host").empty()) { +- throw exception("Incomplete Request",status_code::bad_request); +- } +- +- bytes_processed = ( +- len - static_cast(m_buf->end()-end) +- + sizeof(header_delimiter) - 1 +- ); +- +- // frees memory used temporarily during request parsing +- m_buf.reset(); +- +- // if this was not an upgrade request and has a content length +- // continue capturing content-length bytes and expose them as a +- // request body. +- +- if (prepare_body()) { +- bytes_processed += process_body(buf+bytes_processed,len-bytes_processed); +- if (body_ready()) { +- m_ready = true; +- } +- return bytes_processed; +- } else { +- m_ready = true; +- +- // return number of bytes processed (starting bytes - bytes left) +- return bytes_processed; +- } +- } else { +- if (m_method.empty()) { +- this->process(begin,end); +- } else { +- this->process_header(begin,end); +- } +- } +- +- begin = end+(sizeof(header_delimiter)-1); +- } +-} +- +-inline std::string request::raw() const { +- // TODO: validation. Make sure all required fields have been set? +- std::stringstream ret; +- +- ret << m_method << " " << m_uri << " " << get_version() << "\r\n"; +- ret << raw_headers() << "\r\n" << m_body; +- +- return ret.str(); +-} +- +-inline std::string request::raw_head() const { +- // TODO: validation. Make sure all required fields have been set? +- std::stringstream ret; +- +- ret << m_method << " " << m_uri << " " << get_version() << "\r\n"; +- ret << raw_headers() << "\r\n"; +- +- return ret.str(); +-} +- +-inline void request::set_method(std::string const & method) { +- if (std::find_if(method.begin(),method.end(),is_not_token_char) != method.end()) { +- throw exception("Invalid method token.",status_code::bad_request); +- } +- +- m_method = method; +-} +- +-inline void request::set_uri(std::string const & uri) { +- // TODO: validation? +- m_uri = uri; +-} +- +-inline void request::process(std::string::iterator begin, std::string::iterator +- end) +-{ +- std::string::iterator cursor_start = begin; +- std::string::iterator cursor_end = std::find(begin,end,' '); +- +- if (cursor_end == end) { +- throw exception("Invalid request line1",status_code::bad_request); +- } +- +- set_method(std::string(cursor_start,cursor_end)); +- +- cursor_start = cursor_end+1; +- cursor_end = std::find(cursor_start,end,' '); +- +- if (cursor_end == end) { +- throw exception("Invalid request line2",status_code::bad_request); +- } +- +- set_uri(std::string(cursor_start,cursor_end)); +- set_version(std::string(cursor_end+1,end)); +-} +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#endif // HTTP_PARSER_REQUEST_IMPL_HPP +diff --git a/src/lib/websocketpp/http/impl/response.hpp b/src/lib/websocketpp/http/impl/response.hpp +deleted file mode 100644 +index 833805f..0000000 +--- a/src/lib/websocketpp/http/impl/response.hpp ++++ /dev/null +@@ -1,266 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_RESPONSE_IMPL_HPP +-#define HTTP_PARSER_RESPONSE_IMPL_HPP +- +-#include +-#include +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-inline size_t response::consume(char const * buf, size_t len) { +- if (m_state == DONE) {return 0;} +- +- if (m_state == BODY) { +- return this->process_body(buf,len); +- } +- +- // copy new header bytes into buffer +- m_buf->append(buf,len); +- +- // Search for delimiter in buf. If found read until then. If not read all +- std::string::iterator begin = m_buf->begin(); +- std::string::iterator end = begin; +- +- +- for (;;) { +- // search for delimiter +- end = std::search( +- begin, +- m_buf->end(), +- header_delimiter, +- header_delimiter + sizeof(header_delimiter) - 1 +- ); +- +- m_header_bytes += (end-begin+sizeof(header_delimiter)); +- +- if (m_header_bytes > max_header_size) { +- // exceeded max header size +- throw exception("Maximum header size exceeded.", +- status_code::request_header_fields_too_large); +- } +- +- if (end == m_buf->end()) { +- // we are out of bytes. Discard the processed bytes and copy the +- // remaining unprecessed bytes to the beginning of the buffer +- std::copy(begin,end,m_buf->begin()); +- m_buf->resize(static_cast(end-begin)); +- +- m_read += len; +- m_header_bytes -= m_buf->size(); +- +- return len; +- } +- +- //the range [begin,end) now represents a line to be processed. +- +- if (end-begin == 0) { +- // we got a blank line +- if (m_state == RESPONSE_LINE) { +- throw exception("Incomplete Request",status_code::bad_request); +- } +- +- // TODO: grab content-length +- std::string length = get_header("Content-Length"); +- +- if (length.empty()) { +- // no content length found, read indefinitely +- m_read = 0; +- } else { +- std::istringstream ss(length); +- +- if ((ss >> m_read).fail()) { +- throw exception("Unable to parse Content-Length header", +- status_code::bad_request); +- } +- } +- +- m_state = BODY; +- +- // calc header bytes processed (starting bytes - bytes left) +- size_t read = ( +- len - static_cast(m_buf->end() - end) +- + sizeof(header_delimiter) - 1 +- ); +- +- // if there were bytes left process them as body bytes +- if (read < len) { +- read += this->process_body(buf+read,(len-read)); +- } +- +- // frees memory used temporarily during header parsing +- m_buf.reset(); +- +- return read; +- } else { +- if (m_state == RESPONSE_LINE) { +- this->process(begin,end); +- m_state = HEADERS; +- } else { +- this->process_header(begin,end); +- } +- } +- +- begin = end+(sizeof(header_delimiter) - 1); +- } +-} +- +-inline size_t response::consume(std::istream & s) { +- char buf[istream_buffer]; +- size_t bytes_read; +- size_t bytes_processed; +- size_t total = 0; +- +- while (s.good()) { +- s.getline(buf,istream_buffer); +- bytes_read = static_cast(s.gcount()); +- +- if (s.fail() || s.eof()) { +- bytes_processed = this->consume(buf,bytes_read); +- total += bytes_processed; +- +- if (bytes_processed != bytes_read) { +- // problem +- break; +- } +- } else if (s.bad()) { +- // problem +- break; +- } else { +- // the delimiting newline was found. Replace the trailing null with +- // the newline that was discarded, since our raw consume function +- // expects the newline to be be there. +- buf[bytes_read-1] = '\n'; +- bytes_processed = this->consume(buf,bytes_read); +- total += bytes_processed; +- +- if (bytes_processed != bytes_read) { +- // problem +- break; +- } +- } +- } +- +- return total; +-} +- +-inline std::string response::raw() const { +- // TODO: validation. Make sure all required fields have been set? +- +- std::stringstream ret; +- +- ret << get_version() << " " << m_status_code << " " << m_status_msg; +- ret << "\r\n" << raw_headers() << "\r\n"; +- +- ret << m_body; +- +- return ret.str(); +-} +- +-inline void response::set_status(status_code::value code) { +- // TODO: validation? +- m_status_code = code; +- m_status_msg = get_string(code); +-} +- +-inline void response::set_status(status_code::value code, std::string const & +- msg) +-{ +- // TODO: validation? +- m_status_code = code; +- m_status_msg = msg; +-} +- +-inline void response::process(std::string::iterator begin, +- std::string::iterator end) +-{ +- std::string::iterator cursor_start = begin; +- std::string::iterator cursor_end = std::find(begin,end,' '); +- +- if (cursor_end == end) { +- throw exception("Invalid response line",status_code::bad_request); +- } +- +- set_version(std::string(cursor_start,cursor_end)); +- +- cursor_start = cursor_end+1; +- cursor_end = std::find(cursor_start,end,' '); +- +- if (cursor_end == end) { +- throw exception("Invalid request line",status_code::bad_request); +- } +- +- int code; +- +- std::istringstream ss(std::string(cursor_start,cursor_end)); +- +- if ((ss >> code).fail()) { +- throw exception("Unable to parse response code",status_code::bad_request); +- } +- +- set_status(status_code::value(code),std::string(cursor_end+1,end)); +-} +- +-inline size_t response::process_body(char const * buf, size_t len) { +- // If no content length was set then we read forever and never set m_ready +- if (m_read == 0) { +- //m_body.append(buf,len); +- //return len; +- m_state = DONE; +- return 0; +- } +- +- // Otherwise m_read is the number of bytes left. +- size_t to_read; +- +- if (len >= m_read) { +- // if we have more bytes than we need read, read only the amount needed +- // then set done state +- to_read = m_read; +- m_state = DONE; +- } else { +- // we need more bytes than are available, read them all +- to_read = len; +- } +- +- m_body.append(buf,to_read); +- m_read -= to_read; +- return to_read; +-} +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#endif // HTTP_PARSER_RESPONSE_IMPL_HPP +diff --git a/src/lib/websocketpp/http/parser.hpp b/src/lib/websocketpp/http/parser.hpp +deleted file mode 100644 +index d124e03..0000000 +--- a/src/lib/websocketpp/http/parser.hpp ++++ /dev/null +@@ -1,629 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_HPP +-#define HTTP_PARSER_HPP +- +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-namespace state { +- enum value { +- method, +- resource, +- version, +- headers +- }; +-} +- +-namespace body_encoding { +- enum value { +- unknown, +- plain, +- chunked +- }; +-} +- +-typedef std::map header_list; +- +-/// Read and return the next token in the stream +-/** +- * Read until a non-token character is found and then return the token and +- * iterator to the next character to read +- * +- * @param begin An iterator to the beginning of the sequence +- * @param end An iterator to the end of the sequence +- * @return A pair containing the token and an iterator to the next character in +- * the stream +- */ +-template +-std::pair extract_token(InputIterator begin, +- InputIterator end) +-{ +- InputIterator it = std::find_if(begin,end,&is_not_token_char); +- return std::make_pair(std::string(begin,it),it); +-} +- +-/// Read and return the next quoted string in the stream +-/** +- * Read a double quoted string starting at `begin`. The quotes themselves are +- * stripped. The quoted value is returned along with an iterator to the next +- * character to read +- * +- * @param begin An iterator to the beginning of the sequence +- * @param end An iterator to the end of the sequence +- * @return A pair containing the string read and an iterator to the next +- * character in the stream +- */ +-template +-std::pair extract_quoted_string(InputIterator begin, +- InputIterator end) +-{ +- std::string s; +- +- if (end == begin) { +- return std::make_pair(s,begin); +- } +- +- if (*begin != '"') { +- return std::make_pair(s,begin); +- } +- +- InputIterator cursor = begin+1; +- InputIterator marker = cursor; +- +- cursor = std::find(cursor,end,'"'); +- +- while (cursor != end) { +- // either this is the end or a quoted string +- if (*(cursor-1) == '\\') { +- s.append(marker,cursor-1); +- s.append(1,'"'); +- ++cursor; +- marker = cursor; +- } else { +- s.append(marker,cursor); +- ++cursor; +- return std::make_pair(s,cursor); +- } +- +- cursor = std::find(cursor,end,'"'); +- } +- +- return std::make_pair("",begin); +-} +- +-/// Read and discard one unit of linear whitespace +-/** +- * Read one unit of linear white space and return the iterator to the character +- * afterwards. If `begin` is returned, no whitespace was extracted. +- * +- * @param begin An iterator to the beginning of the sequence +- * @param end An iterator to the end of the sequence +- * @return An iterator to the character after the linear whitespace read +- */ +-template +-InputIterator extract_lws(InputIterator begin, InputIterator end) { +- InputIterator it = begin; +- +- // strip leading CRLF +- if (end-begin > 2 && *begin == '\r' && *(begin+1) == '\n' && +- is_whitespace_char(static_cast(*(begin+2)))) +- { +- it+=3; +- } +- +- it = std::find_if(it,end,&is_not_whitespace_char); +- return it; +-} +- +-/// Read and discard linear whitespace +-/** +- * Read linear white space until a non-lws character is read and return an +- * iterator to that character. If `begin` is returned, no whitespace was +- * extracted. +- * +- * @param begin An iterator to the beginning of the sequence +- * @param end An iterator to the end of the sequence +- * @return An iterator to the character after the linear whitespace read +- */ +-template +-InputIterator extract_all_lws(InputIterator begin, InputIterator end) { +- InputIterator old_it; +- InputIterator new_it = begin; +- +- do { +- // Pull value from previous iteration +- old_it = new_it; +- +- // look ahead another pass +- new_it = extract_lws(old_it,end); +- } while (new_it != end && old_it != new_it); +- +- return new_it; +-} +- +-/// Extract HTTP attributes +-/** +- * An http attributes list is a semicolon delimited list of key value pairs in +- * the format: *( ";" attribute "=" value ) where attribute is a token and value +- * is a token or quoted string. +- * +- * Attributes extracted are appended to the supplied attributes list +- * `attributes`. +- * +- * @param [in] begin An iterator to the beginning of the sequence +- * @param [in] end An iterator to the end of the sequence +- * @param [out] attributes A reference to the attributes list to append +- * attribute/value pairs extracted to +- * @return An iterator to the character after the last atribute read +- */ +-template +-InputIterator extract_attributes(InputIterator begin, InputIterator end, +- attribute_list & attributes) +-{ +- InputIterator cursor; +- bool first = true; +- +- if (begin == end) { +- return begin; +- } +- +- cursor = begin; +- std::pair ret; +- +- while (cursor != end) { +- std::string name; +- +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end) { +- break; +- } +- +- if (first) { +- // ignore this check for the very first pass +- first = false; +- } else { +- if (*cursor == ';') { +- // advance past the ';' +- ++cursor; +- } else { +- // non-semicolon in this position indicates end end of the +- // attribute list, break and return. +- break; +- } +- } +- +- cursor = http::parser::extract_all_lws(cursor,end); +- ret = http::parser::extract_token(cursor,end); +- +- if (ret.first.empty()) { +- // error: expected a token +- return begin; +- } else { +- name = ret.first; +- cursor = ret.second; +- } +- +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end || *cursor != '=') { +- // if there is an equals sign, read the attribute value. Otherwise +- // record a blank value and continue +- attributes[name].clear(); +- continue; +- } +- +- // advance past the '=' +- ++cursor; +- +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end) { +- // error: expected a token or quoted string +- return begin; +- } +- +- ret = http::parser::extract_quoted_string(cursor,end); +- if (ret.second != cursor) { +- attributes[name] = ret.first; +- cursor = ret.second; +- continue; +- } +- +- ret = http::parser::extract_token(cursor,end); +- if (ret.first.empty()) { +- // error : expected token or quoted string +- return begin; +- } else { +- attributes[name] = ret.first; +- cursor = ret.second; +- } +- } +- +- return cursor; +-} +- +-/// Extract HTTP parameters +-/** +- * An http parameters list is a comma delimited list of tokens followed by +- * optional semicolon delimited attributes lists. +- * +- * Parameters extracted are appended to the supplied parameters list +- * `parameters`. +- * +- * @param [in] begin An iterator to the beginning of the sequence +- * @param [in] end An iterator to the end of the sequence +- * @param [out] parameters A reference to the parameters list to append +- * paramter values extracted to +- * @return An iterator to the character after the last parameter read +- */ +-template +-InputIterator extract_parameters(InputIterator begin, InputIterator end, +- parameter_list ¶meters) +-{ +- InputIterator cursor; +- +- if (begin == end) { +- // error: expected non-zero length range +- return begin; +- } +- +- cursor = begin; +- std::pair ret; +- +- /** +- * LWS +- * token +- * LWS +- * *(";" method-param) +- * LWS +- * ,=loop again +- */ +- while (cursor != end) { +- std::string parameter_name; +- attribute_list attributes; +- +- // extract any stray whitespace +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end) {break;} +- +- ret = http::parser::extract_token(cursor,end); +- +- if (ret.first.empty()) { +- // error: expected a token +- return begin; +- } else { +- parameter_name = ret.first; +- cursor = ret.second; +- } +- +- // Safe break point, insert parameter with blank attributes and exit +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end) { +- //parameters[parameter_name] = attributes; +- parameters.push_back(std::make_pair(parameter_name,attributes)); +- break; +- } +- +- // If there is an attribute list, read it in +- if (*cursor == ';') { +- InputIterator acursor; +- +- ++cursor; +- acursor = http::parser::extract_attributes(cursor,end,attributes); +- +- if (acursor == cursor) { +- // attribute extraction ended in syntax error +- return begin; +- } +- +- cursor = acursor; +- } +- +- // insert parameter into output list +- //parameters[parameter_name] = attributes; +- parameters.push_back(std::make_pair(parameter_name,attributes)); +- +- cursor = http::parser::extract_all_lws(cursor,end); +- if (cursor == end) {break;} +- +- // if next char is ',' then read another parameter, else stop +- if (*cursor != ',') { +- break; +- } +- +- // advance past comma +- ++cursor; +- +- if (cursor == end) { +- // expected more bytes after a comma +- return begin; +- } +- } +- +- return cursor; +-} +- +-inline std::string strip_lws(std::string const & input) { +- std::string::const_iterator begin = extract_all_lws(input.begin(),input.end()); +- if (begin == input.end()) { +- return std::string(); +- } +- +- std::string::const_reverse_iterator rbegin = extract_all_lws(input.rbegin(),input.rend()); +- if (rbegin == input.rend()) { +- return std::string(); +- } +- +- return std::string(begin,rbegin.base()); +-} +- +-/// Base HTTP parser +-/** +- * Includes methods and data elements common to all types of HTTP messages such +- * as headers, versions, bodies, etc. +- */ +-class parser { +-public: +- parser() +- : m_header_bytes(0) +- , m_body_bytes_needed(0) +- , m_body_bytes_max(max_body_size) +- , m_body_encoding(body_encoding::unknown) {} +- +- /// Get the HTTP version string +- /** +- * @return The version string for this parser +- */ +- std::string const & get_version() const { +- return m_version; +- } +- +- /// Set HTTP parser Version +- /** +- * Input should be in format: HTTP/x.y where x and y are positive integers. +- * @todo Does this method need any validation? +- * +- * @param [in] version The value to set the HTTP version to. +- */ +- void set_version(std::string const & version); +- +- /// Get the value of an HTTP header +- /** +- * @todo Make this method case insensitive. +- * +- * @param [in] key The name/key of the header to get. +- * @return The value associated with the given HTTP header key. +- */ +- std::string const & get_header(std::string const & key) const; +- +- /// Extract an HTTP parameter list from a parser header. +- /** +- * If the header requested doesn't exist or exists and is empty the +- * parameter list is valid (but empty). +- * +- * @param [in] key The name/key of the HTTP header to use as input. +- * @param [out] out The parameter list to store extracted parameters in. +- * @return Whether or not the input was a valid parameter list. +- */ +- 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 +- * indicated value. If a header with the name `key` already exists, `val` +- * will be appended to the existing value. +- * +- * @todo Make this method case insensitive. +- * @todo Should there be any restrictions on which keys are allowed? +- * @todo Exception free varient +- * +- * @see replace_header +- * +- * @param [in] key The name/key of the header to append to. +- * @param [in] val The value to append. +- */ +- void append_header(std::string const & key, std::string const & val); +- +- /// Set a value for an HTTP header, replacing an existing value +- /** +- * This method will set the value of the HTTP header `key` with the +- * indicated value. If a header with the name `key` already exists, `val` +- * will replace the existing value. +- * +- * @todo Make this method case insensitive. +- * @todo Should there be any restrictions on which keys are allowed? +- * @todo Exception free varient +- * +- * @see append_header +- * +- * @param [in] key The name/key of the header to append to. +- * @param [in] val The value to append. +- */ +- void replace_header(std::string const & key, std::string const & val); +- +- /// Remove a header from the parser +- /** +- * Removes the header entirely from the parser. This is different than +- * setting the value of the header to blank. +- * +- * @todo Make this method case insensitive. +- * +- * @param [in] key The name/key of the header to remove. +- */ +- void remove_header(std::string const & key); +- +- /// Get HTTP body +- /** +- * Gets the body of the HTTP object +- * +- * @return The body of the HTTP message. +- */ +- std::string const & get_body() const { +- return m_body; +- } +- +- /// Set body content +- /** +- * Set the body content of the HTTP response to the parameter string. Note +- * set_body will also set the Content-Length HTTP header to the appropriate +- * value. If you want the Content-Length header to be something else, do so +- * via replace_header("Content-Length") after calling set_body() +- * +- * @param value String data to include as the body content. +- */ +- void set_body(std::string const & value); +- +- /// Get body size limit +- /** +- * Retrieves the maximum number of bytes to parse & buffer before canceling +- * a request. +- * +- * @since 0.5.0 +- * +- * @return The maximum length of a message body. +- */ +- size_t get_max_body_size() const { +- return m_body_bytes_max; +- } +- +- /// Set body size limit +- /** +- * Set the maximum number of bytes to parse and buffer before canceling a +- * request. +- * +- * @since 0.5.0 +- * +- * @param value The size to set the max body length to. +- */ +- void set_max_body_size(size_t value) { +- m_body_bytes_max = value; +- } +- +- /// Extract an HTTP parameter list from a string. +- /** +- * @param [in] in The input string. +- * @param [out] out The parameter list to store extracted parameters in. +- * @return Whether or not the input was a valid parameter list. +- */ +- bool parse_parameter_list(std::string const & in, parameter_list & out) +- const; +-protected: +- /// Process a header line +- /** +- * @todo Update this method to be exception free. +- * +- * @param [in] begin An iterator to the beginning of the sequence. +- * @param [in] end An iterator to the end of the sequence. +- */ +- void process_header(std::string::iterator begin, std::string::iterator end); +- +- /// Prepare the parser to begin parsing body data +- /** +- * Inspects headers to determine if the message has a body that needs to be +- * read. If so, sets up the necessary state, otherwise returns false. If +- * this method returns true and loading the message body is desired call +- * `process_body` until it returns zero bytes or an error. +- * +- * Must not be called until after all headers have been processed. +- * +- * @since 0.5.0 +- * +- * @return True if more bytes are needed to load the body, false otherwise. +- */ +- bool prepare_body(); +- +- /// Process body data +- /** +- * Parses body data. +- * +- * @since 0.5.0 +- * +- * @param [in] begin An iterator to the beginning of the sequence. +- * @param [in] end An iterator to the end of the sequence. +- * @return The number of bytes processed +- */ +- size_t process_body(char const * buf, size_t len); +- +- /// Check if the parser is done parsing the body +- /** +- * Behavior before a call to `prepare_body` is undefined. +- * +- * @since 0.5.0 +- * +- * @return True if the message body has been completed loaded. +- */ +- bool body_ready() const { +- return (m_body_bytes_needed == 0); +- } +- +- /// Generate and return the HTTP headers as a string +- /** +- * Each headers will be followed by the \r\n sequence including the last one. +- * A second \r\n sequence (blank header) is not appended by this method +- * +- * @return The HTTP headers as a string. +- */ +- std::string raw_headers() const; +- +- std::string m_version; +- header_list m_headers; +- +- size_t m_header_bytes; +- +- std::string m_body; +- size_t m_body_bytes_needed; +- size_t m_body_bytes_max; +- body_encoding::value m_body_encoding; +-}; +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#include +- +-#endif // HTTP_PARSER_HPP +diff --git a/src/lib/websocketpp/http/request.hpp b/src/lib/websocketpp/http/request.hpp +deleted file mode 100644 +index 2f789ac..0000000 +--- a/src/lib/websocketpp/http/request.hpp ++++ /dev/null +@@ -1,124 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_REQUEST_HPP +-#define HTTP_PARSER_REQUEST_HPP +- +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-/// Stores, parses, and manipulates HTTP requests +-/** +- * http::request provides the following functionality for working with HTTP +- * requests. +- * +- * - Initialize request via manually setting each element +- * - Initialize request via reading raw bytes and parsing +- * - Once initialized, access individual parsed elements +- * - Once initialized, read entire request as raw bytes +- */ +-class request : public parser { +-public: +- typedef request type; +- typedef lib::shared_ptr ptr; +- +- request() +- : m_buf(lib::make_shared()) +- , m_ready(false) {} +- +- /// Process bytes in the input buffer +- /** +- * Process up to len bytes from input buffer buf. Returns the number of +- * bytes processed. Bytes left unprocessed means bytes left over after the +- * final header delimiters. +- * +- * Consume is a streaming processor. It may be called multiple times on one +- * request and the full headers need not be available before processing can +- * begin. If the end of the request was reached during this call to consume +- * the ready flag will be set. Further calls to consume once ready will be +- * ignored. +- * +- * Consume will throw an http::exception in the case of an error. Typical +- * error reasons include malformed requests, incomplete requests, and max +- * header size being reached. +- * +- * @param buf Pointer to byte buffer +- * @param len Size of byte buffer +- * @return Number of bytes processed. +- */ +- size_t consume(char const * buf, size_t len); +- +- /// Returns whether or not the request is ready for reading. +- bool ready() const { +- return m_ready; +- } +- +- /// Returns the full raw request (including the body) +- std::string raw() const; +- +- /// Returns the raw request headers only (similar to an HTTP HEAD request) +- std::string raw_head() const; +- +- /// Set the HTTP method. Must be a valid HTTP token +- void set_method(std::string const & method); +- +- /// Return the request method +- std::string const & get_method() const { +- return m_method; +- } +- +- /// Set the HTTP uri. Must be a valid HTTP uri +- void set_uri(std::string const & uri); +- +- /// Return the requested URI +- std::string const & get_uri() const { +- return m_uri; +- } +- +-private: +- /// Helper function for message::consume. Process request line +- void process(std::string::iterator begin, std::string::iterator end); +- +- lib::shared_ptr m_buf; +- std::string m_method; +- std::string m_uri; +- bool m_ready; +-}; +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#include +- +-#endif // HTTP_PARSER_REQUEST_HPP +diff --git a/src/lib/websocketpp/http/response.hpp b/src/lib/websocketpp/http/response.hpp +deleted file mode 100644 +index e0f0415..0000000 +--- a/src/lib/websocketpp/http/response.hpp ++++ /dev/null +@@ -1,188 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef HTTP_PARSER_RESPONSE_HPP +-#define HTTP_PARSER_RESPONSE_HPP +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace http { +-namespace parser { +- +-/// Stores, parses, and manipulates HTTP responses +-/** +- * http::response provides the following functionality for working with HTTP +- * responses. +- * +- * - Initialize response via manually setting each element +- * - Initialize response via reading raw bytes and parsing +- * - Once initialized, access individual parsed elements +- * - Once initialized, read entire response as raw bytes +- * +- * http::response checks for header completeness separately from the full +- * response. Once the header is complete, the Content-Length header is read to +- * determine when to stop reading body bytes. If no Content-Length is present +- * ready() will never return true. It is the responsibility of the caller to +- * consume to determine when the response is complete (ie when the connection +- * terminates, or some other metric). +- */ +-class response : public parser { +-public: +- typedef response type; +- typedef lib::shared_ptr ptr; +- +- response() +- : m_read(0) +- , m_buf(lib::make_shared()) +- , m_status_code(status_code::uninitialized) +- , m_state(RESPONSE_LINE) {} +- +- /// Process bytes in the input buffer +- /** +- * Process up to len bytes from input buffer buf. Returns the number of +- * bytes processed. Bytes left unprocessed means bytes left over after the +- * final header delimiters. +- * +- * Consume is a streaming processor. It may be called multiple times on one +- * response and the full headers need not be available before processing can +- * begin. If the end of the response was reached during this call to consume +- * the ready flag will be set. Further calls to consume once ready will be +- * ignored. +- * +- * Consume will throw an http::exception in the case of an error. Typical +- * error reasons include malformed responses, incomplete responses, and max +- * header size being reached. +- * +- * @param buf Pointer to byte buffer +- * @param len Size of byte buffer +- * @return Number of bytes processed. +- */ +- size_t consume(char const * buf, size_t len); +- +- /// Process bytes in the input buffer (istream version) +- /** +- * Process bytes from istream s. Returns the number of bytes processed. +- * Bytes left unprocessed means bytes left over after the final header +- * delimiters. +- * +- * Consume is a streaming processor. It may be called multiple times on one +- * response and the full headers need not be available before processing can +- * begin. If the end of the response was reached during this call to consume +- * the ready flag will be set. Further calls to consume once ready will be +- * ignored. +- * +- * Consume will throw an http::exception in the case of an error. Typical +- * error reasons include malformed responses, incomplete responses, and max +- * header size being reached. +- * +- * @param buf Pointer to byte buffer +- * @param len Size of byte buffer +- * @return Number of bytes processed. +- */ +- size_t consume(std::istream & s); +- +- /// Returns true if the response is ready. +- /** +- * @note will never return true if the content length header is not present +- */ +- bool ready() const { +- return m_state == DONE; +- } +- +- /// Returns true if the response headers are fully parsed. +- bool headers_ready() const { +- return (m_state == BODY || m_state == DONE); +- } +- +- /// Returns the full raw response +- std::string raw() const; +- +- /// Set response status code and message +- /** +- * Sets the response status code to `code` and looks up the corresponding +- * message for standard codes. Non-standard codes will be entered as Unknown +- * use set_status(status_code::value,std::string) overload to set both +- * values explicitly. +- * +- * @param code Code to set +- * @param msg Message to set +- */ +- void set_status(status_code::value code); +- +- /// Set response status code and message +- /** +- * Sets the response status code and message to independent custom values. +- * use set_status(status_code::value) to set the code and have the standard +- * message be automatically set. +- * +- * @param code Code to set +- * @param msg Message to set +- */ +- void set_status(status_code::value code, std::string const & msg); +- +- /// Return the response status code +- status_code::value get_status_code() const { +- return m_status_code; +- } +- +- /// Return the response status message +- const std::string& get_status_msg() const { +- return m_status_msg; +- } +-private: +- /// Helper function for consume. Process response line +- void process(std::string::iterator begin, std::string::iterator end); +- +- /// Helper function for processing body bytes +- size_t process_body(char const * buf, size_t len); +- +- enum state { +- RESPONSE_LINE = 0, +- HEADERS = 1, +- BODY = 2, +- DONE = 3 +- }; +- +- std::string m_status_msg; +- size_t m_read; +- lib::shared_ptr m_buf; +- status_code::value m_status_code; +- state m_state; +- +-}; +- +-} // namespace parser +-} // namespace http +-} // namespace ws_websocketpp +- +-#include +- +-#endif // HTTP_PARSER_RESPONSE_HPP +diff --git a/src/lib/websocketpp/impl/connection_impl.hpp b/src/lib/websocketpp/impl/connection_impl.hpp +deleted file mode 100644 +index d8fe393..0000000 +--- a/src/lib/websocketpp/impl/connection_impl.hpp ++++ /dev/null +@@ -1,2375 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CONNECTION_IMPL_HPP +-#define WEBSOCKETPP_CONNECTION_IMPL_HPP +- +-#include +-#include +-#include +-#include +- +-#include +- +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +- +-namespace istate = session::internal_state; +- +-template +-void connection::set_termination_handler( +- termination_handler new_handler) +-{ +- m_alog->write(log::alevel::devel, +- "connection set_termination_handler"); +- +- //scoped_lock_type lock(m_connection_state_lock); +- +- m_termination_handler = new_handler; +-} +- +-template +-std::string const & connection::get_origin() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_processor->get_origin(m_request); +-} +- +-template +-size_t connection::get_buffered_amount() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_send_buffer_size; +-} +- +-template +-session::state::value connection::get_state() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_state; +-} +- +-template +-lib::error_code connection::send(std::string const & payload, +- frame::opcode::value op) +-{ +- message_ptr msg = m_msg_manager->get_message(op,payload.size()); +- msg->append_payload(payload); +- msg->set_compressed(true); +- +- return send(msg); +-} +- +-template +-lib::error_code connection::send(void const * payload, size_t len, +- frame::opcode::value op) +-{ +- message_ptr msg = m_msg_manager->get_message(op,len); +- msg->append_payload(payload,len); +- +- return send(msg); +-} +- +-template +-lib::error_code connection::send(typename config::message_type::ptr msg) +-{ +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection send"); +- } +- +- { +- scoped_lock_type lock(m_connection_state_lock); +- if (m_state != session::state::open) { +- return error::make_error_code(error::invalid_state); +- } +- } +- +- message_ptr outgoing_msg; +- bool needs_writing = false; +- +- if (msg->get_prepared()) { +- outgoing_msg = msg; +- +- scoped_lock_type lock(m_write_lock); +- write_push(outgoing_msg); +- needs_writing = !m_write_flag && !m_send_queue.empty(); +- } else { +- outgoing_msg = m_msg_manager->get_message(); +- +- if (!outgoing_msg) { +- return error::make_error_code(error::no_outgoing_buffers); +- } +- +- scoped_lock_type lock(m_write_lock); +- lib::error_code ec = m_processor->prepare_data_frame(msg,outgoing_msg); +- +- if (ec) { +- return ec; +- } +- +- write_push(outgoing_msg); +- needs_writing = !m_write_flag && !m_send_queue.empty(); +- } +- +- if (needs_writing) { +- transport_con_type::dispatch(lib::bind( +- &type::write_frame, +- type::get_shared() +- )); +- } +- +- return lib::error_code(); +-} +- +-template +-void connection::ping(std::string const& payload, lib::error_code& ec) { +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection ping"); +- } +- +- { +- scoped_lock_type lock(m_connection_state_lock); +- 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()); +- ec = error::make_error_code(error::invalid_state); +- return; +- } +- } +- +- message_ptr msg = m_msg_manager->get_message(); +- if (!msg) { +- ec = error::make_error_code(error::no_outgoing_buffers); +- return; +- } +- +- ec = m_processor->prepare_ping(payload,msg); +- if (ec) {return;} +- +- // set ping timer if we are listening for one +- if (m_pong_timeout_handler) { +- // Cancel any existing timers +- if (m_ping_timer) { +- m_ping_timer->cancel(); +- } +- +- if (m_pong_timeout_dur > 0) { +- m_ping_timer = transport_con_type::set_timer( +- m_pong_timeout_dur, +- lib::bind( +- &type::handle_pong_timeout, +- type::get_shared(), +- payload, +- lib::placeholders::_1 +- ) +- ); +- } +- +- if (!m_ping_timer) { +- // Our transport doesn't support timers +- m_elog->write(log::elevel::warn,"Warning: a pong_timeout_handler is \ +- set but the transport in use does not support timeouts."); +- } +- } +- +- bool needs_writing = false; +- { +- scoped_lock_type lock(m_write_lock); +- write_push(msg); +- needs_writing = !m_write_flag && !m_send_queue.empty(); +- } +- +- if (needs_writing) { +- transport_con_type::dispatch(lib::bind( +- &type::write_frame, +- type::get_shared() +- )); +- } +- +- ec = lib::error_code(); +-} +- +-template +-void connection::ping(std::string const & payload) { +- lib::error_code ec; +- ping(payload,ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +-template +-void connection::handle_pong_timeout(std::string payload, +- lib::error_code const & ec) +-{ +- if (ec) { +- if (ec == transport::error::operation_aborted) { +- // ignore, this is expected +- return; +- } +- +- m_elog->write(log::elevel::devel,"pong_timeout error: "+ec.message()); +- return; +- } +- +- if (m_pong_timeout_handler) { +- m_pong_timeout_handler(m_connection_hdl,payload); +- } +-} +- +-template +-void connection::pong(std::string const& payload, lib::error_code& ec) { +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection pong"); +- } +- +- { +- scoped_lock_type lock(m_connection_state_lock); +- 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()); +- ec = error::make_error_code(error::invalid_state); +- return; +- } +- } +- +- message_ptr msg = m_msg_manager->get_message(); +- if (!msg) { +- ec = error::make_error_code(error::no_outgoing_buffers); +- return; +- } +- +- ec = m_processor->prepare_pong(payload,msg); +- if (ec) {return;} +- +- bool needs_writing = false; +- { +- scoped_lock_type lock(m_write_lock); +- write_push(msg); +- needs_writing = !m_write_flag && !m_send_queue.empty(); +- } +- +- if (needs_writing) { +- transport_con_type::dispatch(lib::bind( +- &type::write_frame, +- type::get_shared() +- )); +- } +- +- ec = lib::error_code(); +-} +- +-template +-void connection::pong(std::string const & payload) { +- lib::error_code ec; +- pong(payload,ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +-template +-void connection::close(close::status::value const code, +- std::string const & reason, lib::error_code & ec) +-{ +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection close"); +- } +- +- // Truncate reason to maximum size allowable in a close frame. +- std::string tr(reason,0,std::min(reason.size(), +- frame::limits::close_reason_size)); +- +- scoped_lock_type lock(m_connection_state_lock); +- +- if (m_state != session::state::open) { +- ec = error::make_error_code(error::invalid_state); +- return; +- } +- +- ec = this->send_close_frame(code,tr,false,close::status::terminal(code)); +-} +- +-template +-void connection::close(close::status::value const code, +- std::string const & reason) +-{ +- lib::error_code ec; +- close(code,reason,ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +-/// Trigger the on_interrupt handler +-/** +- * This is thread safe if the transport is thread safe +- */ +-template +-lib::error_code connection::interrupt() { +- m_alog->write(log::alevel::devel,"connection connection::interrupt"); +- return transport_con_type::interrupt( +- lib::bind( +- &type::handle_interrupt, +- type::get_shared() +- ) +- ); +-} +- +- +-template +-void connection::handle_interrupt() { +- if (m_interrupt_handler) { +- m_interrupt_handler(m_connection_hdl); +- } +-} +- +-template +-lib::error_code connection::pause_reading() { +- m_alog->write(log::alevel::devel,"connection connection::pause_reading"); +- return transport_con_type::dispatch( +- lib::bind( +- &type::handle_pause_reading, +- type::get_shared() +- ) +- ); +-} +- +-/// Pause reading handler. Not safe to call directly +-template +-void connection::handle_pause_reading() { +- m_alog->write(log::alevel::devel,"connection connection::handle_pause_reading"); +- m_read_flag = false; +-} +- +-template +-lib::error_code connection::resume_reading() { +- m_alog->write(log::alevel::devel,"connection connection::resume_reading"); +- return transport_con_type::dispatch( +- lib::bind( +- &type::handle_resume_reading, +- type::get_shared() +- ) +- ); +-} +- +-/// Resume reading helper method. Not safe to call directly +-template +-void connection::handle_resume_reading() { +- m_read_flag = true; +- read_frame(); +-} +- +- +- +- +- +- +- +- +- +- +- +-template +-bool connection::get_secure() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_uri->get_secure(); +-} +- +-template +-std::string const & connection::get_host() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_uri->get_host(); +-} +- +-template +-std::string const & connection::get_resource() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_uri->get_resource(); +-} +- +-template +-uint16_t connection::get_port() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_uri->get_port(); +-} +- +-template +-uri_ptr connection::get_uri() const { +- //scoped_lock_type lock(m_connection_state_lock); +- return m_uri; +-} +- +-template +-void connection::set_uri(uri_ptr uri) { +- //scoped_lock_type lock(m_connection_state_lock); +- m_uri = uri; +-} +- +- +- +- +- +- +-template +-std::string const & connection::get_subprotocol() const { +- return m_subprotocol; +-} +- +-template +-std::vector const & +-connection::get_requested_subprotocols() const { +- return m_requested_subprotocols; +-} +- +-template +-void connection::add_subprotocol(std::string const & value, +- lib::error_code & ec) +-{ +- if (m_is_server) { +- ec = error::make_error_code(error::client_only); +- return; +- } +- +- // If the value is empty or has a non-RFC2616 token character it is invalid. +- if (value.empty() || std::find_if(value.begin(),value.end(), +- http::is_not_token_char) != value.end()) +- { +- ec = error::make_error_code(error::invalid_subprotocol); +- return; +- } +- +- m_requested_subprotocols.push_back(value); +-} +- +-template +-void connection::add_subprotocol(std::string const & value) { +- lib::error_code ec; +- this->add_subprotocol(value,ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +- +-template +-void connection::select_subprotocol(std::string const & value, +- lib::error_code & ec) +-{ +- if (!m_is_server) { +- ec = error::make_error_code(error::server_only); +- return; +- } +- +- if (value.empty()) { +- ec = lib::error_code(); +- return; +- } +- +- std::vector::iterator it; +- +- it = std::find(m_requested_subprotocols.begin(), +- m_requested_subprotocols.end(), +- value); +- +- if (it == m_requested_subprotocols.end()) { +- ec = error::make_error_code(error::unrequested_subprotocol); +- return; +- } +- +- m_subprotocol = value; +-} +- +-template +-void connection::select_subprotocol(std::string const & value) { +- lib::error_code ec; +- this->select_subprotocol(value,ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +- +-template +-std::string const & +-connection::get_request_header(std::string const & key) const { +- return m_request.get_header(key); +-} +- +-template +-std::string const & +-connection::get_request_body() const { +- return m_request.get_body(); +-} +- +-template +-std::string const & +-connection::get_response_header(std::string const & key) const { +- return m_response.get_header(key); +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::set_status(http::status_code::value code) +-{ +- if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { +- throw exception("Call to set_status from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- m_response.set_status(code); +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::set_status(http::status_code::value code, +- std::string const & msg) +-{ +- if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { +- throw exception("Call to set_status from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- +- m_response.set_status(code,msg); +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::set_body(std::string const & value) { +- if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { +- throw exception("Call to set_status from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- +- m_response.set_body(value); +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::append_header(std::string const & key, +- std::string const & val) +-{ +- if (m_is_server) { +- if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { +- // we are setting response headers for an incoming server connection +- m_response.append_header(key,val); +- } else { +- throw exception("Call to append_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } else { +- if (m_internal_state == istate::USER_INIT) { +- // we are setting initial headers for an outgoing client connection +- m_request.append_header(key,val); +- } else { +- throw exception("Call to append_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::replace_header(std::string const & key, +- std::string const & val) +-{ +- if (m_is_server) { +- if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { +- // we are setting response headers for an incoming server connection +- m_response.replace_header(key,val); +- } else { +- throw exception("Call to replace_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } else { +- if (m_internal_state == istate::USER_INIT) { +- // we are setting initial headers for an outgoing client connection +- m_request.replace_header(key,val); +- } else { +- throw exception("Call to replace_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } +-} +- +-// TODO: EXCEPTION_FREE +-template +-void connection::remove_header(std::string const & key) +-{ +- if (m_is_server) { +- if (m_internal_state == istate::PROCESS_HTTP_REQUEST) { +- // we are setting response headers for an incoming server connection +- m_response.remove_header(key); +- } else { +- throw exception("Call to remove_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } else { +- if (m_internal_state == istate::USER_INIT) { +- // we are setting initial headers for an outgoing client connection +- m_request.remove_header(key); +- } else { +- throw exception("Call to remove_header from invalid state", +- error::make_error_code(error::invalid_state)); +- } +- } +-} +- +-/// Defer HTTP Response until later +-/** +- * Used in the http handler to defer the HTTP response for this connection +- * until later. Handshake timers will be canceled and the connection will be +- * left open until `send_http_response` or an equivalent is called. +- * +- * Warning: deferred connections won't time out and as a result can tie up +- * resources. +- * +- * @return A status code, zero on success, non-zero otherwise +- */ +-template +-lib::error_code connection::defer_http_response() { +- // Cancel handshake timer, otherwise the connection will time out and we'll +- // close the connection before the app has a chance to send a response. +- if (m_handshake_timer) { +- m_handshake_timer->cancel(); +- m_handshake_timer.reset(); +- } +- +- // Do something to signal deferral +- m_http_state = session::http_state::deferred; +- +- return lib::error_code(); +-} +- +-/// Send deferred HTTP Response (exception free) +-/** +- * Sends an http response to an HTTP connection that was deferred. This will +- * send a complete response including all headers, status line, and body +- * text. The connection will be closed afterwards. +- * +- * @since 0.6.0 +- * +- * @param ec A status code, zero on success, non-zero otherwise +- */ +-template +-void connection::send_http_response(lib::error_code & ec) { +- { +- scoped_lock_type lock(m_connection_state_lock); +- if (m_http_state != session::http_state::deferred) { +- ec = error::make_error_code(error::invalid_state); +- return; +- } +- +- m_http_state = session::http_state::body_written; +- } +- +- this->write_http_response(lib::error_code()); +- ec = lib::error_code(); +-} +- +-template +-void connection::send_http_response() { +- lib::error_code ec; +- this->send_http_response(ec); +- if (ec) { +- throw exception(ec); +- } +-} +- +- +- +- +-/******** logic thread ********/ +- +-template +-void 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"); +- this->terminate(error::make_error_code(error::invalid_state)); +- return; +- } +- +- m_internal_state = istate::TRANSPORT_INIT; +- +- // Depending on how the transport implements init this function may return +- // immediately and call handle_transport_init later or call +- // handle_transport_init from this function. +- transport_con_type::init( +- lib::bind( +- &type::handle_transport_init, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +-} +- +-template +-void connection::handle_transport_init(lib::error_code const & ec) { +- 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, +- "handle_transport_init must be called from transport init state"); +- ecm = error::make_error_code(error::invalid_state); +- } +- +- if (ecm) { +- std::stringstream s; +- s << "handle_transport_init received error: "<< ecm.message(); +- m_elog->write(log::elevel::rerror,s.str()); +- +- this->terminate(ecm); +- return; +- } +- +- // At this point the transport is ready to read and write bytes. +- if (m_is_server) { +- m_internal_state = istate::READ_HTTP_REQUEST; +- this->read_handshake(1); +- } else { +- // We are a client. Set the processor to the version specified in the +- // config file and send a handshake request. +- m_internal_state = istate::WRITE_HTTP_REQUEST; +- m_processor = get_processor(config::client_version); +- this->send_http_request(); +- } +-} +- +-template +-void connection::read_handshake(size_t num_bytes) { +- m_alog->write(log::alevel::devel,"connection read_handshake"); +- +- if (m_open_handshake_timeout_dur > 0) { +- m_handshake_timer = transport_con_type::set_timer( +- m_open_handshake_timeout_dur, +- lib::bind( +- &type::handle_open_handshake_timeout, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +- } +- +- transport_con_type::async_read_at_least( +- num_bytes, +- m_buf, +- config::connection_read_buffer_size, +- lib::bind( +- &type::handle_read_handshake, +- type::get_shared(), +- lib::placeholders::_1, +- lib::placeholders::_2 +- ) +- ); +-} +- +-// All exit paths for this function need to call write_http_response() or submit +-// a new read request with this function as the handler. +-template +-void connection::handle_read_handshake(lib::error_code const & ec, +- size_t bytes_transferred) +-{ +- m_alog->write(log::alevel::devel,"connection handle_read_handshake"); +- +- lib::error_code ecm = ec; +- +- if (!ecm) { +- scoped_lock_type lock(m_connection_state_lock); +- +- if (m_state == session::state::connecting) { +- if (m_internal_state != istate::READ_HTTP_REQUEST) { +- ecm = error::make_error_code(error::invalid_state); +- } +- } else if (m_state == session::state::closed) { +- // 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, +- "handle_read_handshake invoked after connection was closed"); +- return; +- } else { +- ecm = error::make_error_code(error::invalid_state); +- } +- } +- +- if (ecm) { +- 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, +- "got (expected) eof/state error from closed con"); +- return; +- } +- +- log_err(log::elevel::rerror,"handle_read_handshake",ecm); +- this->terminate(ecm); +- return; +- } +- +- // 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."); +- this->terminate(make_error_code(error::general)); +- return; +- } +- +- size_t bytes_processed = 0; +- try { +- bytes_processed = m_request.consume(m_buf,bytes_transferred); +- } catch (http::exception &e) { +- // All HTTP exceptions will result in this request failing and an error +- // response being returned. No more bytes will be read in this con. +- m_response.set_status(e.m_error_code,e.m_error_msg); +- this->write_http_response_error(error::make_error_code(error::http_parse_error)); +- return; +- } +- +- // More paranoid boundaries checking. +- // TODO: Is this overkill? +- if (bytes_processed > bytes_transferred) { +- 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)) { +- std::stringstream s; +- s << "bytes_transferred: " << bytes_transferred +- << " bytes, bytes processed: " << bytes_processed << " bytes"; +- m_alog->write(log::alevel::devel,s.str()); +- } +- +- if (m_request.ready()) { +- lib::error_code processor_ec = this->initialize_processor(); +- if (processor_ec) { +- this->write_http_response_error(processor_ec); +- return; +- } +- +- if (m_processor && m_processor->get_version() == 0) { +- // Version 00 has an extra requirement to read some bytes after the +- // handshake +- if (bytes_transferred-bytes_processed >= 8) { +- m_request.replace_header( +- "Sec-WebSocket-Key3", +- std::string(m_buf+bytes_processed,m_buf+bytes_processed+8) +- ); +- bytes_processed += 8; +- } else { +- // TODO: need more bytes +- 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_request.get_header("Sec-WebSocket-Key3").empty()) { +- m_alog->write(log::alevel::devel, +- utility::to_hex(m_request.get_header("Sec-WebSocket-Key3"))); +- } +- } +- +- // The remaining bytes in m_buf are frame data. Copy them to the +- // beginning of the buffer and note the length. They will be read after +- // the handshake completes and before more bytes are read. +- std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf); +- m_buf_cursor = bytes_transferred-bytes_processed; +- +- +- m_internal_state = istate::PROCESS_HTTP_REQUEST; +- +- // We have the complete request. Process it. +- lib::error_code handshake_ec = this->process_handshake_request(); +- +- // Write a response if this is a websocket connection or if it is an +- // HTTP connection for which the response has not been deferred or +- // started yet by a different system (i.e. still in init state). +- if (!m_is_http || m_http_state == session::http_state::init) { +- this->write_http_response(handshake_ec); +- } +- } else { +- // read at least 1 more byte +- transport_con_type::async_read_at_least( +- 1, +- m_buf, +- config::connection_read_buffer_size, +- lib::bind( +- &type::handle_read_handshake, +- type::get_shared(), +- lib::placeholders::_1, +- lib::placeholders::_2 +- ) +- ); +- } +-} +- +-// write_http_response requires the request to be fully read and the connection +-// to be in the PROCESS_HTTP_REQUEST state. In some cases we can detect errors +-// before the request is fully read (specifically at a point where we aren't +-// sure if the hybi00 key3 bytes need to be read). This method sets the correct +-// state and calls write_http_response +-template +-void connection::write_http_response_error(lib::error_code const & ec) { +- if (m_internal_state != istate::READ_HTTP_REQUEST) { +- m_alog->write(log::alevel::devel, +- "write_http_response_error called in invalid state"); +- this->terminate(error::make_error_code(error::invalid_state)); +- return; +- } +- +- m_internal_state = istate::PROCESS_HTTP_REQUEST; +- +- this->write_http_response(ec); +-} +- +-// All exit paths for this function need to call write_http_response() or submit +-// a new read request with this function as the handler. +-template +-void connection::handle_read_frame(lib::error_code const & ec, +- size_t bytes_transferred) +-{ +- //m_alog->write(log::alevel::devel,"connection handle_read_frame"); +- +- lib::error_code ecm = ec; +- +- if (!ecm && m_internal_state != istate::PROCESS_CONNECTION) { +- ecm = error::make_error_code(error::invalid_state); +- } +- +- if (ecm) { +- log::level echannel = log::elevel::rerror; +- +- 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"); +- 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, +- // this is a signal to terminate our end of the connection after +- // the closing handshake +- terminate(lib::error_code()); +- return; +- } +- } 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, +- "handle_read_frame: got invalid istate in closed state"); +- return; +- } +- } 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; +- } +- +- // 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"); +- this->terminate(make_error_code(error::general)); +- return; +- }*/ +- +- size_t p = 0; +- +- 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()); +- } +- +- while (p < bytes_transferred) { +- 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()); +- } +- +- lib::error_code consume_ec; +- +- if (m_alog->static_test(log::alevel::devel)) { +- std::stringstream s; +- s << "Processing Bytes: " << utility::to_hex(reinterpret_cast(m_buf)+p,bytes_transferred-p); +- m_alog->write(log::alevel::devel,s.str()); +- } +- +- p += m_processor->consume( +- reinterpret_cast(m_buf)+p, +- bytes_transferred-p, +- consume_ec +- ); +- +- 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()); +- } +- if (consume_ec) { +- log_err(log::elevel::rerror, "consume", consume_ec); +- +- if (config::drop_on_protocol_error) { +- this->terminate(consume_ec); +- return; +- } else { +- lib::error_code close_ec; +- this->close( +- processor::error::to_ws(consume_ec), +- consume_ec.message(), +- close_ec +- ); +- +- if (close_ec) { +- log_err(log::elevel::fatal, "Protocol error close frame ", close_ec); +- this->terminate(close_ec); +- return; +- } +- } +- return; +- } +- +- if (m_processor->ready()) { +- if (m_alog->static_test(log::alevel::devel)) { +- std::stringstream s; +- s << "Complete message received. Dispatching"; +- 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"); +- } 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"); +- } else if (m_message_handler) { +- m_message_handler(m_connection_hdl, msg); +- } +- } else { +- process_control_frame(msg); +- } +- } +- } +- +- read_frame(); +-} +- +-/// Issue a new transport read unless reading is paused. +-template +-void connection::read_frame() { +- if (!m_read_flag) { +- return; +- } +- +- transport_con_type::async_read_at_least( +- // std::min wont work with undefined static const values. +- // TODO: is there a more elegant way to do this? +- // Need to determine if requesting 1 byte or the exact number of bytes +- // is better here. 1 byte lets us be a bit more responsive at a +- // potential expense of additional runs through handle_read_frame +- /*(m_processor->get_bytes_needed() > config::connection_read_buffer_size ? +- config::connection_read_buffer_size : m_processor->get_bytes_needed())*/ +- 1, +- m_buf, +- config::connection_read_buffer_size, +- m_handle_read_frame +- ); +-} +- +-template +-lib::error_code connection::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)) { +- return lib::error_code(); +- } +- +- int version = processor::get_websocket_version(m_request); +- +- if (version < 0) { +- 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); +- } +- +- m_processor = get_processor(version); +- +- // if the processor is not null we are done +- if (m_processor) { +- return lib::error_code(); +- } +- +- // 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_response.set_status(http::status_code::bad_request); +- +- std::stringstream ss; +- std::string sep; +- std::vector::const_iterator it; +- for (it = versions_supported.begin(); it != versions_supported.end(); it++) +- { +- ss << sep << *it; +- sep = ","; +- } +- +- m_response.replace_header("Sec-WebSocket-Version",ss.str()); +- return error::make_error_code(error::unsupported_version); +-} +- +-template +-lib::error_code connection::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"); +- +- // extract URI from request +- m_uri = processor::get_uri_from_host( +- m_request, +- (transport_con_type::is_secure() ? "https" : "http") +- ); +- +- if (!m_uri->get_valid()) { +- 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); +- } +- +- if (m_http_handler) { +- m_is_http = true; +- m_http_handler(m_connection_hdl); +- +- if (m_state == session::state::closed) { +- return error::make_error_code(error::http_connection_ended); +- } +- } else { +- set_status(http::status_code::upgrade_required); +- return error::make_error_code(error::upgrade_required); +- } +- +- return lib::error_code(); +- } +- +- lib::error_code ec = m_processor->validate_handshake(m_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_response.set_status(http::status_code::bad_request); +- return ec; +- } +- +- // Read extension parameters and set up values necessary for the end user +- // to complete extension negotiation. +- std::pair neg_results; +- neg_results = m_processor->negotiate_extensions(m_request); +- +- 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_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 +- // clients. +- if (neg_results.second.size() > 0) { +- m_response.replace_header("Sec-WebSocket-Extensions", +- neg_results.second); +- } +- } +- +- // extract URI from request +- m_uri = m_processor->get_uri(m_request); +- +- +- if (!m_uri->get_valid()) { +- 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); +- } +- +- // extract subprotocols +- lib::error_code subp_ec = m_processor->extract_subprotocols(m_request, +- m_requested_subprotocols); +- +- if (subp_ec) { +- // should we do anything? +- } +- +- // Ask application to validate the connection +- if (!m_validate_handler || m_validate_handler(m_connection_hdl)) { +- m_response.set_status(http::status_code::switching_protocols); +- +- // Write the appropriate response headers based on request and +- // processor version +- ec = m_processor->process_handshake(m_request,m_subprotocol,m_response); +- +- if (ec) { +- std::stringstream s; +- s << "Processing error: " << ec << "(" << ec.message() << ")"; +- 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"); +- +- // Use Bad Request if the user handler did not provide a more +- // specific http response error code. +- // TODO: is there a better default? +- if (m_response.get_status_code() == http::status_code::uninitialized) { +- m_response.set_status(http::status_code::bad_request); +- } +- +- return error::make_error_code(error::rejected); +- } +- +- return lib::error_code(); +-} +- +-template +-void connection::write_http_response(lib::error_code const & ec) { +- 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."); +- return; +- } +- +- if (m_response.get_status_code() == http::status_code::uninitialized) { +- m_response.set_status(http::status_code::internal_server_error); +- m_ec = error::make_error_code(error::general); +- } else { +- m_ec = ec; +- } +- +- m_response.set_version("HTTP/1.1"); +- +- // Set server header based on the user agent settings +- if (m_response.get_header("Server").empty()) { +- if (!m_user_agent.empty()) { +- m_response.replace_header("Server",m_user_agent); +- } else { +- m_response.remove_header("Server"); +- } +- } +- +- // have the processor generate the raw bytes for the wire (if it exists) +- if (m_processor) { +- m_handshake_buffer = m_processor->get_raw(m_response); +- } else { +- // a processor wont exist for raw HTTP responses. +- 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_response.get_header("Sec-WebSocket-Key3").empty()) { +- m_alog->write(log::alevel::devel, +- utility::to_hex(m_response.get_header("Sec-WebSocket-Key3"))); +- } +- } +- +- // write raw bytes +- transport_con_type::async_write( +- m_handshake_buffer.data(), +- m_handshake_buffer.size(), +- lib::bind( +- &type::handle_write_http_response, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +-} +- +-template +-void connection::handle_write_http_response(lib::error_code const & ec) { +- m_alog->write(log::alevel::devel,"handle_write_http_response"); +- +- lib::error_code ecm = ec; +- +- if (!ecm) { +- scoped_lock_type lock(m_connection_state_lock); +- +- if (m_state == session::state::connecting) { +- if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { +- ecm = error::make_error_code(error::invalid_state); +- } +- } else if (m_state == session::state::closed) { +- // 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, +- "handle_write_http_response invoked after connection was closed"); +- return; +- } else { +- ecm = error::make_error_code(error::invalid_state); +- } +- } +- +- if (ecm) { +- 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, +- "got (expected) eof/state error from closed con"); +- return; +- } +- +- log_err(log::elevel::rerror,"handle_write_http_response",ecm); +- this->terminate(ecm); +- return; +- } +- +- 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_processor || m_ec == error::http_parse_error || +- m_ec == error::invalid_version || m_ec == error::unsupported_version +- || m_ec == error::upgrade_required) +- {*/ +- if (!m_is_http) { +- std::stringstream s; +- s << "Handshake ended with HTTP error: " +- << m_response.get_status_code(); +- 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->log_http_result(); +- +- if (m_ec) { +- 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); +- } +- +- this->terminate(m_ec); +- return; +- } +- +- this->log_open_result(); +- +- m_internal_state = istate::PROCESS_CONNECTION; +- m_state = session::state::open; +- +- if (m_open_handler) { +- m_open_handler(m_connection_hdl); +- } +- +- this->handle_read_frame(lib::error_code(), m_buf_cursor); +-} +- +-template +-void connection::send_http_request() { +- m_alog->write(log::alevel::devel,"connection send_http_request"); +- +- // TODO: origin header? +- +- // Have the protocol processor fill in the appropriate fields based on the +- // selected client version +- if (m_processor) { +- lib::error_code ec; +- ec = m_processor->client_handshake_request(m_request,m_uri, +- m_requested_subprotocols); +- +- if (ec) { +- log_err(log::elevel::fatal,"Internal library error: Processor",ec); +- return; +- } +- } else { +- m_elog->write(log::elevel::fatal,"Internal library error: missing processor"); +- return; +- } +- +- // Unless the user has overridden the user agent, send generic WS++ UA. +- if (m_request.get_header("User-Agent").empty()) { +- if (!m_user_agent.empty()) { +- m_request.replace_header("User-Agent",m_user_agent); +- } else { +- m_request.remove_header("User-Agent"); +- } +- } +- +- 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_open_handshake_timeout_dur > 0) { +- m_handshake_timer = transport_con_type::set_timer( +- m_open_handshake_timeout_dur, +- lib::bind( +- &type::handle_open_handshake_timeout, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +- } +- +- transport_con_type::async_write( +- m_handshake_buffer.data(), +- m_handshake_buffer.size(), +- lib::bind( +- &type::handle_send_http_request, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +-} +- +-template +-void connection::handle_send_http_request(lib::error_code const & ec) { +- m_alog->write(log::alevel::devel,"handle_send_http_request"); +- +- lib::error_code ecm = ec; +- +- if (!ecm) { +- scoped_lock_type lock(m_connection_state_lock); +- +- if (m_state == session::state::connecting) { +- if (m_internal_state != istate::WRITE_HTTP_REQUEST) { +- ecm = error::make_error_code(error::invalid_state); +- } else { +- m_internal_state = istate::READ_HTTP_RESPONSE; +- } +- } else if (m_state == session::state::closed) { +- // 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, +- "handle_send_http_request invoked after connection was closed"); +- return; +- } else { +- ecm = error::make_error_code(error::invalid_state); +- } +- } +- +- if (ecm) { +- 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, +- "got (expected) eof/state error from closed con"); +- return; +- } +- +- log_err(log::elevel::rerror,"handle_send_http_request",ecm); +- this->terminate(ecm); +- return; +- } +- +- transport_con_type::async_read_at_least( +- 1, +- m_buf, +- config::connection_read_buffer_size, +- lib::bind( +- &type::handle_read_http_response, +- type::get_shared(), +- lib::placeholders::_1, +- lib::placeholders::_2 +- ) +- ); +-} +- +-template +-void connection::handle_read_http_response(lib::error_code const & ec, +- size_t bytes_transferred) +-{ +- m_alog->write(log::alevel::devel,"handle_read_http_response"); +- +- lib::error_code ecm = ec; +- +- if (!ecm) { +- scoped_lock_type lock(m_connection_state_lock); +- +- if (m_state == session::state::connecting) { +- if (m_internal_state != istate::READ_HTTP_RESPONSE) { +- ecm = error::make_error_code(error::invalid_state); +- } +- } else if (m_state == session::state::closed) { +- // 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, +- "handle_read_http_response invoked after connection was closed"); +- return; +- } else { +- ecm = error::make_error_code(error::invalid_state); +- } +- } +- +- if (ecm) { +- 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, +- "got (expected) eof/state error from closed con"); +- return; +- } +- +- log_err(log::elevel::rerror,"handle_read_http_response",ecm); +- this->terminate(ecm); +- return; +- } +- +- size_t bytes_processed = 0; +- // TODO: refactor this to use error codes rather than exceptions +- try { +- bytes_processed = m_response.consume(m_buf,bytes_transferred); +- } catch (http::exception & e) { +- m_elog->write(log::elevel::rerror, +- std::string("error in handle_read_http_response: ")+e.what()); +- this->terminate(make_error_code(error::general)); +- return; +- } +- +- m_alog->write(log::alevel::devel,std::string("Raw response: ")+m_response.raw()); +- +- if (m_response.headers_ready()) { +- if (m_handshake_timer) { +- m_handshake_timer->cancel(); +- m_handshake_timer.reset(); +- } +- +- lib::error_code validate_ec = m_processor->validate_server_handshake_response( +- m_request, +- m_response +- ); +- if (validate_ec) { +- log_err(log::elevel::rerror,"Server handshake response",validate_ec); +- this->terminate(validate_ec); +- return; +- } +- +- // Read extension parameters and set up values necessary for the end +- // user to complete extension negotiation. +- std::pair neg_results; +- neg_results = m_processor->negotiate_extensions(m_response); +- +- if (neg_results.first) { +- // There was a fatal error in extension negotiation. For the moment +- // kill all connections that fail extension negotiation. +- +- // TODO: deal with cases where the response is well formed but +- // 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: " +- + neg_results.first.message()); +- this->terminate(make_error_code(error::extension_neg_failed)); +- // TODO: close connection with reason 1010 (and list extensions) +- } +- +- // response is valid, connection can now be assumed to be open +- m_internal_state = istate::PROCESS_CONNECTION; +- m_state = session::state::open; +- +- this->log_open_result(); +- +- if (m_open_handler) { +- m_open_handler(m_connection_hdl); +- } +- +- // The remaining bytes in m_buf are frame data. Copy them to the +- // beginning of the buffer and note the length. They will be read after +- // the handshake completes and before more bytes are read. +- std::copy(m_buf+bytes_processed,m_buf+bytes_transferred,m_buf); +- m_buf_cursor = bytes_transferred-bytes_processed; +- +- this->handle_read_frame(lib::error_code(), m_buf_cursor); +- } else { +- transport_con_type::async_read_at_least( +- 1, +- m_buf, +- config::connection_read_buffer_size, +- lib::bind( +- &type::handle_read_http_response, +- type::get_shared(), +- lib::placeholders::_1, +- lib::placeholders::_2 +- ) +- ); +- } +-} +- +-template +-void connection::handle_open_handshake_timeout( +- lib::error_code const & ec) +-{ +- 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, +- "open handle_open_handshake_timeout error: "+ec.message()); +- // TODO: ignore or fail here? +- } else { +- m_alog->write(log::alevel::devel,"open handshake timer expired"); +- terminate(make_error_code(error::open_handshake_timeout)); +- } +-} +- +-template +-void connection::handle_close_handshake_timeout( +- lib::error_code const & ec) +-{ +- 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, +- "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"); +- terminate(make_error_code(error::close_handshake_timeout)); +- } +-} +- +-template +-void connection::terminate(lib::error_code const & ec) { +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection terminate"); +- } +- +- // Cancel close handshake timer +- if (m_handshake_timer) { +- m_handshake_timer->cancel(); +- m_handshake_timer.reset(); +- } +- +- terminate_status tstat = unknown; +- if (ec) { +- m_ec = ec; +- m_local_close_code = close::status::abnormal_close; +- m_local_close_reason = ec.message(); +- } +- +- // TODO: does any of this need a mutex? +- if (m_is_http) { +- m_http_state = session::http_state::closed; +- } +- if (m_state == session::state::connecting) { +- m_state = session::state::closed; +- tstat = failed; +- +- // Log fail result here before socket is shut down and we can't get +- // the remote address, etc anymore +- 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, +- "terminate called on connection that was already terminated"); +- return; +- } +- +- // TODO: choose between shutdown and close based on error code sent +- +- transport_con_type::async_shutdown( +- lib::bind( +- &type::handle_terminate, +- type::get_shared(), +- tstat, +- lib::placeholders::_1 +- ) +- ); +-} +- +-template +-void connection::handle_terminate(terminate_status tstat, +- lib::error_code const & ec) +-{ +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection handle_terminate"); +- } +- +- if (ec) { +- // there was an error actually shutting down the connection +- log_err(log::elevel::devel,"handle_terminate",ec); +- } +- +- // clean shutdown +- if (tstat == failed) { +- if (m_ec != error::http_connection_ended) { +- if (m_fail_handler) { +- m_fail_handler(m_connection_hdl); +- } +- } +- } else if (tstat == closed) { +- if (m_close_handler) { +- m_close_handler(m_connection_hdl); +- } +- log_close_result(); +- } else { +- m_elog->write(log::elevel::rerror,"Unknown terminate_status"); +- } +- +- // call the termination handler if it exists +- // if it exists it might (but shouldn't) refer to a bad memory location. +- // If it does, we don't care and should catch and ignore it. +- if (m_termination_handler) { +- try { +- m_termination_handler(type::get_shared()); +- } catch (std::exception const & e) { +- m_elog->write(log::elevel::warn, +- std::string("termination_handler call failed. Reason was: ")+e.what()); +- } +- } +-} +- +-template +-void connection::write_frame() { +- //m_alog->write(log::alevel::devel,"connection write_frame"); +- +- { +- scoped_lock_type lock(m_write_lock); +- +- // Check the write flag. If true, there is an outstanding transport +- // write already. In this case we just return. The write handler will +- // start a new write if the write queue isn't empty. If false, we set +- // the write flag and proceed to initiate a transport write. +- if (m_write_flag) { +- return; +- } +- +- // pull off all the messages that are ready to write. +- // stop if we get a message marked terminal +- message_ptr next_message = write_pop(); +- while (next_message) { +- m_current_msgs.push_back(next_message); +- if (!next_message->get_terminal()) { +- next_message = write_pop(); +- } else { +- next_message = message_ptr(); +- } +- } +- +- if (m_current_msgs.empty()) { +- // there was nothing to send +- return; +- } else { +- // At this point we own the next messages to be sent and are +- // responsible for holding the write flag until they are +- // successfully sent or there is some error +- m_write_flag = true; +- } +- } +- +- typename std::vector::iterator it; +- for (it = m_current_msgs.begin(); it != m_current_msgs.end(); ++it) { +- std::string const & header = (*it)->get_header(); +- std::string const & payload = (*it)->get_payload(); +- +- m_send_buffer.push_back(transport::buffer(header.c_str(),header.size())); +- m_send_buffer.push_back(transport::buffer(payload.c_str(),payload.size())); +- } +- +- // 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)) { +- std::stringstream general,header,payload; +- +- general << "Dispatching write containing " << m_current_msgs.size() +- <<" message(s) containing "; +- header << "Header Bytes: \n"; +- payload << "Payload Bytes: \n"; +- +- size_t hbytes = 0; +- size_t pbytes = 0; +- +- for (size_t i = 0; i < m_current_msgs.size(); i++) { +- hbytes += m_current_msgs[i]->get_header().size(); +- pbytes += m_current_msgs[i]->get_payload().size(); +- +- +- header << "[" << i << "] (" +- << 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)) { +- payload << "[" << i << "] (" +- << m_current_msgs[i]->get_payload().size() << ") ["<get_opcode()<<"] " +- << (m_current_msgs[i]->get_opcode() == frame::opcode::text ? +- m_current_msgs[i]->get_payload() : +- utility::to_hex(m_current_msgs[i]->get_payload()) +- ) +- << "\n"; +- } +- } +- } +- +- 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()); +- } +- } +- +- transport_con_type::async_write( +- m_send_buffer, +- m_write_frame_handler +- ); +-} +- +-template +-void connection::handle_write_frame(lib::error_code const & ec) +-{ +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel,"connection handle_write_frame"); +- } +- +- bool terminal = m_current_msgs.back()->get_terminal(); +- +- m_send_buffer.clear(); +- m_current_msgs.clear(); +- // TODO: recycle instead of deleting +- +- if (ec) { +- log_err(log::elevel::fatal,"handle_write_frame",ec); +- this->terminate(ec); +- return; +- } +- +- if (terminal) { +- this->terminate(lib::error_code()); +- return; +- } +- +- bool needs_writing = false; +- { +- scoped_lock_type lock(m_write_lock); +- +- // release write flag +- m_write_flag = false; +- +- needs_writing = !m_send_queue.empty(); +- } +- +- if (needs_writing) { +- transport_con_type::dispatch(lib::bind( +- &type::write_frame, +- type::get_shared() +- )); +- } +-} +- +-template +-std::vector const & connection::get_supported_versions() const +-{ +- return versions_supported; +-} +- +-template +-void connection::process_control_frame(typename config::message_type::ptr msg) +-{ +- 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()); +- +- if (m_state == session::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"); +- return; +- } +- +- if (op == frame::opcode::PING) { +- bool should_reply = true; +- +- if (m_ping_handler) { +- should_reply = m_ping_handler(m_connection_hdl, msg->get_payload()); +- } +- +- if (should_reply) { +- this->pong(msg->get_payload(),ec); +- if (ec) { +- log_err(log::elevel::devel,"Failed to send response pong",ec); +- } +- } +- } else if (op == frame::opcode::PONG) { +- if (m_pong_handler) { +- m_pong_handler(m_connection_hdl, msg->get_payload()); +- } +- if (m_ping_timer) { +- m_ping_timer->cancel(); +- } +- } else if (op == frame::opcode::CLOSE) { +- 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); +- if (ec) { +- s.str(""); +- 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()); +- 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()); +- ec = send_close_ack(close::status::protocol_error, +- "Invalid close code"); +- if (ec) { +- log_err(log::elevel::devel,"send_close_ack",ec); +- } +- } +- return; +- } +- +- 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, +- "Received invalid close reason. Dropping connection per config"); +- this->terminate(ec); +- } else { +- 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"); +- if (ec) { +- log_err(log::elevel::devel,"send_close_ack",ec); +- } +- } +- return; +- } +- +- if (m_state == session::state::open) { +- 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()); +- +- ec = send_close_ack(); +- if (ec) { +- log_err(log::elevel::devel,"send_close_ack",ec); +- } +- } 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_was_clean = true; +- +- // If we are a server terminate the connection now. Clients should +- // leave the connection open to give the server an opportunity to +- // initiate the TCP close. The client's timer will handle closing +- // its side of the connection if the server misbehaves. +- // +- // TODO: different behavior if the underlying transport doesn't +- // support timers? +- if (m_is_server) { +- terminate(lib::error_code()); +- } +- } else { +- // spurious, ignore +- 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"); +- // initiate protocol error shutdown +- } +-} +- +-template +-lib::error_code connection::send_close_ack(close::status::value code, +- std::string const & reason) +-{ +- return send_close_frame(code,reason,true,m_is_server); +-} +- +-template +-lib::error_code connection::send_close_frame(close::status::value code, +- std::string const & reason, bool ack, bool terminal) +-{ +- m_alog->write(log::alevel::devel,"send_close_frame"); +- +- // check for special codes +- +- // If silent close is set, respect it and blank out close information +- // Otherwise use whatever has been specified in the parameters. If +- // parameters specifies close::status::blank then determine what to do +- // based on whether or not this is an ack. If it is not an ack just +- // 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_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_local_close_code = code; +- m_local_close_reason = reason; +- } else if (!ack) { +- 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, +- "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_local_close_code = m_remote_close_code; +- m_local_close_reason = m_remote_close_reason; +- } +- +- 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()); +- +- message_ptr msg = m_msg_manager->get_message(); +- if (!msg) { +- return error::make_error_code(error::no_outgoing_buffers); +- } +- +- lib::error_code ec = m_processor->prepare_close(m_local_close_code, +- m_local_close_reason,msg); +- if (ec) { +- return ec; +- } +- +- // Messages flagged terminal will result in the TCP connection being dropped +- // after the message has been written. This is typically used when servers +- // send an ack and when any endpoint encounters a protocol error +- if (terminal) { +- msg->set_terminal(true); +- } +- +- m_state = session::state::closing; +- +- if (ack) { +- m_was_clean = true; +- } +- +- // Start a timer so we don't wait forever for the acknowledgement close +- // frame +- if (m_close_handshake_timeout_dur > 0) { +- m_handshake_timer = transport_con_type::set_timer( +- m_close_handshake_timeout_dur, +- lib::bind( +- &type::handle_close_handshake_timeout, +- type::get_shared(), +- lib::placeholders::_1 +- ) +- ); +- } +- +- bool needs_writing = false; +- { +- scoped_lock_type lock(m_write_lock); +- write_push(msg); +- needs_writing = !m_write_flag && !m_send_queue.empty(); +- } +- +- if (needs_writing) { +- transport_con_type::dispatch(lib::bind( +- &type::write_frame, +- type::get_shared() +- )); +- } +- +- return lib::error_code(); +-} +- +-template +-typename connection::processor_ptr +-connection::get_processor(int version) const { +- // TODO: allow disabling certain versions +- +- processor_ptr p; +- +- switch (version) { +- case 0: +- p = lib::make_shared >( +- transport_con_type::is_secure(), +- m_is_server, +- m_msg_manager +- ); +- break; +- case 7: +- p = lib::make_shared >( +- transport_con_type::is_secure(), +- m_is_server, +- m_msg_manager, +- lib::ref(m_rng) +- ); +- break; +- case 8: +- p = lib::make_shared >( +- transport_con_type::is_secure(), +- m_is_server, +- m_msg_manager, +- lib::ref(m_rng) +- ); +- break; +- case 13: +- p = lib::make_shared >( +- transport_con_type::is_secure(), +- m_is_server, +- m_msg_manager, +- lib::ref(m_rng) +- ); +- break; +- default: +- return p; +- } +- +- // Settings not configured by the constructor +- p->set_max_message_size(m_max_message_size); +- +- return p; +-} +- +-template +-void connection::write_push(typename config::message_type::ptr msg) +-{ +- if (!msg) { +- return; +- } +- +- m_send_buffer_size += msg->get_payload().size(); +- m_send_queue.push(msg); +- +- 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()); +- } +-} +- +-template +-typename config::message_type::ptr connection::write_pop() +-{ +- message_ptr msg; +- +- if (m_send_queue.empty()) { +- return msg; +- } +- +- msg = m_send_queue.front(); +- +- m_send_buffer_size -= msg->get_payload().size(); +- m_send_queue.pop(); +- +- 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()); +- } +- return msg; +-} +- +-template +-void connection::log_open_result() +-{ +- std::stringstream s; +- +- int version; +- if (!processor::is_websocket_handshake(m_request)) { +- version = -1; +- } else { +- version = processor::get_websocket_version(m_request); +- } +- +- // Connection Type +- s << (version == -1 ? "HTTP" : "WebSocket") << " Connection "; +- +- // Remote endpoint address +- s << transport_con_type::get_remote_endpoint() << " "; +- +- // Version string if WebSocket +- if (version != -1) { +- s << "v" << version << " "; +- } +- +- // User Agent +- std::string ua = m_request.get_header("User-Agent"); +- if (ua.empty()) { +- s << "\"\" "; +- } else { +- // check if there are any quotes in the user agent +- s << "\"" << utility::string_replace_all(ua,"\"","\\\"") << "\" "; +- } +- +- // URI +- s << (m_uri ? m_uri->get_resource() : "NULL") << " "; +- +- // Status code +- s << m_response.get_status_code(); +- +- m_alog->write(log::alevel::connect,s.str()); +-} +- +-template +-void connection::log_close_result() +-{ +- std::stringstream s; +- +- s << "Disconnect " +- << "close local:[" << m_local_close_code +- << (m_local_close_reason.empty() ? "" : ","+m_local_close_reason) +- << "] remote:[" << m_remote_close_code +- << (m_remote_close_reason.empty() ? "" : ","+m_remote_close_reason) << "]"; +- +- m_alog->write(log::alevel::disconnect,s.str()); +-} +- +-template +-void connection::log_fail_result() +-{ +- std::stringstream s; +- +- int version = processor::get_websocket_version(m_request); +- +- // Connection Type +- s << "WebSocket Connection "; +- +- // Remote endpoint address & WebSocket version +- s << transport_con_type::get_remote_endpoint(); +- if (version < 0) { +- s << " -"; +- } else { +- s << " v" << version; +- } +- +- // User Agent +- std::string ua = m_request.get_header("User-Agent"); +- if (ua.empty()) { +- s << " \"\" "; +- } else { +- // check if there are any quotes in the user agent +- s << " \"" << utility::string_replace_all(ua,"\"","\\\"") << "\" "; +- } +- +- // URI +- s << (m_uri ? m_uri->get_resource() : "-"); +- +- // HTTP Status code +- s << " " << m_response.get_status_code(); +- +- // WebSocket++ error code & reason +- s << " " << m_ec << " " << m_ec.message(); +- +- m_alog->write(log::alevel::fail,s.str()); +-} +- +-template +-void connection::log_http_result() { +- std::stringstream s; +- +- if (processor::is_websocket_handshake(m_request)) { +- m_alog->write(log::alevel::devel,"Call to log_http_result for WebSocket"); +- return; +- } +- +- // Connection Type +- s << (m_request.get_header("host").empty() ? "-" : m_request.get_header("host")) +- << " " << transport_con_type::get_remote_endpoint() +- << " \"" << m_request.get_method() +- << " " << (m_uri ? m_uri->get_resource() : "-") +- << " " << m_request.get_version() << "\" " << m_response.get_status_code() +- << " " << m_response.get_body().size(); +- +- // User Agent +- std::string ua = m_request.get_header("User-Agent"); +- if (ua.empty()) { +- s << " \"\" "; +- } else { +- // check if there are any quotes in the user agent +- s << " \"" << utility::string_replace_all(ua,"\"","\\\"") << "\" "; +- } +- +- m_alog->write(log::alevel::http,s.str()); +-} +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_CONNECTION_IMPL_HPP +diff --git a/src/lib/websocketpp/impl/endpoint_impl.hpp b/src/lib/websocketpp/impl/endpoint_impl.hpp +deleted file mode 100644 +index 8223ccd..0000000 +--- a/src/lib/websocketpp/impl/endpoint_impl.hpp ++++ /dev/null +@@ -1,269 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_ENDPOINT_IMPL_HPP +-#define WEBSOCKETPP_ENDPOINT_IMPL_HPP +- +-#include +- +-namespace ws_websocketpp { +- +-template +-typename endpoint::connection_ptr +-endpoint::create_connection() { +- m_alog->write(log::alevel::devel,"create_connection"); +- //scoped_lock_type lock(m_state_lock); +- +- /*if (m_state == STOPPING || m_state == STOPPED) { +- return connection_ptr(); +- }*/ +- +- //scoped_lock_type guard(m_mutex); +- // Create a connection on the heap and manage it using a shared pointer +- connection_ptr con = lib::make_shared(m_is_server, +- m_user_agent, m_alog, m_elog, lib::ref(m_rng)); +- +- connection_weak_ptr w(con); +- +- // Create a weak pointer on the heap using that shared_ptr. +- // Cast that weak pointer to void* and manage it using another shared_ptr +- // connection_hdl hdl(reinterpret_cast(new connection_weak_ptr(con))); +- +- con->set_handle(w); +- +- // Copy default handlers from the endpoint +- con->set_open_handler(m_open_handler); +- con->set_close_handler(m_close_handler); +- con->set_fail_handler(m_fail_handler); +- con->set_ping_handler(m_ping_handler); +- con->set_pong_handler(m_pong_handler); +- con->set_pong_timeout_handler(m_pong_timeout_handler); +- con->set_interrupt_handler(m_interrupt_handler); +- con->set_http_handler(m_http_handler); +- con->set_validate_handler(m_validate_handler); +- con->set_message_handler(m_message_handler); +- +- if (m_open_handshake_timeout_dur != config::timeout_open_handshake) { +- con->set_open_handshake_timeout(m_open_handshake_timeout_dur); +- } +- if (m_close_handshake_timeout_dur != config::timeout_close_handshake) { +- con->set_close_handshake_timeout(m_close_handshake_timeout_dur); +- } +- if (m_pong_timeout_dur != config::timeout_pong) { +- con->set_pong_timeout(m_pong_timeout_dur); +- } +- if (m_max_message_size != config::max_message_size) { +- con->set_max_message_size(m_max_message_size); +- } +- con->set_max_http_body_size(m_max_http_body_size); +- +- lib::error_code ec; +- +- ec = transport_type::init(con); +- if (ec) { +- m_elog->write(log::elevel::fatal,ec.message()); +- return connection_ptr(); +- } +- +- return con; +-} +- +-template +-void endpoint::interrupt(connection_hdl hdl, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- +- m_alog->write(log::alevel::devel,"Interrupting connection"); +- +- ec = con->interrupt(); +-} +- +-template +-void endpoint::interrupt(connection_hdl hdl) { +- lib::error_code ec; +- interrupt(hdl,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::pause_reading(connection_hdl hdl, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- +- ec = con->pause_reading(); +-} +- +-template +-void endpoint::pause_reading(connection_hdl hdl) { +- lib::error_code ec; +- pause_reading(hdl,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::resume_reading(connection_hdl hdl, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- +- ec = con->resume_reading(); +-} +- +-template +-void endpoint::resume_reading(connection_hdl hdl) { +- lib::error_code ec; +- resume_reading(hdl,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::send_http_response(connection_hdl hdl, +- lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- con->send_http_response(ec); +-} +- +-template +-void endpoint::send_http_response(connection_hdl hdl) { +- lib::error_code ec; +- send_http_response(hdl,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::send(connection_hdl hdl, std::string const & payload, +- frame::opcode::value op, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- +- ec = con->send(payload,op); +-} +- +-template +-void endpoint::send(connection_hdl hdl, std::string const & payload, +- frame::opcode::value op) +-{ +- lib::error_code ec; +- send(hdl,payload,op,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::send(connection_hdl hdl, void const * payload, +- size_t len, frame::opcode::value op, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- ec = con->send(payload,len,op); +-} +- +-template +-void endpoint::send(connection_hdl hdl, void const * payload, +- size_t len, frame::opcode::value op) +-{ +- lib::error_code ec; +- send(hdl,payload,len,op,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::send(connection_hdl hdl, message_ptr msg, +- lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- ec = con->send(msg); +-} +- +-template +-void endpoint::send(connection_hdl hdl, message_ptr msg) { +- lib::error_code ec; +- send(hdl,msg,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::close(connection_hdl hdl, close::status::value +- const code, std::string const & reason, +- lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- con->close(code,reason,ec); +-} +- +-template +-void endpoint::close(connection_hdl hdl, close::status::value +- const code, std::string const & reason) +-{ +- lib::error_code ec; +- close(hdl,code,reason,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::ping(connection_hdl hdl, std::string const & +- payload, lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- con->ping(payload,ec); +-} +- +-template +-void endpoint::ping(connection_hdl hdl, std::string const & payload) +-{ +- lib::error_code ec; +- ping(hdl,payload,ec); +- if (ec) { throw exception(ec); } +-} +- +-template +-void endpoint::pong(connection_hdl hdl, std::string const & payload, +- lib::error_code & ec) +-{ +- connection_ptr con = get_con_from_hdl(hdl,ec); +- if (ec) {return;} +- con->pong(payload,ec); +-} +- +-template +-void endpoint::pong(connection_hdl hdl, std::string const & payload) +-{ +- lib::error_code ec; +- pong(hdl,payload,ec); +- if (ec) { throw exception(ec); } +-} +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_ENDPOINT_IMPL_HPP +diff --git a/src/lib/websocketpp/impl/utilities_impl.hpp b/src/lib/websocketpp/impl/utilities_impl.hpp +deleted file mode 100644 +index 206a6d0..0000000 +--- a/src/lib/websocketpp/impl/utilities_impl.hpp ++++ /dev/null +@@ -1,87 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_UTILITIES_IMPL_HPP +-#define WEBSOCKETPP_UTILITIES_IMPL_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace utility { +- +-inline std::string to_lower(std::string const & in) { +- std::string out = in; +- std::transform(out.begin(),out.end(),out.begin(),::tolower); +- return out; +-} +- +-inline std::string to_hex(std::string const & input) { +- std::string output; +- std::string hex = "0123456789ABCDEF"; +- +- for (size_t i = 0; i < input.size(); i++) { +- output += hex[(input[i] & 0xF0) >> 4]; +- output += hex[input[i] & 0x0F]; +- output += " "; +- } +- +- return output; +-} +- +-inline std::string to_hex(uint8_t const * input, size_t length) { +- std::string output; +- std::string hex = "0123456789ABCDEF"; +- +- for (size_t i = 0; i < length; i++) { +- output += hex[(input[i] & 0xF0) >> 4]; +- output += hex[input[i] & 0x0F]; +- output += " "; +- } +- +- return output; +-} +- +-inline std::string to_hex(const char* input,size_t length) { +- return to_hex(reinterpret_cast(input),length); +-} +- +-inline std::string string_replace_all(std::string subject, std::string const & +- search, std::string const & replace) +-{ +- size_t pos = 0; +- while((pos = subject.find(search, pos)) != std::string::npos) { +- subject.replace(pos, search.length(), replace); +- pos += replace.length(); +- } +- return subject; +-} +- +-} // namespace utility +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_UTILITIES_IMPL_HPP +diff --git a/src/lib/websocketpp/logger/basic.hpp b/src/lib/websocketpp/logger/basic.hpp +deleted file mode 100644 +index df4dfd6..0000000 +--- a/src/lib/websocketpp/logger/basic.hpp ++++ /dev/null +@@ -1,199 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_LOGGER_BASIC_HPP +-#define WEBSOCKETPP_LOGGER_BASIC_HPP +- +-/* Need a way to print a message to the log +- * +- * - timestamps +- * - channels +- * - thread safe +- * - output to stdout or file +- * - selective output channels, both compile time and runtime +- * - named channels +- * - ability to test whether a log message will be printed at compile time +- * +- */ +- +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace log { +- +-/// Basic logger that outputs to an ostream +-template +-class basic { +-public: +- basic(channel_type_hint::value h = +- channel_type_hint::access) +- : m_static_channels(0xffffffff) +- , m_dynamic_channels(0) +- , m_out(h == channel_type_hint::error ? (std::ostream*)&Rcpp::Rcerr : (std::ostream*)&Rcpp::Rcout) {} +- +- basic(std::ostream * out) +- : m_static_channels(0xffffffff) +- , m_dynamic_channels(0) +- , m_out(out) {} +- +- basic(level c, channel_type_hint::value h = +- channel_type_hint::access) +- : m_static_channels(c) +- , m_dynamic_channels(0) +- , m_out(h == channel_type_hint::error ? (std::ostream*)&Rcpp::Rcerr : (std::ostream*)&Rcpp::Rcout) {} +- +- basic(level c, std::ostream * out) +- : m_static_channels(c) +- , m_dynamic_channels(0) +- , m_out(out) {} +- +- /// Destructor +- ~basic() {} +- +- /// Copy constructor +- basic(basic const & other) +- : m_static_channels(other.m_static_channels) +- , m_dynamic_channels(other.m_dynamic_channels) +- , m_out(other.m_out) +- {} +- +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no copy assignment operator because of const member variables +- basic & operator=(basic const &) = delete; +-#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +-#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ +- /// Move constructor +- basic(basic && other) +- : m_static_channels(other.m_static_channels) +- , m_dynamic_channels(other.m_dynamic_channels) +- , m_out(other.m_out) +- {} +- +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no move assignment operator because of const member variables +- basic & operator=(basic &&) = delete; +-#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +-#endif // _WEBSOCKETPP_MOVE_SEMANTICS_ +- +- void set_ostream(std::ostream * out = (std::ostream*)&Rcpp::Rcout) { +- m_out = out; +- } +- +- void set_channels(level channels) { +- if (channels == names::none) { +- clear_channels(names::all); +- return; +- } +- +- scoped_lock_type lock(m_lock); +- m_dynamic_channels |= (channels & m_static_channels); +- } +- +- void clear_channels(level channels) { +- scoped_lock_type lock(m_lock); +- m_dynamic_channels &= ~channels; +- } +- +- /// Write a string message to the given channel +- /** +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level channel, std::string const & msg) { +- scoped_lock_type lock(m_lock); +- if (!this->dynamic_test(channel)) { return; } +- *m_out << "[" << timestamp << "] " +- << "[" << names::channel_name(channel) << "] " +- << msg << "\n"; +- m_out->flush(); +- } +- +- /// Write a cstring message to the given channel +- /** +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level channel, char const * msg) { +- scoped_lock_type lock(m_lock); +- if (!this->dynamic_test(channel)) { return; } +- *m_out << "[" << timestamp << "] " +- << "[" << names::channel_name(channel) << "] " +- << msg << "\n"; +- m_out->flush(); +- } +- +- _WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) const { +- return ((channel & m_static_channels) != 0); +- } +- +- bool dynamic_test(level channel) { +- return ((channel & m_dynamic_channels) != 0); +- } +- +-protected: +- typedef typename concurrency::scoped_lock_type scoped_lock_type; +- typedef typename concurrency::mutex_type mutex_type; +- mutex_type m_lock; +- +-private: +- // The timestamp does not include the time zone, because on Windows with the +- // default registry settings, the time zone would be written out in full, +- // which would be obnoxiously verbose. +- // +- // TODO: find a workaround for this or make this format user settable +- static std::ostream & timestamp(std::ostream & os) { +- std::time_t t = std::time(NULL); +- std::tm lt = lib::localtime(t); +- #ifdef _WEBSOCKETPP_PUTTIME_ +- return os << std::put_time(<,"%Y-%m-%d %H:%M:%S"); +- #else // Falls back to strftime, which requires a temporary copy of the string. +- char buffer[20]; +- size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",<); +- return os << (result == 0 ? "Unknown" : buffer); +- #endif +- } +- +- level const m_static_channels; +- level m_dynamic_channels; +- std::ostream * m_out; +-}; +- +-} // log +-} // websocketpp +- +-#endif // WEBSOCKETPP_LOGGER_BASIC_HPP +diff --git a/src/lib/websocketpp/logger/levels.hpp b/src/lib/websocketpp/logger/levels.hpp +deleted file mode 100644 +index acaf4c1..0000000 +--- a/src/lib/websocketpp/logger/levels.hpp ++++ /dev/null +@@ -1,203 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_LOGGER_LEVELS_HPP +-#define WEBSOCKETPP_LOGGER_LEVELS_HPP +- +-#include +- +-namespace ws_websocketpp { +-namespace log { +- +-/// Type of a channel package +-typedef uint32_t level; +- +-/// Package of values for hinting at the nature of a given logger. +-/** +- * Used by the library to signal to the logging class a hint that it can use to +- * set itself up. For example, the `access` hint indicates that it is an access +- * log that might be suitable for being printed to an access log file or to cout +- * whereas `error` might be suitable for an error log file or cerr. +- */ +-struct channel_type_hint { +- /// Type of a channel type hint value +- typedef uint32_t value; +- +- /// No information +- static value const none = 0; +- /// Access log +- static value const access = 1; +- /// Error log +- static value const error = 2; +-}; +- +-/// Package of log levels for logging errors +-struct elevel { +- /// Special aggregate value representing "no levels" +- static level const none = 0x0; +- /// Low level debugging information (warning: very chatty) +- static level const devel = 0x1; +- /// Information about unusual system states or other minor internal library +- /// problems, less chatty than devel. +- static level const library = 0x2; +- /// Information about minor configuration problems or additional information +- /// about other warnings. +- static level const info = 0x4; +- /// Information about important problems not severe enough to terminate +- /// connections. +- static level const warn = 0x8; +- /// Recoverable error. Recovery may mean cleanly closing the connection with +- /// an appropriate error code to the remote endpoint. +- static level const rerror = 0x10; +- /// Unrecoverable error. This error will trigger immediate unclean +- /// termination of the connection or endpoint. +- static level const fatal = 0x20; +- /// Special aggregate value representing "all levels" +- static level const all = 0xffffffff; +- +- /// Get the textual name of a channel given a channel id +- /** +- * The id must be that of a single channel. Passing an aggregate channel +- * package results in undefined behavior. +- * +- * @param channel The channel id to look up. +- * +- * @return The name of the specified channel. +- */ +- static char const * channel_name(level channel) { +- switch(channel) { +- case devel: +- return "devel"; +- case library: +- return "library"; +- case info: +- return "info"; +- case warn: +- return "warning"; +- case rerror: +- return "error"; +- case fatal: +- return "fatal"; +- default: +- return "unknown"; +- } +- } +-}; +- +-/// Package of log levels for logging access events +-struct alevel { +- /// Special aggregate value representing "no levels" +- static level const none = 0x0; +- /// Information about new connections +- /** +- * One line for each new connection that includes a host of information +- * including: the remote address, websocket version, requested resource, +- * http code, remote user agent +- */ +- static level const connect = 0x1; +- /// One line for each closed connection. Includes closing codes and reasons. +- static level const disconnect = 0x2; +- /// One line per control frame +- static level const control = 0x4; +- /// One line per frame, includes the full frame header +- static level const frame_header = 0x8; +- /// One line per frame, includes the full message payload (warning: chatty) +- static level const frame_payload = 0x10; +- /// Reserved +- static level const message_header = 0x20; +- /// Reserved +- static level const message_payload = 0x40; +- /// Reserved +- static level const endpoint = 0x80; +- /// Extra information about opening handshakes +- static level const debug_handshake = 0x100; +- /// Extra information about closing handshakes +- static level const debug_close = 0x200; +- /// Development messages (warning: very chatty) +- static level const devel = 0x400; +- /// Special channel for application specific logs. Not used by the library. +- static level const app = 0x800; +- /// Access related to HTTP requests +- static level const http = 0x1000; +- /// One line for each failed WebSocket connection with details +- static level const fail = 0x2000; +- /// Aggregate package representing the commonly used core access channels +- /// Connect, Disconnect, Fail, and HTTP +- static level const access_core = 0x00003003; +- /// Special aggregate value representing "all levels" +- static level const all = 0xffffffff; +- +- /// Get the textual name of a channel given a channel id +- /** +- * Get the textual name of a channel given a channel id. The id must be that +- * of a single channel. Passing an aggregate channel package results in +- * undefined behavior. +- * +- * @param channel The channelid to look up. +- * +- * @return The name of the specified channel. +- */ +- static char const * channel_name(level channel) { +- switch(channel) { +- case connect: +- return "connect"; +- case disconnect: +- return "disconnect"; +- case control: +- return "control"; +- case frame_header: +- return "frame_header"; +- case frame_payload: +- return "frame_payload"; +- case message_header: +- return "message_header"; +- case message_payload: +- return "message_payload"; +- case endpoint: +- return "endpoint"; +- case debug_handshake: +- return "debug_handshake"; +- case debug_close: +- return "debug_close"; +- case devel: +- return "devel"; +- case app: +- return "application"; +- case http: +- return "http"; +- case fail: +- return "fail"; +- default: +- return "unknown"; +- } +- } +-}; +- +-} // logger +-} // websocketpp +- +-#endif //WEBSOCKETPP_LOGGER_LEVELS_HPP +diff --git a/src/lib/websocketpp/logger/stub.hpp b/src/lib/websocketpp/logger/stub.hpp +deleted file mode 100644 +index aab1959..0000000 +--- a/src/lib/websocketpp/logger/stub.hpp ++++ /dev/null +@@ -1,119 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_LOGGER_STUB_HPP +-#define WEBSOCKETPP_LOGGER_STUB_HPP +- +-#include +- +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace log { +- +-/// Stub logger that ignores all input +-class stub { +-public: +- /// Construct the logger +- /** +- * @param hint A channel type specific hint for how to construct the logger +- */ +- explicit stub(channel_type_hint::value) {} +- +- /// Construct the logger +- /** +- * @param default_channels A set of channels to statically enable +- * @param hint A channel type specific hint for how to construct the logger +- */ +- stub(level, channel_type_hint::value) {} +- _WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {} +- +- /// Dynamically enable the given list of channels +- /** +- * All operations on the stub logger are no-ops and all arguments are +- * ignored +- * +- * @param channels The package of channels to enable +- */ +- void set_channels(level) {} +- +- /// Dynamically disable the given list of channels +- /** +- * All operations on the stub logger are no-ops and all arguments are +- * ignored +- * +- * @param channels The package of channels to disable +- */ +- void clear_channels(level) {} +- +- /// Write a string message to the given channel +- /** +- * Writing on the stub logger is a no-op and all arguments are ignored +- * +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level, std::string const &) {} +- +- /// Write a cstring message to the given channel +- /** +- * Writing on the stub logger is a no-op and all arguments are ignored +- * +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level, char const *) {} +- +- /// Test whether a channel is statically enabled +- /** +- * The stub logger has no channels so all arguments are ignored and +- * `static_test` always returns false. +- * +- * @param channel The package of channels to test +- */ +- _WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level) const { +- return false; +- } +- +- /// Test whether a channel is dynamically enabled +- /** +- * The stub logger has no channels so all arguments are ignored and +- * `dynamic_test` always returns false. +- * +- * @param channel The package of channels to test +- */ +- bool dynamic_test(level) { +- return false; +- } +-}; +- +-} // log +-} // websocketpp +- +-#endif // WEBSOCKETPP_LOGGER_STUB_HPP +diff --git a/src/lib/websocketpp/logger/syslog.hpp b/src/lib/websocketpp/logger/syslog.hpp +deleted file mode 100644 +index 2dbd87b..0000000 +--- a/src/lib/websocketpp/logger/syslog.hpp ++++ /dev/null +@@ -1,146 +0,0 @@ +-/* +- * 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. +- * +- * +- * The initial version of this logging policy was contributed to the WebSocket++ +- * project by Tom Hughes. +- */ +- +-#ifndef WEBSOCKETPP_LOGGER_SYSLOG_HPP +-#define WEBSOCKETPP_LOGGER_SYSLOG_HPP +- +-#include +- +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace log { +- +-/// Basic logger that outputs to syslog +-template +-class syslog : public basic { +-public: +- typedef basic base; +- +- /// Construct the logger +- /** +- * @param hint A channel type specific hint for how to construct the logger +- */ +- syslog(channel_type_hint::value hint = +- channel_type_hint::access) +- : basic(hint), m_channel_type_hint(hint) {} +- +- /// Construct the logger +- /** +- * @param channels A set of channels to statically enable +- * @param hint A channel type specific hint for how to construct the logger +- */ +- syslog(level channels, channel_type_hint::value hint = +- channel_type_hint::access) +- : basic(channels, hint), m_channel_type_hint(hint) {} +- +- /// Write a string message to the given channel +- /** +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level channel, std::string const & msg) { +- write(channel, msg.c_str()); +- } +- +- /// Write a cstring message to the given channel +- /** +- * @param channel The channel to write to +- * @param msg The message to write +- */ +- void write(level channel, char const * msg) { +- scoped_lock_type lock(base::m_lock); +- if (!this->dynamic_test(channel)) { return; } +- ::syslog(syslog_priority(channel), "[%s] %s", +- names::channel_name(channel), msg); +- } +-private: +- typedef typename base::scoped_lock_type scoped_lock_type; +- +- /// The default level is used for all access logs and any error logs that +- /// don't trivially map to one of the standard syslog levels. +- static int const default_level = LOG_INFO; +- +- /// retrieve the syslog priority code given a WebSocket++ channel +- /** +- * @param channel The level to look up +- * @return The syslog level associated with `channel` +- */ +- int syslog_priority(level channel) const { +- if (m_channel_type_hint == channel_type_hint::access) { +- return syslog_priority_access(channel); +- } else { +- return syslog_priority_error(channel); +- } +- } +- +- /// retrieve the syslog priority code given a WebSocket++ error channel +- /** +- * @param channel The level to look up +- * @return The syslog level associated with `channel` +- */ +- int syslog_priority_error(level channel) const { +- switch (channel) { +- case elevel::devel: +- return LOG_DEBUG; +- case elevel::library: +- return LOG_DEBUG; +- case elevel::info: +- return LOG_INFO; +- case elevel::warn: +- return LOG_WARNING; +- case elevel::rerror: +- return LOG_ERR; +- case elevel::fatal: +- return LOG_CRIT; +- default: +- return default_level; +- } +- } +- +- /// retrieve the syslog priority code given a WebSocket++ access channel +- /** +- * @param channel The level to look up +- * @return The syslog level associated with `channel` +- */ +- _WEBSOCKETPP_CONSTEXPR_TOKEN_ int syslog_priority_access(level) const { +- return default_level; +- } +- +- channel_type_hint::value m_channel_type_hint; +-}; +- +-} // log +-} // websocketpp +- +-#endif // WEBSOCKETPP_LOGGER_SYSLOG_HPP +diff --git a/src/lib/websocketpp/message_buffer/alloc.hpp b/src/lib/websocketpp/message_buffer/alloc.hpp +deleted file mode 100644 +index 270aea4..0000000 +--- a/src/lib/websocketpp/message_buffer/alloc.hpp ++++ /dev/null +@@ -1,105 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +-#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace message_buffer { +-namespace alloc { +- +-/// A connection message manager that allocates a new message for each +-/// request. +-template +-class con_msg_manager +- : public lib::enable_shared_from_this > +-{ +-public: +- typedef con_msg_manager type; +- typedef lib::shared_ptr ptr; +- typedef lib::weak_ptr weak_ptr; +- +- typedef typename message::ptr message_ptr; +- +- /// Get an empty message buffer +- /** +- * @return A shared pointer to an empty new message +- */ +- message_ptr get_message() { +- return message_ptr(lib::make_shared(type::shared_from_this())); +- } +- +- /// Get a message buffer with specified size and opcode +- /** +- * @param op The opcode to use +- * @param size Minimum size in bytes to request for the message payload. +- * +- * @return A shared pointer to a new message with specified size. +- */ +- message_ptr get_message(frame::opcode::value op,size_t size) { +- return message_ptr(lib::make_shared(type::shared_from_this(),op,size)); +- } +- +- /// Recycle a message +- /** +- * This method shouldn't be called. If it is, return false to indicate an +- * error. The rest of the method recycle chain should notice this and free +- * the memory. +- * +- * @param msg The message to be recycled. +- * +- * @return true if the message was successfully recycled, false otherwse. +- */ +- bool recycle(message *) { +- return false; +- } +-}; +- +-/// An endpoint message manager that allocates a new manager for each +-/// connection. +-template +-class endpoint_msg_manager { +-public: +- typedef typename con_msg_manager::ptr con_msg_man_ptr; +- +- /// Get a pointer to a connection message manager +- /** +- * @return A pointer to the requested connection message manager. +- */ +- con_msg_man_ptr get_manager() const { +- return con_msg_man_ptr(lib::make_shared()); +- } +-}; +- +-} // namespace alloc +-} // namespace message_buffer +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +diff --git a/src/lib/websocketpp/message_buffer/message.hpp b/src/lib/websocketpp/message_buffer/message.hpp +deleted file mode 100644 +index 34d7733..0000000 +--- a/src/lib/websocketpp/message_buffer/message.hpp ++++ /dev/null +@@ -1,340 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP +-#define WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace message_buffer { +- +-/* # message: +- * object that stores a message while it is being sent or received. Contains +- * the message payload itself, the message header, the extension data, and the +- * opcode. +- * +- * # connection_message_manager: +- * An object that manages all of the message_buffers associated with a given +- * connection. Implements the get_message_buffer(size) method that returns +- * a message buffer at least size bytes long. +- * +- * Message buffers are reference counted with shared ownership semantics. Once +- * requested from the manager the requester and it's associated downstream code +- * may keep a pointer to the message indefinitely at a cost of extra resource +- * usage. Once the reference count drops to the point where the manager is the +- * only reference the messages is recycled using whatever method is implemented +- * in the manager. +- * +- * # endpoint_message_manager: +- * An object that manages connection_message_managers. Implements the +- * get_message_manager() method. This is used once by each connection to +- * request the message manager that they are supposed to use to manage message +- * buffers for their own use. +- * +- * TYPES OF CONNECTION_MESSAGE_MANAGERS +- * - allocate a message with the exact size every time one is requested +- * - maintain a pool of pre-allocated messages and return one when needed. +- * Recycle previously used messages back into the pool +- * +- * TYPES OF ENDPOINT_MESSAGE_MANAGERS +- * - allocate a new connection manager for each connection. Message pools +- * become connection specific. This increases memory usage but improves +- * concurrency. +- * - allocate a single connection manager and share a pointer to it with all +- * connections created by this endpoint. The message pool will be shared +- * among all connections, improving memory usage and performance at the cost +- * of reduced concurrency +- */ +- +- +-/// Represents a buffer for a single WebSocket message. +-/** +- * +- * +- */ +-template class con_msg_manager> +-class message { +-public: +- typedef lib::shared_ptr ptr; +- +- typedef con_msg_manager con_msg_man_type; +- typedef typename con_msg_man_type::ptr con_msg_man_ptr; +- typedef typename con_msg_man_type::weak_ptr con_msg_man_weak_ptr; +- +- /// Construct an empty message +- /** +- * Construct an empty message +- */ +- message(const con_msg_man_ptr manager) +- : m_manager(manager) +- , m_prepared(false) +- , m_fin(true) +- , m_terminal(false) +- , m_compressed(false) {} +- +- /// Construct a message and fill in some values +- /** +- * +- */ +- message(const con_msg_man_ptr manager, frame::opcode::value op, size_t size = 128) +- : m_manager(manager) +- , m_opcode(op) +- , m_prepared(false) +- , m_fin(true) +- , m_terminal(false) +- , m_compressed(false) +- { +- m_payload.reserve(size); +- } +- +- /// Return whether or not the message has been prepared for sending +- /** +- * The prepared flag indicates that the message has been prepared by a +- * websocket protocol processor and is ready to be written to the wire. +- * +- * @return whether or not the message has been prepared for sending +- */ +- bool get_prepared() const { +- return m_prepared; +- } +- +- /// Set or clear the flag that indicates that the message has been prepared +- /** +- * This flag should not be set by end user code without a very good reason. +- * +- * @param value The value to set the prepared flag to +- */ +- void set_prepared(bool value) { +- m_prepared = value; +- } +- +- /// Return whether or not the message is flagged as compressed +- /** +- * @return whether or not the message is/should be compressed +- */ +- bool get_compressed() const { +- return m_compressed; +- } +- +- /// Set or clear the compression flag +- /** +- * Setting the compression flag indicates that the data in this message +- * would benefit from compression. If both endpoints negotiate a compression +- * extension WebSocket++ will attempt to compress messages with this flag. +- * Setting this flag does not guarantee that the message will be compressed. +- * +- * @param value The value to set the compressed flag to +- */ +- void set_compressed(bool value) { +- m_compressed = value; +- } +- +- /// Get whether or not the message is terminal +- /** +- * Messages can be flagged as terminal, which results in the connection +- * being close after they are written rather than the implementation going +- * on to the next message in the queue. This is typically used internally +- * for close messages only. +- * +- * @return Whether or not this message is marked terminal +- */ +- bool get_terminal() const { +- return m_terminal; +- } +- +- /// Set the terminal flag +- /** +- * This flag should not be set by end user code without a very good reason. +- * +- * @see get_terminal() +- * +- * @param value The value to set the terminal flag to. +- */ +- void set_terminal(bool value) { +- m_terminal = value; +- } +- /// Read the fin bit +- /** +- * A message with the fin bit set will be sent as the last message of its +- * sequence. A message with the fin bit cleared will require subsequent +- * frames of opcode continuation until one of them has the fin bit set. +- * +- * The remote end likely will not deliver any bytes until the frame with the fin +- * bit set has been received. +- * +- * @return Whether or not the fin bit is set +- */ +- bool get_fin() const { +- return m_fin; +- } +- +- /// Set the fin bit +- /** +- * @see get_fin for a more detailed explaination of the fin bit +- * +- * @param value The value to set the fin bit to. +- */ +- void set_fin(bool value) { +- m_fin = value; +- } +- +- /// Return the message opcode +- frame::opcode::value get_opcode() const { +- return m_opcode; +- } +- +- /// Set the opcode +- void set_opcode(frame::opcode::value op) { +- m_opcode = op; +- } +- +- /// Return the prepared frame header +- /** +- * This value is typically set by a websocket protocol processor +- * and shouldn't be tampered with. +- */ +- std::string const & get_header() const { +- return m_header; +- } +- +- /// Set prepared frame header +- /** +- * Under normal circumstances this should not be called by end users +- * +- * @param header A string to set the header to. +- */ +- void set_header(std::string const & header) { +- m_header = header; +- } +- +- std::string const & get_extension_data() const { +- return m_extension_data; +- } +- +- /// Get a reference to the payload string +- /** +- * @return A const reference to the message's payload string +- */ +- std::string const & get_payload() const { +- return m_payload; +- } +- +- /// Get a non-const reference to the payload string +- /** +- * @return A reference to the message's payload string +- */ +- std::string & get_raw_payload() { +- return m_payload; +- } +- +- /// Set payload data +- /** +- * Set the message buffer's payload to the given value. +- * +- * @param payload A string to set the payload to. +- */ +- void set_payload(std::string const & payload) { +- m_payload = payload; +- } +- +- /// Set payload data +- /** +- * Set the message buffer's payload to the given value. +- * +- * @param payload A pointer to a data array to set to. +- * @param len The length of new payload in bytes. +- */ +- void set_payload(void const * payload, size_t len) { +- m_payload.reserve(len); +- char const * pl = static_cast(payload); +- m_payload.assign(pl, pl + len); +- } +- +- /// Append payload data +- /** +- * Append data to the message buffer's payload. +- * +- * @param payload A string containing the data array to append. +- */ +- void append_payload(std::string const & payload) { +- m_payload.append(payload); +- } +- +- /// Append payload data +- /** +- * Append data to the message buffer's payload. +- * +- * @param payload A pointer to a data array to append +- * @param len The length of payload in bytes +- */ +- void append_payload(void const * payload, size_t len) { +- m_payload.reserve(m_payload.size()+len); +- m_payload.append(static_cast(payload),len); +- } +- +- /// Recycle the message +- /** +- * A request to recycle this message was received. Forward that request to +- * the connection message manager for processing. Errors and exceptions +- * from the manager's recycle member function should be passed back up the +- * call chain. The caller to message::recycle will deal with them. +- * +- * Recycle must *only* be called by the message shared_ptr's destructor. +- * Once recycled successfully, ownership of the memory has been passed to +- * another system and must not be accessed again. +- * +- * @return true if the message was successfully recycled, false otherwise. +- */ +- bool recycle() { +- con_msg_man_ptr shared = m_manager.lock(); +- +- if (shared) { +- return shared->recycle(this); +- } else { +- return false; +- } +- } +-private: +- con_msg_man_weak_ptr m_manager; +- std::string m_header; +- std::string m_extension_data; +- std::string m_payload; +- frame::opcode::value m_opcode; +- bool m_prepared; +- bool m_fin; +- bool m_terminal; +- bool m_compressed; +-}; +- +-} // namespace message_buffer +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_MESSAGE_BUFFER_MESSAGE_HPP +diff --git a/src/lib/websocketpp/message_buffer/pool.hpp b/src/lib/websocketpp/message_buffer/pool.hpp +deleted file mode 100644 +index 1e5e32e..0000000 +--- a/src/lib/websocketpp/message_buffer/pool.hpp ++++ /dev/null +@@ -1,229 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +-#define WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +- +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace message_buffer { +- +-/* # message: +- * object that stores a message while it is being sent or received. Contains +- * the message payload itself, the message header, the extension data, and the +- * opcode. +- * +- * # connection_message_manager: +- * An object that manages all of the message_buffers associated with a given +- * connection. Implements the get_message_buffer(size) method that returns +- * a message buffer at least size bytes long. +- * +- * Message buffers are reference counted with shared ownership semantics. Once +- * requested from the manager the requester and it's associated downstream code +- * may keep a pointer to the message indefinitely at a cost of extra resource +- * usage. Once the reference count drops to the point where the manager is the +- * only reference the messages is recycled using whatever method is implemented +- * in the manager. +- * +- * # endpoint_message_manager: +- * An object that manages connection_message_managers. Implements the +- * get_message_manager() method. This is used once by each connection to +- * request the message manager that they are supposed to use to manage message +- * buffers for their own use. +- * +- * TYPES OF CONNECTION_MESSAGE_MANAGERS +- * - allocate a message with the exact size every time one is requested +- * - maintain a pool of pre-allocated messages and return one when needed. +- * Recycle previously used messages back into the pool +- * +- * TYPES OF ENDPOINT_MESSAGE_MANAGERS +- * - allocate a new connection manager for each connection. Message pools +- * become connection specific. This increases memory usage but improves +- * concurrency. +- * - allocate a single connection manager and share a pointer to it with all +- * connections created by this endpoint. The message pool will be shared +- * among all connections, improving memory usage and performance at the cost +- * of reduced concurrency +- */ +- +-/// Custom deleter for use in shared_ptrs to message. +-/** +- * This is used to catch messages about to be deleted and offer the manager the +- * ability to recycle them instead. Message::recycle will return true if it was +- * successfully recycled and false otherwise. In the case of exceptions or error +- * this deleter frees the memory. +- */ +-template +-void message_deleter(T* msg) { +- try { +- if (!msg->recycle()) { +- delete msg; +- } +- } catch (...) { +- // TODO: is there a better way to ensure this function doesn't throw? +- delete msg; +- } +-} +- +-/// Represents a buffer for a single WebSocket message. +-/** +- * +- * +- */ +-template +-class message { +-public: +- typedef lib::shared_ptr ptr; +- +- typedef typename con_msg_manager::weak_ptr con_msg_man_ptr; +- +- message(con_msg_man_ptr manager, size_t size = 128) +- : m_manager(manager) +- , m_payload(size) {} +- +- frame::opcode::value get_opcode() const { +- return m_opcode; +- } +- const std::string& get_header() const { +- return m_header; +- } +- const std::string& get_extension_data() const { +- return m_extension_data; +- } +- const std::string& get_payload() const { +- return m_payload; +- } +- +- /// Recycle the message +- /** +- * A request to recycle this message was received. Forward that request to +- * the connection message manager for processing. Errors and exceptions +- * from the manager's recycle member function should be passed back up the +- * call chain. The caller to message::recycle will deal with them. +- * +- * Recycle must *only* be called by the message shared_ptr's destructor. +- * Once recycled successfully, ownership of the memory has been passed to +- * another system and must not be accessed again. +- * +- * @return true if the message was successfully recycled, false otherwise. +- */ +- bool recycle() { +- typename con_msg_manager::ptr shared = m_manager.lock(); +- +- if (shared) { +- return shared->(recycle(this)); +- } else { +- return false; +- } +- } +-private: +- con_msg_man_ptr m_manager; +- +- frame::opcode::value m_opcode; +- std::string m_header; +- std::string m_extension_data; +- std::string m_payload; +-}; +- +-namespace alloc { +- +-/// A connection message manager that allocates a new message for each +-/// request. +-template +-class con_msg_manager { +-public: +- typedef lib::shared_ptr ptr; +- typedef lib::weak_ptr weak_ptr; +- +- typedef typename message::ptr message_ptr; +- +- /// Get a message buffer with specified size +- /** +- * @param size Minimum size in bytes to request for the message payload. +- * +- * @return A shared pointer to a new message with specified size. +- */ +- message_ptr get_message(size_t size) const { +- return lib::make_shared(size); +- } +- +- /// Recycle a message +- /** +- * This method shouldn't be called. If it is, return false to indicate an +- * error. The rest of the method recycle chain should notice this and free +- * the memory. +- * +- * @param msg The message to be recycled. +- * +- * @return true if the message was successfully recycled, false otherwse. +- */ +- bool recycle(message * msg) { +- return false; +- } +-}; +- +-/// An endpoint message manager that allocates a new manager for each +-/// connection. +-template +-class endpoint_msg_manager { +-public: +- typedef typename con_msg_manager::ptr con_msg_man_ptr; +- +- /// Get a pointer to a connection message manager +- /** +- * @return A pointer to the requested connection message manager. +- */ +- con_msg_man_ptr get_manager() const { +- return lib::make_shared(); +- } +-}; +- +-} // namespace alloc +- +-namespace pool { +- +-/// A connection messages manager that maintains a pool of messages that is +-/// used to fulfill get_message requests. +-class con_msg_manager { +- +-}; +- +-/// An endpoint manager that maintains a shared pool of connection managers +-/// and returns an appropriate one for the requesting connection. +-class endpoint_msg_manager { +- +-}; +- +-} // namespace pool +- +-} // namespace message_buffer +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_MESSAGE_BUFFER_ALLOC_HPP +diff --git a/src/lib/websocketpp/processors/base.hpp b/src/lib/websocketpp/processors/base.hpp +deleted file mode 100644 +index a2110e1..0000000 +--- a/src/lib/websocketpp/processors/base.hpp ++++ /dev/null +@@ -1,299 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_BASE_HPP +-#define WEBSOCKETPP_PROCESSOR_BASE_HPP +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace processor { +- +-/// Constants related to processing WebSocket connections +-namespace constants { +- +-static char const upgrade_token[] = "websocket"; +-static char const connection_token[] = "Upgrade"; +-static char const handshake_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; +- +-} // namespace constants +- +- +-/// Processor class related error codes +-namespace error_cat { +-enum value { +- BAD_REQUEST = 0, // Error was the result of improperly formatted user input +- INTERNAL_ERROR = 1, // Error was a logic error internal to WebSocket++ +- PROTOCOL_VIOLATION = 2, +- MESSAGE_TOO_BIG = 3, +- PAYLOAD_VIOLATION = 4 // Error was due to receiving invalid payload data +-}; +-} // namespace error_cat +- +-/// Error code category and codes used by all processor types +-namespace error { +-enum processor_errors { +- /// Catch-all error for processor policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// Error was the result of improperly formatted user input +- bad_request, +- +- /// Processor encountered a protocol violation in an incoming message +- protocol_violation, +- +- /// Processor encountered a message that was too large +- message_too_big, +- +- /// Processor encountered invalid payload data. +- invalid_payload, +- +- /// The processor method was called with invalid arguments +- invalid_arguments, +- +- /// Opcode was invalid for requested operation +- invalid_opcode, +- +- /// Control frame too large +- control_too_big, +- +- /// Illegal use of reserved bit +- invalid_rsv_bit, +- +- /// Fragmented control message +- fragmented_control, +- +- /// Continuation without message +- invalid_continuation, +- +- /// Clients may not send unmasked frames +- masking_required, +- +- /// Servers may not send masked frames +- masking_forbidden, +- +- /// Payload length not minimally encoded +- non_minimal_encoding, +- +- /// Not supported on 32 bit systems +- requires_64bit, +- +- /// Invalid UTF-8 encoding +- invalid_utf8, +- +- /// Operation required not implemented functionality +- not_implemented, +- +- /// Invalid HTTP method +- invalid_http_method, +- +- /// Invalid HTTP version +- invalid_http_version, +- +- /// Invalid HTTP status +- invalid_http_status, +- +- /// Missing Required Header +- missing_required_header, +- +- /// Embedded SHA-1 library error +- sha1_library, +- +- /// No support for this feature in this protocol version. +- no_protocol_support, +- +- /// Reserved close code used +- reserved_close_code, +- +- /// Invalid close code used +- invalid_close_code, +- +- /// Using a reason requires a close code +- reason_requires_code, +- +- /// Error parsing subprotocols +- subprotocol_parse_error, +- +- /// Error parsing extensions +- extension_parse_error, +- +- /// Extension related operation was ignored because extensions are disabled +- extensions_disabled, +- +- /// Short Ke3 read. Hybi00 requires a third key to be read from the 8 bytes +- /// after the handshake. Less than 8 bytes were read. +- short_key3 +-}; +- +-/// Category for processor errors +-class processor_category : public lib::error_category { +-public: +- processor_category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.processor"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case error::general: +- return "Generic processor error"; +- case error::bad_request: +- return "invalid user input"; +- case error::protocol_violation: +- return "Generic protocol violation"; +- case error::message_too_big: +- return "A message was too large"; +- case error::invalid_payload: +- return "A payload contained invalid data"; +- case error::invalid_arguments: +- return "invalid function arguments"; +- case error::invalid_opcode: +- return "invalid opcode"; +- case error::control_too_big: +- return "Control messages are limited to fewer than 125 characters"; +- case error::invalid_rsv_bit: +- return "Invalid use of reserved bits"; +- case error::fragmented_control: +- return "Control messages cannot be fragmented"; +- case error::invalid_continuation: +- return "Invalid message continuation"; +- case error::masking_required: +- return "Clients may not send unmasked frames"; +- case error::masking_forbidden: +- return "Servers may not send masked frames"; +- case error::non_minimal_encoding: +- return "Payload length was not minimally encoded"; +- case error::requires_64bit: +- return "64 bit frames are not supported on 32 bit systems"; +- case error::invalid_utf8: +- return "Invalid UTF8 encoding"; +- case error::not_implemented: +- return "Operation required not implemented functionality"; +- case error::invalid_http_method: +- return "Invalid HTTP method."; +- case error::invalid_http_version: +- return "Invalid HTTP version."; +- case error::invalid_http_status: +- return "Invalid HTTP status."; +- case error::missing_required_header: +- return "A required HTTP header is missing"; +- case error::sha1_library: +- return "SHA-1 library error"; +- case error::no_protocol_support: +- return "The WebSocket protocol version in use does not support this feature"; +- case error::reserved_close_code: +- return "Reserved close code used"; +- case error::invalid_close_code: +- return "Invalid close code used"; +- case error::reason_requires_code: +- return "Using a close reason requires a valid close code"; +- case error::subprotocol_parse_error: +- return "Error parsing subprotocol header"; +- case error::extension_parse_error: +- return "Error parsing extension header"; +- case error::extensions_disabled: +- return "Extensions are disabled"; +- case error::short_key3: +- return "Short Hybi00 Key 3 read"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the processor error category +-inline lib::error_category const & get_processor_category() { +- static processor_category instance; +- return instance; +-} +- +-/// Create an error code with the given value and the processor category +-inline lib::error_code make_error_code(error::processor_errors e) { +- return lib::error_code(static_cast(e), get_processor_category()); +-} +- +-/// Converts a processor error_code into a websocket close code +-/** +- * Looks up the appropriate WebSocket close code that should be sent after an +- * error of this sort occurred. +- * +- * If the error is not in the processor category close::status::blank is +- * returned. +- * +- * If the error isn't normally associated with reasons to close a connection +- * (such as errors intended to be used internally or delivered to client +- * applications, ex: invalid arguments) then +- * close::status::internal_endpoint_error is returned. +- */ +-inline close::status::value to_ws(lib::error_code ec) { +- if (ec.category() != get_processor_category()) { +- return close::status::blank; +- } +- +- switch (ec.value()) { +- case error::protocol_violation: +- case error::control_too_big: +- case error::invalid_opcode: +- case error::invalid_rsv_bit: +- case error::fragmented_control: +- case error::invalid_continuation: +- case error::masking_required: +- case error::masking_forbidden: +- case error::reserved_close_code: +- case error::invalid_close_code: +- return close::status::protocol_error; +- case error::invalid_payload: +- case error::invalid_utf8: +- return close::status::invalid_payload; +- case error::message_too_big: +- return close::status::message_too_big; +- default: +- return close::status::internal_endpoint_error; +- } +-} +- +-} // namespace error +-} // namespace processor +-} // namespace ws_websocketpp +- +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif //WEBSOCKETPP_PROCESSOR_BASE_HPP +diff --git a/src/lib/websocketpp/processors/hybi00.hpp b/src/lib/websocketpp/processors/hybi00.hpp +deleted file mode 100644 +index cce1000..0000000 +--- a/src/lib/websocketpp/processors/hybi00.hpp ++++ /dev/null +@@ -1,462 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_HYBI00_HPP +-#define WEBSOCKETPP_PROCESSOR_HYBI00_HPP +- +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include +- +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace processor { +- +-/// Processor for Hybi Draft version 00 +-/** +- * There are many differences between Hybi 00 and Hybi 13 +- */ +-template +-class hybi00 : public processor { +-public: +- typedef processor base; +- +- typedef typename config::request_type request_type; +- typedef typename config::response_type response_type; +- +- typedef typename config::message_type message_type; +- typedef typename message_type::ptr message_ptr; +- +- typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; +- +- explicit hybi00(bool secure, bool p_is_server, msg_manager_ptr manager) +- : processor(secure, p_is_server) +- , msg_hdr(0x00) +- , msg_ftr(0xff) +- , m_state(HEADER) +- , m_msg_manager(manager) {} +- +- int get_version() const { +- return 0; +- } +- +- lib::error_code validate_handshake(request_type const & r) const { +- if (r.get_method() != "GET") { +- return make_error_code(error::invalid_http_method); +- } +- +- if (r.get_version() != "HTTP/1.1") { +- return make_error_code(error::invalid_http_version); +- } +- +- // required headers +- // Host is required by HTTP/1.1 +- // Connection is required by is_websocket_handshake +- // Upgrade is required by is_websocket_handshake +- if (r.get_header("Sec-WebSocket-Key1").empty() || +- r.get_header("Sec-WebSocket-Key2").empty() || +- r.get_header("Sec-WebSocket-Key3").empty()) +- { +- return make_error_code(error::missing_required_header); +- } +- +- return lib::error_code(); +- } +- +- lib::error_code process_handshake(request_type const & req, +- std::string const & subprotocol, response_type & res) const +- { +- char key_final[16]; +- +- // copy key1 into final key +- decode_client_key(req.get_header("Sec-WebSocket-Key1"), &key_final[0]); +- +- // copy key2 into final key +- decode_client_key(req.get_header("Sec-WebSocket-Key2"), &key_final[4]); +- +- // copy key3 into final key +- // key3 should be exactly 8 bytes. If it is more it will be truncated +- // if it is less the final key will almost certainly be wrong. +- // TODO: decide if it is best to silently fail here or produce some sort +- // of warning or exception. +- std::string const & key3 = req.get_header("Sec-WebSocket-Key3"); +- std::copy(key3.c_str(), +- key3.c_str()+(std::min)(static_cast(8), key3.size()), +- &key_final[8]); +- +- res.append_header( +- "Sec-WebSocket-Key3", +- md5::md5_hash_string(std::string(key_final,16)) +- ); +- +- res.append_header("Upgrade","WebSocket"); +- res.append_header("Connection","Upgrade"); +- +- // Echo back client's origin unless our local application set a +- // more restrictive one. +- if (res.get_header("Sec-WebSocket-Origin").empty()) { +- res.append_header("Sec-WebSocket-Origin",req.get_header("Origin")); +- } +- +- // Echo back the client's request host unless our local application +- // set a different one. +- if (res.get_header("Sec-WebSocket-Location").empty()) { +- uri_ptr uri = get_uri(req); +- res.append_header("Sec-WebSocket-Location",uri->str()); +- } +- +- if (!subprotocol.empty()) { +- res.replace_header("Sec-WebSocket-Protocol",subprotocol); +- } +- +- return lib::error_code(); +- } +- +- /// Fill in a set of request headers for a client connection request +- /** +- * The Hybi 00 processor only implements incoming connections so this will +- * always return an error. +- * +- * @param [out] req Set of headers to fill in +- * @param [in] uri The uri being connected to +- * @param [in] subprotocols The list of subprotocols to request +- */ +- lib::error_code client_handshake_request(request_type &, uri_ptr, +- std::vector const &) const +- { +- return error::make_error_code(error::no_protocol_support); +- } +- +- /// Validate the server's response to an outgoing handshake request +- /** +- * The Hybi 00 processor only implements incoming connections so this will +- * always return an error. +- * +- * @param req The original request sent +- * @param res The reponse to generate +- * @return An error code, 0 on success, non-zero for other errors +- */ +- lib::error_code validate_server_handshake_response(request_type const &, +- response_type &) const +- { +- return error::make_error_code(error::no_protocol_support); +- } +- +- std::string get_raw(response_type const & res) const { +- response_type temp = res; +- temp.remove_header("Sec-WebSocket-Key3"); +- return temp.raw() + res.get_header("Sec-WebSocket-Key3"); +- } +- +- std::string const & get_origin(request_type const & r) const { +- return r.get_header("Origin"); +- } +- +- /// Extracts requested subprotocols from a handshake request +- /** +- * hybi00 does support subprotocols +- * https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00#section-1.9 +- * +- * @param [in] req The request to extract from +- * @param [out] subprotocol_list A reference to a vector of strings to store +- * the results in. +- */ +- lib::error_code extract_subprotocols(request_type const & req, +- std::vector & subprotocol_list) +- { +- if (!req.get_header("Sec-WebSocket-Protocol").empty()) { +- http::parameter_list p; +- +- if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) { +- http::parameter_list::const_iterator it; +- +- for (it = p.begin(); it != p.end(); ++it) { +- subprotocol_list.push_back(it->first); +- } +- } else { +- return error::make_error_code(error::subprotocol_parse_error); +- } +- } +- return lib::error_code(); +- } +- +- uri_ptr get_uri(request_type const & request) const { +- std::string h = request.get_header("Host"); +- +- size_t last_colon = h.rfind(":"); +- size_t last_sbrace = h.rfind("]"); +- +- // no : = hostname with no port +- // last : before ] = ipv6 literal with no port +- // : with no ] = hostname with port +- // : after ] = ipv6 literal with port +- +- if (last_colon == std::string::npos || +- (last_sbrace != std::string::npos && last_sbrace > last_colon)) +- { +- return lib::make_shared(base::m_secure, h, request.get_uri()); +- } else { +- return lib::make_shared(base::m_secure, +- h.substr(0,last_colon), +- h.substr(last_colon+1), +- request.get_uri()); +- } +- +- // TODO: check if get_uri is a full uri +- } +- +- /// Get hybi00 handshake key3 +- /** +- * @todo This doesn't appear to be used anymore. It might be able to be +- * removed +- */ +- std::string get_key3() const { +- return ""; +- } +- +- /// Process new websocket connection bytes +- size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { +- // if in state header we are expecting a 0x00 byte, if we don't get one +- // it is a fatal error +- size_t p = 0; // bytes processed +- size_t l = 0; +- +- ec = lib::error_code(); +- +- while (p < len) { +- if (m_state == HEADER) { +- if (buf[p] == msg_hdr) { +- p++; +- m_msg_ptr = m_msg_manager->get_message(frame::opcode::text,1); +- +- if (!m_msg_ptr) { +- ec = make_error_code(ws_websocketpp::error::no_incoming_buffers); +- m_state = FATAL_ERROR; +- } else { +- m_state = PAYLOAD; +- } +- } else { +- ec = make_error_code(error::protocol_violation); +- m_state = FATAL_ERROR; +- } +- } else if (m_state == PAYLOAD) { +- uint8_t *it = std::find(buf+p,buf+len,msg_ftr); +- +- // 0 1 2 3 4 5 +- // 0x00 0x23 0x23 0x23 0xff 0xXX +- +- // Copy payload bytes into message +- l = static_cast(it-(buf+p)); +- m_msg_ptr->append_payload(buf+p,l); +- p += l; +- +- if (it != buf+len) { +- // message is done, copy it and the trailing +- p++; +- // TODO: validation +- m_state = READY; +- } +- } else { +- // TODO +- break; +- } +- } +- // If we get one, we create a new message and move to application state +- +- // if in state application we are copying bytes into the output message +- // and validating them for UTF8 until we hit a 0xff byte. Once we hit +- // 0x00, the message is complete and is dispatched. Then we go back to +- // header state. +- +- //ec = make_error_code(error::not_implemented); +- return p; +- } +- +- bool ready() const { +- return (m_state == READY); +- } +- +- bool get_error() const { +- return false; +- } +- +- message_ptr get_message() { +- message_ptr ret = m_msg_ptr; +- m_msg_ptr = message_ptr(); +- m_state = HEADER; +- return ret; +- } +- +- /// Prepare a message for writing +- /** +- * Performs validation, masking, compression, etc. will return an error if +- * there was an error, otherwise msg will be ready to be written +- */ +- virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) +- { +- if (!in || !out) { +- return make_error_code(error::invalid_arguments); +- } +- +- // TODO: check if the message is prepared already +- +- // validate opcode +- if (in->get_opcode() != frame::opcode::text) { +- return make_error_code(error::invalid_opcode); +- } +- +- std::string& i = in->get_raw_payload(); +- //std::string& o = out->get_raw_payload(); +- +- // validate payload utf8 +- if (!utf8_validator::validate(i)) { +- return make_error_code(error::invalid_payload); +- } +- +- // generate header +- out->set_header(std::string(reinterpret_cast(&msg_hdr),1)); +- +- // process payload +- out->set_payload(i); +- out->append_payload(std::string(reinterpret_cast(&msg_ftr),1)); +- +- // hybi00 doesn't support compression +- // hybi00 doesn't have masking +- +- out->set_prepared(true); +- +- return lib::error_code(); +- } +- +- /// Prepare a ping frame +- /** +- * Hybi 00 doesn't support pings so this will always return an error +- * +- * @param in The string to use for the ping payload +- * @param out The message buffer to prepare the ping in. +- * @return Status code, zero on success, non-zero on failure +- */ +- lib::error_code prepare_ping(std::string const &, message_ptr) const +- { +- return lib::error_code(error::no_protocol_support); +- } +- +- /// Prepare a pong frame +- /** +- * Hybi 00 doesn't support pongs so this will always return an error +- * +- * @param in The string to use for the pong payload +- * @param out The message buffer to prepare the pong in. +- * @return Status code, zero on success, non-zero on failure +- */ +- lib::error_code prepare_pong(std::string const &, message_ptr) const +- { +- return lib::error_code(error::no_protocol_support); +- } +- +- /// Prepare a close frame +- /** +- * Hybi 00 doesn't support the close code or reason so these parameters are +- * ignored. +- * +- * @param code The close code to send +- * @param reason The reason string to send +- * @param out The message buffer to prepare the fame in +- * @return Status code, zero on success, non-zero on failure +- */ +- lib::error_code prepare_close(close::status::value, std::string const &, +- message_ptr out) const +- { +- if (!out) { +- return lib::error_code(error::invalid_arguments); +- } +- +- std::string val; +- val.append(1,'\xff'); +- val.append(1,'\x00'); +- out->set_payload(val); +- out->set_prepared(true); +- +- return lib::error_code(); +- } +-private: +- void decode_client_key(std::string const & key, char * result) const { +- unsigned int spaces = 0; +- std::string digits; +- uint32_t num; +- +- // key2 +- for (size_t i = 0; i < key.size(); i++) { +- if (key[i] == ' ') { +- spaces++; +- } else if (key[i] >= '0' && key[i] <= '9') { +- digits += key[i]; +- } +- } +- +- num = static_cast(strtoul(digits.c_str(), NULL, 10)); +- if (spaces > 0 && num > 0) { +- num = htonl(num/spaces); +- std::copy(reinterpret_cast(&num), +- reinterpret_cast(&num)+4, +- result); +- } else { +- std::fill(result,result+4,0); +- } +- } +- +- enum state { +- HEADER = 0, +- PAYLOAD = 1, +- READY = 2, +- FATAL_ERROR = 3 +- }; +- +- uint8_t const msg_hdr; +- uint8_t const msg_ftr; +- +- state m_state; +- +- msg_manager_ptr m_msg_manager; +- message_ptr m_msg_ptr; +- utf8_validator::validator m_validator; +-}; +- +-} // namespace processor +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_PROCESSOR_HYBI00_HPP +diff --git a/src/lib/websocketpp/processors/hybi07.hpp b/src/lib/websocketpp/processors/hybi07.hpp +deleted file mode 100644 +index e9efb13..0000000 +--- a/src/lib/websocketpp/processors/hybi07.hpp ++++ /dev/null +@@ -1,78 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_HYBI07_HPP +-#define WEBSOCKETPP_PROCESSOR_HYBI07_HPP +- +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace processor { +- +-/// Processor for Hybi Draft version 07 +-/** +- * The primary difference between 07 and 08 is a version number. +- */ +-template +-class hybi07 : public hybi08 { +-public: +- typedef typename config::request_type request_type; +- +- typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; +- typedef typename config::rng_type rng_type; +- +- explicit hybi07(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng) +- : hybi08(secure, p_is_server, manager, rng) {} +- +- /// Fill in a set of request headers for a client connection request +- /** +- * The Hybi 07 processor only implements incoming connections so this will +- * always return an error. +- * +- * @param [out] req Set of headers to fill in +- * @param [in] uri The uri being connected to +- * @param [in] subprotocols The list of subprotocols to request +- */ +- lib::error_code client_handshake_request(request_type &, uri_ptr, +- std::vector const &) const +- { +- return error::make_error_code(error::no_protocol_support); +- } +- +- int get_version() const { +- return 7; +- } +-private: +-}; +- +-} // namespace processor +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_PROCESSOR_HYBI07_HPP +diff --git a/src/lib/websocketpp/processors/hybi08.hpp b/src/lib/websocketpp/processors/hybi08.hpp +deleted file mode 100644 +index 491e0ee..0000000 +--- a/src/lib/websocketpp/processors/hybi08.hpp ++++ /dev/null +@@ -1,83 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_HYBI08_HPP +-#define WEBSOCKETPP_PROCESSOR_HYBI08_HPP +- +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace processor { +- +-/// Processor for Hybi Draft version 08 +-/** +- * The primary difference between 08 and 13 is a different origin header name +- */ +-template +-class hybi08 : public hybi13 { +-public: +- typedef hybi08 type; +- typedef typename config::request_type request_type; +- +- typedef typename config::con_msg_manager_type::ptr msg_manager_ptr; +- typedef typename config::rng_type rng_type; +- +- explicit hybi08(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng) +- : hybi13(secure, p_is_server, manager, rng) {} +- +- /// Fill in a set of request headers for a client connection request +- /** +- * The Hybi 08 processor only implements incoming connections so this will +- * always return an error. +- * +- * @param [out] req Set of headers to fill in +- * @param [in] uri The uri being connected to +- * @param [in] subprotocols The list of subprotocols to request +- */ +- lib::error_code client_handshake_request(request_type &, uri_ptr, +- std::vector const &) const +- { +- return error::make_error_code(error::no_protocol_support); +- } +- +- int get_version() const { +- return 8; +- } +- +- std::string const & get_origin(request_type const & r) const { +- return r.get_header("Sec-WebSocket-Origin"); +- } +-private: +-}; +- +-} // namespace processor +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_PROCESSOR_HYBI08_HPP +diff --git a/src/lib/websocketpp/processors/hybi13.hpp b/src/lib/websocketpp/processors/hybi13.hpp +deleted file mode 100644 +index 4fafce9..0000000 +--- a/src/lib/websocketpp/processors/hybi13.hpp ++++ /dev/null +@@ -1,1078 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_HYBI13_HPP +-#define WEBSOCKETPP_PROCESSOR_HYBI13_HPP +- +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace processor { +- +-/// Processor for Hybi version 13 (RFC6455) +-template +-class hybi13 : public processor { +-public: +- typedef processor base; +- +- typedef typename config::request_type request_type; +- typedef typename config::response_type response_type; +- +- typedef typename config::message_type message_type; +- typedef typename message_type::ptr message_ptr; +- +- typedef typename config::con_msg_manager_type msg_manager_type; +- typedef typename msg_manager_type::ptr msg_manager_ptr; +- typedef typename config::rng_type rng_type; +- +- typedef typename config::permessage_deflate_type permessage_deflate_type; +- +- typedef std::pair err_str_pair; +- +- explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng) +- : processor(secure, p_is_server) +- , m_msg_manager(manager) +- , m_rng(rng) +- { +- reset_headers(); +- } +- +- int get_version() const { +- return 13; +- } +- +- bool has_permessage_deflate() const { +- return m_permessage_deflate.is_implemented(); +- } +- +- err_str_pair negotiate_extensions(request_type const & request) { +- return negotiate_extensions_helper(request); +- } +- +- err_str_pair negotiate_extensions(response_type const & response) { +- return negotiate_extensions_helper(response); +- } +- +- /// Extension negotiation helper function +- /** +- * This exists mostly because the code for requests and responses is +- * identical and I can't have virtual template methods. +- */ +- template +- err_str_pair negotiate_extensions_helper(header_type const & header) { +- err_str_pair ret; +- +- // Respect blanket disabling of all extensions and don't even parse +- // the extension header +- if (!config::enable_extensions) { +- ret.first = make_error_code(error::extensions_disabled); +- return ret; +- } +- +- http::parameter_list p; +- +- bool error = header.get_header_as_plist("Sec-WebSocket-Extensions",p); +- +- if (error) { +- ret.first = make_error_code(error::extension_parse_error); +- return ret; +- } +- +- // If there are no extensions parsed then we are done! +- if (p.size() == 0) { +- return ret; +- } +- +- 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) { +- // not a permessage-deflate extension request, ignore +- if (it->first != "permessage-deflate") { +- 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; +- } +- +- lib::error_code validate_handshake(request_type const & r) const { +- if (r.get_method() != "GET") { +- return make_error_code(error::invalid_http_method); +- } +- +- if (r.get_version() != "HTTP/1.1") { +- return make_error_code(error::invalid_http_version); +- } +- +- // required headers +- // Host is required by HTTP/1.1 +- // Connection is required by is_websocket_handshake +- // Upgrade is required by is_websocket_handshake +- if (r.get_header("Sec-WebSocket-Key").empty()) { +- return make_error_code(error::missing_required_header); +- } +- +- return lib::error_code(); +- } +- +- /* TODO: the 'subprotocol' parameter may need to be expanded into a more +- * generic struct if other user input parameters to the processed handshake +- * are found. +- */ +- lib::error_code process_handshake(request_type const & request, +- std::string const & subprotocol, response_type & response) const +- { +- std::string server_key = request.get_header("Sec-WebSocket-Key"); +- +- lib::error_code ec = process_handshake_key(server_key); +- +- if (ec) { +- return ec; +- } +- +- response.replace_header("Sec-WebSocket-Accept",server_key); +- response.append_header("Upgrade",constants::upgrade_token); +- response.append_header("Connection",constants::connection_token); +- +- if (!subprotocol.empty()) { +- response.replace_header("Sec-WebSocket-Protocol",subprotocol); +- } +- +- return lib::error_code(); +- } +- +- /// Fill in a set of request headers for a client connection request +- /** +- * @param [out] req Set of headers to fill in +- * @param [in] uri The uri being connected to +- * @param [in] subprotocols The list of subprotocols to request +- */ +- lib::error_code client_handshake_request(request_type & req, uri_ptr +- uri, std::vector const & subprotocols) const +- { +- req.set_method("GET"); +- req.set_uri(uri->get_resource()); +- req.set_version("HTTP/1.1"); +- +- req.append_header("Upgrade","websocket"); +- req.append_header("Connection","Upgrade"); +- req.replace_header("Sec-WebSocket-Version","13"); +- req.replace_header("Host",uri->get_host_port()); +- +- if (!subprotocols.empty()) { +- std::ostringstream result; +- std::vector::const_iterator it = subprotocols.begin(); +- result << *it++; +- while (it != subprotocols.end()) { +- result << ", " << *it++; +- } +- +- req.replace_header("Sec-WebSocket-Protocol",result.str()); +- } +- +- // Generate handshake key +- frame::uint32_converter conv; +- unsigned char raw_key[16]; +- +- for (int i = 0; i < 4; i++) { +- conv.i = m_rng(); +- std::copy(conv.c,conv.c+4,&raw_key[i*4]); +- } +- +- req.replace_header("Sec-WebSocket-Key",base64_encode(raw_key, 16)); +- +- if (m_permessage_deflate.is_implemented()) { +- std::string offer = m_permessage_deflate.generate_offer(); +- if (!offer.empty()) { +- req.replace_header("Sec-WebSocket-Extensions",offer); +- } +- } +- +- return lib::error_code(); +- } +- +- /// Validate the server's response to an outgoing handshake request +- /** +- * @param req The original request sent +- * @param res The reponse to generate +- * @return An error code, 0 on success, non-zero for other errors +- */ +- lib::error_code validate_server_handshake_response(request_type const & req, +- response_type& res) const +- { +- // A valid response has an HTTP 101 switching protocols code +- if (res.get_status_code() != http::status_code::switching_protocols) { +- return error::make_error_code(error::invalid_http_status); +- } +- +- // And the upgrade token in an upgrade header +- std::string const & upgrade_header = res.get_header("Upgrade"); +- if (utility::ci_find_substr(upgrade_header, constants::upgrade_token, +- sizeof(constants::upgrade_token)-1) == upgrade_header.end()) +- { +- return error::make_error_code(error::missing_required_header); +- } +- +- // And the websocket token in the connection header +- std::string const & con_header = res.get_header("Connection"); +- if (utility::ci_find_substr(con_header, constants::connection_token, +- sizeof(constants::connection_token)-1) == con_header.end()) +- { +- return error::make_error_code(error::missing_required_header); +- } +- +- // And has a valid Sec-WebSocket-Accept value +- std::string key = req.get_header("Sec-WebSocket-Key"); +- lib::error_code ec = process_handshake_key(key); +- +- if (ec || key != res.get_header("Sec-WebSocket-Accept")) { +- return error::make_error_code(error::missing_required_header); +- } +- +- // check extensions +- +- return lib::error_code(); +- } +- +- std::string get_raw(response_type const & res) const { +- return res.raw(); +- } +- +- std::string const & get_origin(request_type const & r) const { +- return r.get_header("Origin"); +- } +- +- lib::error_code extract_subprotocols(request_type const & req, +- std::vector & subprotocol_list) +- { +- if (!req.get_header("Sec-WebSocket-Protocol").empty()) { +- http::parameter_list p; +- +- if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) { +- http::parameter_list::const_iterator it; +- +- for (it = p.begin(); it != p.end(); ++it) { +- subprotocol_list.push_back(it->first); +- } +- } else { +- return error::make_error_code(error::subprotocol_parse_error); +- } +- } +- return lib::error_code(); +- } +- +- uri_ptr get_uri(request_type const & request) const { +- return get_uri_from_host(request,(base::m_secure ? "wss" : "ws")); +- } +- +- /// Process new websocket connection bytes +- /** +- * +- * Hybi 13 data streams represent a series of variable length frames. Each +- * frame is made up of a series of fixed length fields. The lengths of later +- * fields are contained in earlier fields. The first field length is fixed +- * by the spec. +- * +- * This processor represents a state machine that keeps track of what field +- * is presently being read and how many more bytes are needed to complete it +- * +- * +- * +- * +- * Read two header bytes +- * Extract full frame length. +- * Read extra header bytes +- * Validate frame header (including extension validate) +- * Read extension data into extension message state object +- * Read payload data into payload +- * +- * @param buf Input buffer +- * +- * @param len Length of input buffer +- * +- * @return Number of bytes processed or zero on error +- */ +- size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) { +- size_t p = 0; +- +- ec = lib::error_code(); +- +- //std::cout << "consume: " << utility::to_hex(buf,len) << std::endl; +- +- // Loop while we don't have a message ready and we still have bytes +- // left to process. +- while (m_state != READY && m_state != FATAL_ERROR && +- (p < len || m_bytes_needed == 0)) +- { +- if (m_state == HEADER_BASIC) { +- p += this->copy_basic_header_bytes(buf+p,len-p); +- +- if (m_bytes_needed > 0) { +- continue; +- } +- +- ec = this->validate_incoming_basic_header( +- m_basic_header, base::m_server, !m_data_msg.msg_ptr +- ); +- if (ec) {break;} +- +- // extract full header size and adjust consume state accordingly +- m_state = HEADER_EXTENDED; +- m_cursor = 0; +- m_bytes_needed = frame::get_header_len(m_basic_header) - +- frame::BASIC_HEADER_LENGTH; +- } else if (m_state == HEADER_EXTENDED) { +- p += this->copy_extended_header_bytes(buf+p,len-p); +- +- if (m_bytes_needed > 0) { +- continue; +- } +- +- ec = validate_incoming_extended_header(m_basic_header,m_extended_header); +- if (ec){break;} +- +- m_state = APPLICATION; +- m_bytes_needed = static_cast(get_payload_size(m_basic_header,m_extended_header)); +- +- // check if this frame is the start of a new message and set up +- // the appropriate message metadata. +- frame::opcode::value op = frame::get_opcode(m_basic_header); +- +- // TODO: get_message failure conditions +- +- if (frame::opcode::is_control(op)) { +- m_control_msg = msg_metadata( +- m_msg_manager->get_message(op,m_bytes_needed), +- frame::get_masking_key(m_basic_header,m_extended_header) +- ); +- +- m_current_msg = &m_control_msg; +- } else { +- if (!m_data_msg.msg_ptr) { +- if (m_bytes_needed > base::m_max_message_size) { +- ec = make_error_code(error::message_too_big); +- break; +- } +- +- m_data_msg = msg_metadata( +- m_msg_manager->get_message(op,m_bytes_needed), +- frame::get_masking_key(m_basic_header,m_extended_header) +- ); +- +- if (m_permessage_deflate.is_enabled()) { +- m_data_msg.msg_ptr->set_compressed(frame::get_rsv1(m_basic_header)); +- } +- } else { +- // Fetch the underlying payload buffer from the data message we +- // are writing into. +- std::string & out = m_data_msg.msg_ptr->get_raw_payload(); +- +- if (out.size() + m_bytes_needed > base::m_max_message_size) { +- ec = make_error_code(error::message_too_big); +- break; +- } +- +- // Each frame starts a new masking key. All other state +- // remains between frames. +- m_data_msg.prepared_key = prepare_masking_key( +- frame::get_masking_key( +- m_basic_header, +- m_extended_header +- ) +- ); +- +- out.reserve(out.size() + m_bytes_needed); +- } +- m_current_msg = &m_data_msg; +- } +- } else if (m_state == EXTENSION) { +- m_state = APPLICATION; +- } else if (m_state == APPLICATION) { +- size_t bytes_to_process = (std::min)(m_bytes_needed,len-p); +- +- if (bytes_to_process > 0) { +- p += this->process_payload_bytes(buf+p,bytes_to_process,ec); +- +- if (ec) {break;} +- } +- +- if (m_bytes_needed > 0) { +- continue; +- } +- +- // If this was the last frame in the message set the ready flag. +- // Otherwise, reset processor state to read additional frames. +- if (frame::get_fin(m_basic_header)) { +- ec = finalize_message(); +- if (ec) { +- break; +- } +- } else { +- this->reset_headers(); +- } +- } else { +- // shouldn't be here +- ec = make_error_code(error::general); +- return 0; +- } +- } +- +- return p; +- } +- +- /// Perform any finalization actions on an incoming message +- /** +- * Called after the full message is received. Provides the opportunity for +- * extensions to complete any data post processing as well as final UTF8 +- * validation checks for text messages. +- * +- * @return A code indicating errors, if any +- */ +- lib::error_code finalize_message() { +- std::string & out = m_current_msg->msg_ptr->get_raw_payload(); +- +- // if the frame is compressed, append the compression +- // trailer and flush the compression buffer. +- if (m_permessage_deflate.is_enabled() +- && m_current_msg->msg_ptr->get_compressed()) +- { +- uint8_t trailer[4] = {0x00, 0x00, 0xff, 0xff}; +- +- // Decompress current buffer into the message buffer +- lib::error_code ec; +- ec = m_permessage_deflate.decompress(trailer,4,out); +- if (ec) { +- return ec; +- } +- } +- +- // ensure that text messages end on a valid UTF8 code point +- if (frame::get_opcode(m_basic_header) == frame::opcode::TEXT) { +- if (!m_current_msg->validator.complete()) { +- return make_error_code(error::invalid_utf8); +- } +- } +- +- m_state = READY; +- +- return lib::error_code(); +- } +- +- void reset_headers() { +- m_state = HEADER_BASIC; +- m_bytes_needed = frame::BASIC_HEADER_LENGTH; +- +- m_basic_header.b0 = 0x00; +- m_basic_header.b1 = 0x00; +- +- std::fill_n( +- m_extended_header.bytes, +- frame::MAX_EXTENDED_HEADER_LENGTH, +- 0x00 +- ); +- } +- +- /// Test whether or not the processor has a message ready +- bool ready() const { +- return (m_state == READY); +- } +- +- message_ptr get_message() { +- if (!ready()) { +- return message_ptr(); +- } +- message_ptr ret = m_current_msg->msg_ptr; +- m_current_msg->msg_ptr.reset(); +- +- if (frame::opcode::is_control(ret->get_opcode())) { +- m_control_msg.msg_ptr.reset(); +- } else { +- m_data_msg.msg_ptr.reset(); +- } +- +- this->reset_headers(); +- +- return ret; +- } +- +- /// Test whether or not the processor is in a fatal error state. +- bool get_error() const { +- return m_state == FATAL_ERROR; +- } +- +- size_t get_bytes_needed() const { +- return m_bytes_needed; +- } +- +- /// Prepare a user data message for writing +- /** +- * Performs validation, masking, compression, etc. will return an error if +- * there was an error, otherwise msg will be ready to be written +- * +- * TODO: tests +- * +- * @param in An unprepared message to prepare +- * @param out A message to be overwritten with the prepared message +- * @return error code +- */ +- virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) +- { +- if (!in || !out) { +- return make_error_code(error::invalid_arguments); +- } +- +- frame::opcode::value op = in->get_opcode(); +- +- // validate opcode: only regular data frames +- if (frame::opcode::is_control(op)) { +- return make_error_code(error::invalid_opcode); +- } +- +- std::string& i = in->get_raw_payload(); +- std::string& o = out->get_raw_payload(); +- +- // validate payload utf8 +- if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) { +- return make_error_code(error::invalid_payload); +- } +- +- frame::masking_key_type key; +- bool masked = !base::m_server; +- bool compressed = m_permessage_deflate.is_enabled() +- && in->get_compressed(); +- bool fin = in->get_fin(); +- +- if (masked) { +- // Generate masking key. +- key.i = m_rng(); +- } else { +- key.i = 0; +- } +- +- // prepare payload +- if (compressed) { +- // compress and store in o after header. +- m_permessage_deflate.compress(i,o); +- +- if (o.size() < 4) { +- return make_error_code(error::general); +- } +- +- // Strip trailing 4 0x00 0x00 0xff 0xff bytes before writing to the +- // wire +- o.resize(o.size()-4); +- +- // mask in place if necessary +- if (masked) { +- this->masked_copy(o,o,key); +- } +- } else { +- // no compression, just copy data into the output buffer +- o.resize(i.size()); +- +- // if we are masked, have the masking function write to the output +- // buffer directly to avoid another copy. If not masked, copy +- // directly without masking. +- if (masked) { +- this->masked_copy(i,o,key); +- } else { +- std::copy(i.begin(),i.end(),o.begin()); +- } +- } +- +- // generate header +- frame::basic_header h(op,o.size(),fin,masked,compressed); +- +- if (masked) { +- frame::extended_header e(o.size(),key.i); +- out->set_header(frame::prepare_header(h,e)); +- } else { +- frame::extended_header e(o.size()); +- out->set_header(frame::prepare_header(h,e)); +- } +- +- out->set_prepared(true); +- out->set_opcode(op); +- +- return lib::error_code(); +- } +- +- /// Get URI +- lib::error_code prepare_ping(std::string const & in, message_ptr out) const { +- return this->prepare_control(frame::opcode::PING,in,out); +- } +- +- lib::error_code prepare_pong(std::string const & in, message_ptr out) const { +- return this->prepare_control(frame::opcode::PONG,in,out); +- } +- +- virtual lib::error_code prepare_close(close::status::value code, +- std::string const & reason, message_ptr out) const +- { +- if (close::status::reserved(code)) { +- return make_error_code(error::reserved_close_code); +- } +- +- if (close::status::invalid(code) && code != close::status::no_status) { +- return make_error_code(error::invalid_close_code); +- } +- +- if (code == close::status::no_status && reason.size() > 0) { +- return make_error_code(error::reason_requires_code); +- } +- +- if (reason.size() > frame:: limits::payload_size_basic-2) { +- return make_error_code(error::control_too_big); +- } +- +- std::string payload; +- +- if (code != close::status::no_status) { +- close::code_converter val; +- val.i = htons(code); +- +- payload.resize(reason.size()+2); +- +- payload[0] = val.c[0]; +- payload[1] = val.c[1]; +- +- std::copy(reason.begin(),reason.end(),payload.begin()+2); +- } +- +- return this->prepare_control(frame::opcode::CLOSE,payload,out); +- } +-protected: +- /// Convert a client handshake key into a server response key in place +- lib::error_code process_handshake_key(std::string & key) const { +- key.append(constants::handshake_guid); +- +- unsigned char message_digest[20]; +- sha1::calc(key.c_str(),key.length(),message_digest); +- key = base64_encode(message_digest,20); +- +- return lib::error_code(); +- } +- +- /// Reads bytes from buf into m_basic_header +- size_t copy_basic_header_bytes(uint8_t const * buf, size_t len) { +- if (len == 0 || m_bytes_needed == 0) { +- return 0; +- } +- +- if (len > 1) { +- // have at least two bytes +- if (m_bytes_needed == 2) { +- m_basic_header.b0 = buf[0]; +- m_basic_header.b1 = buf[1]; +- m_bytes_needed -= 2; +- return 2; +- } else { +- m_basic_header.b1 = buf[0]; +- m_bytes_needed--; +- return 1; +- } +- } else { +- // have exactly one byte +- if (m_bytes_needed == 2) { +- m_basic_header.b0 = buf[0]; +- m_bytes_needed--; +- return 1; +- } else { +- m_basic_header.b1 = buf[0]; +- m_bytes_needed--; +- return 1; +- } +- } +- } +- +- /// Reads bytes from buf into m_extended_header +- size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) { +- size_t bytes_to_read = (std::min)(m_bytes_needed,len); +- +- std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor); +- m_cursor += bytes_to_read; +- m_bytes_needed -= bytes_to_read; +- +- return bytes_to_read; +- } +- +- /// Reads bytes from buf into message payload +- /** +- * This function performs unmasking and uncompression, validates the +- * decoded bytes, and writes them to the appropriate message buffer. +- * +- * This member function will use the input buffer as stratch space for its +- * work. The raw input bytes will not be preserved. This applies only to the +- * bytes actually needed. At most min(m_bytes_needed,len) will be processed. +- * +- * @param buf Input/working buffer +- * @param len Length of buf +- * @return Number of bytes processed or zero in case of an error +- */ +- size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec) +- { +- // unmask if masked +- if (frame::get_masked(m_basic_header)) { +- m_current_msg->prepared_key = frame::byte_mask_circ( +- buf, len, m_current_msg->prepared_key); +- // TODO: SIMD masking +- } +- +- std::string & out = m_current_msg->msg_ptr->get_raw_payload(); +- size_t offset = out.size(); +- +- // decompress message if needed. +- if (m_permessage_deflate.is_enabled() +- && m_current_msg->msg_ptr->get_compressed()) +- { +- // Decompress current buffer into the message buffer +- ec = m_permessage_deflate.decompress(buf,len,out); +- if (ec) { +- return 0; +- } +- } else { +- // No compression, straight copy +- out.append(reinterpret_cast(buf),len); +- } +- +- // validate unmasked, decompressed values +- if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) { +- if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) { +- ec = make_error_code(error::invalid_utf8); +- return 0; +- } +- } +- +- m_bytes_needed -= len; +- +- return len; +- } +- +- /// Validate an incoming basic header +- /** +- * Validates an incoming hybi13 basic header. +- * +- * @param h The basic header to validate +- * @param is_server Whether or not the endpoint that received this frame +- * is a server. +- * @param new_msg Whether or not this is the first frame of the message +- * @return 0 on success or a non-zero error code on failure +- */ +- lib::error_code validate_incoming_basic_header(frame::basic_header const & h, +- bool is_server, bool new_msg) const +- { +- frame::opcode::value op = frame::get_opcode(h); +- +- // Check control frame size limit +- if (frame::opcode::is_control(op) && +- frame::get_basic_size(h) > frame::limits::payload_size_basic) +- { +- return make_error_code(error::control_too_big); +- } +- +- // Check that RSV bits are clear +- // The only RSV bits allowed are rsv1 if the permessage_compress +- // extension is enabled for this connection and the message is not +- // a control message. +- // +- // TODO: unit tests for this +- if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled() +- || frame::opcode::is_control(op))) +- { +- return make_error_code(error::invalid_rsv_bit); +- } +- +- if (frame::get_rsv2(h) || frame::get_rsv3(h)) { +- return make_error_code(error::invalid_rsv_bit); +- } +- +- // Check for reserved opcodes +- if (frame::opcode::reserved(op)) { +- return make_error_code(error::invalid_opcode); +- } +- +- // Check for invalid opcodes +- // TODO: unit tests for this? +- if (frame::opcode::invalid(op)) { +- return make_error_code(error::invalid_opcode); +- } +- +- // Check for fragmented control message +- if (frame::opcode::is_control(op) && !frame::get_fin(h)) { +- return make_error_code(error::fragmented_control); +- } +- +- // Check for continuation without an active message +- if (new_msg && op == frame::opcode::CONTINUATION) { +- return make_error_code(error::invalid_continuation); +- } +- +- // Check for new data frame when expecting continuation +- if (!new_msg && !frame::opcode::is_control(op) && +- op != frame::opcode::CONTINUATION) +- { +- return make_error_code(error::invalid_continuation); +- } +- +- // Servers should reject any unmasked frames from clients. +- // Clients should reject any masked frames from servers. +- if (is_server && !frame::get_masked(h)) { +- return make_error_code(error::masking_required); +- } else if (!is_server && frame::get_masked(h)) { +- return make_error_code(error::masking_forbidden); +- } +- +- return lib::error_code(); +- } +- +- /// Validate an incoming extended header +- /** +- * Validates an incoming hybi13 full header. +- * +- * @todo unit test for the >32 bit frames on 32 bit systems case +- * +- * @param h The basic header to validate +- * @param e The extended header to validate +- * @return An error_code, non-zero values indicate why the validation +- * failed +- */ +- lib::error_code validate_incoming_extended_header(frame::basic_header h, +- frame::extended_header e) const +- { +- uint8_t basic_size = frame::get_basic_size(h); +- uint64_t payload_size = frame::get_payload_size(h,e); +- +- // Check for non-minimally encoded payloads +- if (basic_size == frame::payload_size_code_16bit && +- payload_size <= frame::limits::payload_size_basic) +- { +- return make_error_code(error::non_minimal_encoding); +- } +- +- if (basic_size == frame::payload_size_code_64bit && +- payload_size <= frame::limits::payload_size_extended) +- { +- return make_error_code(error::non_minimal_encoding); +- } +- +- // Check for >32bit frames on 32 bit systems +- if (sizeof(size_t) == 4 && (payload_size >> 32)) { +- return make_error_code(error::requires_64bit); +- } +- +- return lib::error_code(); +- } +- +- /// Copy and mask/unmask in one operation +- /** +- * Reads input from one string and writes unmasked output to another. +- * +- * @param [in] i The input string. +- * @param [out] o The output string. +- * @param [in] key The masking key to use for masking/unmasking +- */ +- void masked_copy (std::string const & i, std::string & o, +- frame::masking_key_type key) const +- { +- frame::byte_mask(i.begin(),i.end(),o.begin(),key); +- // TODO: SIMD masking +- } +- +- /// Generic prepare control frame with opcode and payload. +- /** +- * Internal control frame building method. Handles validation, masking, etc +- * +- * @param op The control opcode to use +- * @param payload The payload to use +- * @param out The message buffer to store the prepared frame in +- * @return Status code, zero on success, non-zero on error +- */ +- lib::error_code prepare_control(frame::opcode::value op, +- std::string const & payload, message_ptr out) const +- { +- if (!out) { +- return make_error_code(error::invalid_arguments); +- } +- +- if (!frame::opcode::is_control(op)) { +- return make_error_code(error::invalid_opcode); +- } +- +- if (payload.size() > frame::limits::payload_size_basic) { +- return make_error_code(error::control_too_big); +- } +- +- frame::masking_key_type key; +- bool masked = !base::m_server; +- +- frame::basic_header h(op,payload.size(),true,masked); +- +- std::string & o = out->get_raw_payload(); +- o.resize(payload.size()); +- +- if (masked) { +- // Generate masking key. +- key.i = m_rng(); +- +- frame::extended_header e(payload.size(),key.i); +- out->set_header(frame::prepare_header(h,e)); +- this->masked_copy(payload,o,key); +- } else { +- frame::extended_header e(payload.size()); +- out->set_header(frame::prepare_header(h,e)); +- std::copy(payload.begin(),payload.end(),o.begin()); +- } +- +- out->set_opcode(op); +- out->set_prepared(true); +- +- return lib::error_code(); +- } +- +- enum state { +- HEADER_BASIC = 0, +- HEADER_EXTENDED = 1, +- EXTENSION = 2, +- APPLICATION = 3, +- READY = 4, +- FATAL_ERROR = 5 +- }; +- +- /// This data structure holds data related to processing a message, such as +- /// the buffer it is being written to, its masking key, its UTF8 validation +- /// state, and sometimes its compression state. +- struct msg_metadata { +- msg_metadata() {} +- msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {} +- msg_metadata(message_ptr m, frame::masking_key_type p) +- : msg_ptr(m) +- , prepared_key(prepare_masking_key(p)) {} +- +- message_ptr msg_ptr; // pointer to the message data buffer +- size_t prepared_key; // prepared masking key +- utf8_validator::validator validator; // utf8 validation state +- }; +- +- // Basic header of the frame being read +- frame::basic_header m_basic_header; +- +- // Pointer to a manager that can create message buffers for us. +- msg_manager_ptr m_msg_manager; +- +- // Number of bytes needed to complete the current operation +- size_t m_bytes_needed; +- +- // Number of extended header bytes read +- size_t m_cursor; +- +- // Metadata for the current data msg +- msg_metadata m_data_msg; +- // Metadata for the current control msg +- msg_metadata m_control_msg; +- +- // Pointer to the metadata associated with the frame being read +- msg_metadata * m_current_msg; +- +- // Extended header of current frame +- frame::extended_header m_extended_header; +- +- rng_type & m_rng; +- +- // Overall state of the processor +- state m_state; +- +- // Extensions +- permessage_deflate_type m_permessage_deflate; +-}; +- +-} // namespace processor +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_PROCESSOR_HYBI13_HPP +diff --git a/src/lib/websocketpp/processors/processor.hpp b/src/lib/websocketpp/processors/processor.hpp +deleted file mode 100644 +index 2aaa1c1..0000000 +--- a/src/lib/websocketpp/processors/processor.hpp ++++ /dev/null +@@ -1,407 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_PROCESSOR_HPP +-#define WEBSOCKETPP_PROCESSOR_HPP +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-/// Processors encapsulate the protocol rules specific to each WebSocket version +-/** +- * The processors namespace includes a number of free functions that operate on +- * various WebSocket related data structures and perform processing that is not +- * related to specific versions of the protocol. +- * +- * It also includes the abstract interface for the protocol specific processing +- * engines. These engines wrap all of the logic necessary for parsing and +- * validating WebSocket handshakes and messages of specific protocol version +- * and set of allowed extensions. +- * +- * An instance of a processor represents the state of a single WebSocket +- * connection of the associated version. One processor instance is needed per +- * logical WebSocket connection. +- */ +-namespace processor { +- +-/// Determine whether or not a generic HTTP request is a WebSocket handshake +-/** +- * @param r The HTTP request to read. +- * +- * @return True if the request is a WebSocket handshake, false otherwise +- */ +-template +-bool is_websocket_handshake(request_type& r) { +- using utility::ci_find_substr; +- +- std::string const & upgrade_header = r.get_header("Upgrade"); +- +- if (ci_find_substr(upgrade_header, constants::upgrade_token, +- sizeof(constants::upgrade_token)-1) == upgrade_header.end()) +- { +- return false; +- } +- +- std::string const & con_header = r.get_header("Connection"); +- +- if (ci_find_substr(con_header, constants::connection_token, +- sizeof(constants::connection_token)-1) == con_header.end()) +- { +- return false; +- } +- +- return true; +-} +- +-/// Extract the version from a WebSocket handshake request +-/** +- * A blank version header indicates a spec before versions were introduced. +- * The only such versions in shipping products are Hixie Draft 75 and Hixie +- * Draft 76. Draft 75 is present in Chrome 4-5 and Safari 5.0.0, Draft 76 (also +- * known as hybi 00 is present in Chrome 6-13 and Safari 5.0.1+. As +- * differentiating between these two sets of browsers is very difficult and +- * Safari 5.0.1+ accounts for the vast majority of cases in the wild this +- * function assumes that all handshakes without a valid version header are +- * Hybi 00. +- * +- * @param r The WebSocket handshake request to read. +- * +- * @return The WebSocket handshake version or -1 if there was an extraction +- * error. +- */ +-template +-int get_websocket_version(request_type& r) { +- if (!r.ready()) { +- return -2; +- } +- +- if (r.get_header("Sec-WebSocket-Version").empty()) { +- return 0; +- } +- +- int version; +- std::istringstream ss(r.get_header("Sec-WebSocket-Version")); +- +- if ((ss >> version).fail()) { +- return -1; +- } +- +- return version; +-} +- +-/// Extract a URI ptr from the host header of the request +-/** +- * @param request The request to extract the Host header from. +- * +- * @param scheme The scheme under which this request was received (ws, wss, +- * http, https, etc) +- * +- * @return A uri_pointer that encodes the value of the host header. +- */ +-template +-uri_ptr get_uri_from_host(request_type & request, std::string scheme) { +- std::string h = request.get_header("Host"); +- +- size_t last_colon = h.rfind(":"); +- size_t last_sbrace = h.rfind("]"); +- +- // no : = hostname with no port +- // last : before ] = ipv6 literal with no port +- // : with no ] = hostname with port +- // : after ] = ipv6 literal with port +- if (last_colon == std::string::npos || +- (last_sbrace != std::string::npos && last_sbrace > last_colon)) +- { +- return lib::make_shared(scheme, h, request.get_uri()); +- } else { +- return lib::make_shared(scheme, +- h.substr(0,last_colon), +- h.substr(last_colon+1), +- request.get_uri()); +- } +-} +- +-/// WebSocket protocol processor abstract base class +-template +-class processor { +-public: +- typedef processor type; +- typedef typename config::request_type request_type; +- typedef typename config::response_type response_type; +- typedef typename config::message_type::ptr message_ptr; +- typedef std::pair err_str_pair; +- +- explicit processor(bool secure, bool p_is_server) +- : m_secure(secure) +- , m_server(p_is_server) +- , m_max_message_size(config::max_message_size) +- {} +- +- virtual ~processor() {} +- +- /// Get the protocol version of this processor +- virtual int get_version() const = 0; +- +- /// Get maximum message size +- /** +- * Get maximum message size. Maximum message size determines the point at which the +- * processor will fail a connection with the message_too_big protocol error. +- * +- * The default is retrieved from the max_message_size value from the template config +- * +- * @since 0.3.0 +- */ +- size_t get_max_message_size() const { +- return m_max_message_size; +- } +- +- /// Set maximum message size +- /** +- * Set maximum message size. Maximum message size determines the point at which the +- * processor will fail a connection with the message_too_big protocol error. +- * +- * The default is retrieved from the max_message_size value from the template config +- * +- * @since 0.3.0 +- * +- * @param new_value The value to set as the maximum message size. +- */ +- void set_max_message_size(size_t new_value) { +- m_max_message_size = new_value; +- } +- +- /// Returns whether or not the permessage_compress extension is implemented +- /** +- * Compile time flag that indicates whether this processor has implemented +- * the permessage_compress extension. By default this is false. +- */ +- virtual bool has_permessage_compress() const { +- return false; +- } +- +- /// Initializes extensions based on the Sec-WebSocket-Extensions header +- /** +- * Reads the Sec-WebSocket-Extensions header and determines if any of the +- * requested extensions are supported by this processor. If they are their +- * settings data is initialized and an extension string to send to the +- * is returned. +- * +- * @param request The request or response headers to look at. +- */ +- virtual err_str_pair negotiate_extensions(request_type const &) { +- return err_str_pair(); +- } +- +- /// Initializes extensions based on the Sec-WebSocket-Extensions header +- /** +- * Reads the Sec-WebSocket-Extensions header and determines if any of the +- * requested extensions were accepted by the server. If they are their +- * settings data is initialized. If they are not a list of required +- * extensions (if any) is returned. This list may be sent back to the server +- * as a part of the 1010/Extension required close code. +- * +- * @param response The request or response headers to look at. +- */ +- virtual err_str_pair negotiate_extensions(response_type const &) { +- return err_str_pair(); +- } +- +- /// validate a WebSocket handshake request for this version +- /** +- * @param request The WebSocket handshake request to validate. +- * is_websocket_handshake(request) must be true and +- * get_websocket_version(request) must equal this->get_version(). +- * +- * @return A status code, 0 on success, non-zero for specific sorts of +- * failure +- */ +- virtual lib::error_code validate_handshake(request_type const & request) const = 0; +- +- /// Calculate the appropriate response for this websocket request +- /** +- * @param req The request to process +- * +- * @param subprotocol The subprotocol in use +- * +- * @param res The response to store the processed response in +- * +- * @return An error code, 0 on success, non-zero for other errors +- */ +- virtual lib::error_code process_handshake(request_type const & req, +- std::string const & subprotocol, response_type& res) const = 0; +- +- /// Fill in an HTTP request for an outgoing connection handshake +- /** +- * @param req The request to process. +- * +- * @return An error code, 0 on success, non-zero for other errors +- */ +- virtual lib::error_code client_handshake_request(request_type & req, +- uri_ptr uri, std::vector const & subprotocols) const = 0; +- +- /// Validate the server's response to an outgoing handshake request +- /** +- * @param req The original request sent +- * @param res The reponse to generate +- * @return An error code, 0 on success, non-zero for other errors +- */ +- virtual lib::error_code validate_server_handshake_response(request_type +- const & req, response_type & res) const = 0; +- +- /// Given a completed response, get the raw bytes to put on the wire +- virtual std::string get_raw(response_type const & request) const = 0; +- +- /// Return the value of the header containing the CORS origin. +- virtual std::string const & get_origin(request_type const & request) const = 0; +- +- /// Extracts requested subprotocols from a handshake request +- /** +- * Extracts a list of all subprotocols that the client has requested in the +- * given opening handshake request. +- * +- * @param [in] req The request to extract from +- * @param [out] subprotocol_list A reference to a vector of strings to store +- * the results in. +- */ +- virtual lib::error_code extract_subprotocols(const request_type & req, +- std::vector & subprotocol_list) = 0; +- +- /// Extracts client uri from a handshake request +- virtual uri_ptr get_uri(request_type const & request) const = 0; +- +- /// process new websocket connection bytes +- /** +- * WebSocket connections are a continous stream of bytes that must be +- * interpreted by a protocol processor into discrete frames. +- * +- * @param buf Buffer from which bytes should be read. +- * @param len Length of buffer +- * @param ec Reference to an error code to return any errors in +- * @return Number of bytes processed +- */ +- virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0; +- +- /// Checks if there is a message ready +- /** +- * Checks if the most recent consume operation processed enough bytes to +- * complete a new WebSocket message. The message can be retrieved by calling +- * get_message() which will reset the internal state to not-ready and allow +- * consume to read more bytes. +- * +- * @return Whether or not a message is ready. +- */ +- virtual bool ready() const = 0; +- +- /// Retrieves the most recently processed message +- /** +- * Retrieves a shared pointer to the recently completed message if there is +- * one. If ready() returns true then there is a message available. +- * Retrieving the message with get_message will reset the state of ready. +- * As such, each new message may be retrieved only once. Calling get_message +- * when there is no message available will result in a null pointer being +- * returned. +- * +- * @return A pointer to the most recently processed message or a null shared +- * pointer. +- */ +- virtual message_ptr get_message() = 0; +- +- /// Tests whether the processor is in a fatal error state +- virtual bool get_error() const = 0; +- +- /// Retrieves the number of bytes presently needed by the processor +- /// This value may be used as a hint to the transport layer as to how many +- /// bytes to wait for before running consume again. +- virtual size_t get_bytes_needed() const { +- return 1; +- } +- +- /// Prepare a data message for writing +- /** +- * Performs validation, masking, compression, etc. will return an error if +- * there was an error, otherwise msg will be ready to be written +- */ +- virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0; +- +- /// Prepare a ping frame +- /** +- * Ping preparation is entirely state free. There is no payload validation +- * other than length. Payload need not be UTF-8. +- * +- * @param in The string to use for the ping payload +- * @param out The message buffer to prepare the ping in. +- * @return Status code, zero on success, non-zero on failure +- */ +- virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const +- = 0; +- +- /// Prepare a pong frame +- /** +- * Pong preparation is entirely state free. There is no payload validation +- * other than length. Payload need not be UTF-8. +- * +- * @param in The string to use for the pong payload +- * @param out The message buffer to prepare the pong in. +- * @return Status code, zero on success, non-zero on failure +- */ +- virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const +- = 0; +- +- /// Prepare a close frame +- /** +- * Close preparation is entirely state free. The code and reason are both +- * subject to validation. Reason must be valid UTF-8. Code must be a valid +- * un-reserved WebSocket close code. Use close::status::no_status to +- * indicate no code. If no code is supplied a reason may not be specified. +- * +- * @param code The close code to send +- * @param reason The reason string to send +- * @param out The message buffer to prepare the fame in +- * @return Status code, zero on success, non-zero on failure +- */ +- virtual lib::error_code prepare_close(close::status::value code, +- std::string const & reason, message_ptr out) const = 0; +-protected: +- bool const m_secure; +- bool const m_server; +- size_t m_max_message_size; +-}; +- +-} // namespace processor +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_PROCESSOR_HPP +diff --git a/src/lib/websocketpp/random/none.hpp b/src/lib/websocketpp/random/none.hpp +deleted file mode 100644 +index 8c22d62..0000000 +--- a/src/lib/websocketpp/random/none.hpp ++++ /dev/null +@@ -1,60 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_RANDOM_NONE_HPP +-#define WEBSOCKETPP_RANDOM_NONE_HPP +- +-namespace ws_websocketpp { +-/// Random number generation policies +-namespace random { +-/// Stub RNG policy that always returns 0 +-namespace none { +- +-/// Thread safe stub "random" integer generator. +-/** +- * This template class provides a random integer stub. The interface mimics the +- * WebSocket++ RNG generator classes but the generater function always returns +- * zero. This can be used to stub out the RNG for unit and performance testing. +- * +- * Call operator() to generate the next number +- */ +-template +-class int_generator { +- public: +- int_generator() {} +- +- /// advances the engine's state and returns the generated value +- int_type operator()() { +- return 0; +- } +-}; +- +-} // namespace none +-} // namespace random +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_RANDOM_NONE_HPP +diff --git a/src/lib/websocketpp/random/random_device.hpp b/src/lib/websocketpp/random/random_device.hpp +deleted file mode 100644 +index 4f9e81f..0000000 +--- a/src/lib/websocketpp/random/random_device.hpp ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP +-#define WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP +- +-#include +- +-namespace ws_websocketpp { +-namespace random { +-/// RNG policy based on std::random_device or boost::random_device +-namespace random_device { +- +-/// Thread safe non-deterministic random integer generator. +-/** +- * This template class provides thread safe non-deterministic random integer +- * generation. Numbers are produced in a uniformly distributed range from the +- * smallest to largest value that int_type can store. +- * +- * Thread-safety is provided via locking based on the concurrency template +- * parameter. +- * +- * Non-deterministic RNG is provided via ws_websocketpp::lib which uses either +- * C++11 or Boost 1.47+'s random_device class. +- * +- * Call operator() to generate the next number +- */ +-template +-class int_generator { +- public: +- typedef typename concurrency::scoped_lock_type scoped_lock_type; +- typedef typename concurrency::mutex_type mutex_type; +- +- /// constructor +- //mac TODO: figure out if signed types present a range problem +- int_generator() {} +- +- /// advances the engine's state and returns the generated value +- int_type operator()() { +- scoped_lock_type guard(m_lock); +- return m_dis(m_rng); +- } +- private: +- +- +- lib::random_device m_rng; +- lib::uniform_int_distribution m_dis; +- +- mutex_type m_lock; +-}; +- +-} // namespace random_device +-} // namespace random +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_RANDOM_RANDOM_DEVICE_HPP +diff --git a/src/lib/websocketpp/roles/client_endpoint.hpp b/src/lib/websocketpp/roles/client_endpoint.hpp +deleted file mode 100644 +index d5922ed..0000000 +--- a/src/lib/websocketpp/roles/client_endpoint.hpp ++++ /dev/null +@@ -1,173 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_CLIENT_ENDPOINT_HPP +-#define WEBSOCKETPP_CLIENT_ENDPOINT_HPP +- +-#include +-#include +- +-#include +- +-#include +- +-#include +- +-namespace ws_websocketpp { +- +-/// Client endpoint role based on the given config +-/** +- * +- */ +-template +-class client : public endpoint,config> { +-public: +- /// Type of this endpoint +- typedef client type; +- +- /// Type of the endpoint concurrency component +- typedef typename config::concurrency_type concurrency_type; +- /// Type of the endpoint transport component +- typedef typename config::transport_type transport_type; +- +- /// Type of the connections this server will create +- typedef connection connection_type; +- /// Type of a shared pointer to the connections this server will create +- typedef typename connection_type::ptr connection_ptr; +- +- /// Type of the connection transport component +- typedef typename transport_type::transport_con_type transport_con_type; +- /// Type of a shared pointer to the connection transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- /// Type of the endpoint component of this server +- typedef endpoint endpoint_type; +- +- friend class connection; +- +- explicit client() : endpoint_type(false) +- { +- endpoint_type::m_alog->write(log::alevel::devel, "client constructor"); +- } +- +- /// Get a new connection +- /** +- * Creates and returns a pointer to a new connection to the given URI +- * suitable for passing to connect(connection_ptr). This method allows +- * applying connection specific settings before performing the opening +- * 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 +- */ +- connection_ptr get_connection(uri_ptr location, lib::error_code & ec) { +- if (location->get_secure() && !transport_type::is_secure()) { +- ec = error::make_error_code(error::endpoint_not_secure); +- return connection_ptr(); +- } +- +- connection_ptr con = endpoint_type::create_connection(); +- +- if (!con) { +- ec = error::make_error_code(error::con_creation_failed); +- return con; +- } +- +- con->set_uri(location); +- +- ec = lib::error_code(); +- return con; +- } +- +- /// Get a new connection (string version) +- /** +- * Creates and returns a pointer to a new connection to the given URI +- * suitable for passing to connect(connection_ptr). This overload allows +- * 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 +- */ +- connection_ptr get_connection(std::string const & u, lib::error_code & ec) { +- uri_ptr location = lib::make_shared(u); +- +- if (!location->get_valid()) { +- ec = error::make_error_code(error::invalid_uri); +- return connection_ptr(); +- } +- +- return get_connection(location, ec); +- } +- +- /// Begin the connection process for the given connection +- /** +- * Initiates the opening connection handshake for connection con. Exact +- * behavior depends on the underlying transport policy. +- * +- * @param con The connection to connect +- * +- * @return The pointer to the connection originally passed in. +- */ +- connection_ptr connect(connection_ptr con) { +- // Ask transport to perform a connection +- transport_type::async_connect( +- lib::static_pointer_cast(con), +- con->get_uri(), +- lib::bind( +- &type::handle_connect, +- this, +- con, +- lib::placeholders::_1 +- ) +- ); +- +- return con; +- } +-private: +- // handle_connect +- void handle_connect(connection_ptr con, lib::error_code const & ec) { +- if (ec) { +- con->terminate(ec); +- +- endpoint_type::m_elog->write(log::elevel::rerror, +- "handle_connect error: "+ec.message()); +- } else { +- endpoint_type::m_alog->write(log::alevel::connect, +- "Successful connection"); +- +- con->start(); +- } +- } +-}; +- +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_CLIENT_ENDPOINT_HPP +diff --git a/src/lib/websocketpp/roles/server_endpoint.hpp b/src/lib/websocketpp/roles/server_endpoint.hpp +deleted file mode 100644 +index 9dc71fd..0000000 +--- a/src/lib/websocketpp/roles/server_endpoint.hpp ++++ /dev/null +@@ -1,195 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_SERVER_ENDPOINT_HPP +-#define WEBSOCKETPP_SERVER_ENDPOINT_HPP +- +-#include +- +-#include +- +-#include +- +-namespace ws_websocketpp { +- +-/// Server endpoint role based on the given config +-/** +- * +- */ +-template +-class server : public endpoint,config> { +-public: +- /// Type of this endpoint +- typedef server type; +- +- /// Type of the endpoint concurrency component +- typedef typename config::concurrency_type concurrency_type; +- /// Type of the endpoint transport component +- typedef typename config::transport_type transport_type; +- +- /// Type of the connections this server will create +- typedef connection connection_type; +- /// Type of a shared pointer to the connections this server will create +- typedef typename connection_type::ptr connection_ptr; +- +- /// Type of the connection transport component +- typedef typename transport_type::transport_con_type transport_con_type; +- /// Type of a shared pointer to the connection transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- /// Type of the endpoint component of this server +- typedef endpoint endpoint_type; +- +- friend class connection; +- +- explicit server() : endpoint_type(true) +- { +- endpoint_type::m_alog->write(log::alevel::devel, "server constructor"); +- } +- +- /// Destructor +- ~server() {} +- +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no copy constructor because endpoints are not copyable +- server(server &) = delete; +- +- // no copy assignment operator because endpoints are not copyable +- server & operator=(server const &) = delete; +-#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +-#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ +- /// Move constructor +- server(server && o) : endpoint,config>(std::move(o)) {} +- +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- // no move assignment operator because of const member variables +- server & operator=(server &&) = delete; +-#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +-#endif // _WEBSOCKETPP_MOVE_SEMANTICS_ +- +- /// Create and initialize a new connection +- /** +- * The connection will be initialized and ready to begin. Call its start() +- * method to begin the processing loop. +- * +- * Note: The connection must either be started or terminated using +- * connection::terminate in order to avoid memory leaks. +- * +- * @return A pointer to the new connection. +- */ +- connection_ptr get_connection() { +- return endpoint_type::create_connection(); +- } +- +- /// Starts the server's async connection acceptance loop (exception free) +- /** +- * Initiates the server connection acceptance loop. Must be called after +- * listen. This method will have no effect until the underlying io_service +- * starts running. It may be called after the io_service is already running. +- * +- * 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) { +- if (!transport_type::is_listening()) { +- ec = error::make_error_code(error::async_accept_not_listening); +- return; +- } +- +- ec = lib::error_code(); +- connection_ptr con = get_connection(); +- +- if (!con) { +- ec = error::make_error_code(error::con_creation_failed); +- return; +- } +- +- transport_type::async_accept( +- lib::static_pointer_cast(con), +- lib::bind(&type::handle_accept,this,con,lib::placeholders::_1), +- ec +- ); +- +- if (ec && con) { +- // If the connection was constructed but the accept failed, +- // terminate the connection to prevent memory leaks +- con->terminate(lib::error_code()); +- } +- } +- +- /// Starts the server's async connection acceptance loop +- /** +- * Initiates the server connection acceptance loop. Must be called after +- * listen. This method will have no effect until the underlying io_service +- * starts running. It may be called after the io_service is already running. +- * +- * Refer to documentation for the transport policy you are using for +- * instructions on how to stop this acceptance loop. +- */ +- void start_accept() { +- lib::error_code ec; +- start_accept(ec); +- if (ec) { +- throw exception(ec); +- } +- } +- +- /// Handler callback for start_accept +- void handle_accept(connection_ptr con, lib::error_code const & ec) { +- if (ec) { +- con->terminate(ec); +- +- 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, +- "handle_accept error: "+ec.message()); +- } +- } else { +- con->start(); +- } +- +- lib::error_code start_ec; +- start_accept(start_ec); +- 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, +- "Restarting async_accept loop failed: "+ec.message()); +- } +- } +-}; +- +-} // namespace ws_websocketpp +- +-#endif //WEBSOCKETPP_SERVER_ENDPOINT_HPP +diff --git a/src/lib/websocketpp/server.hpp b/src/lib/websocketpp/server.hpp +deleted file mode 100644 +index 342fa8c..0000000 +--- a/src/lib/websocketpp/server.hpp ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_SERVER_HPP +-#define WEBSOCKETPP_SERVER_HPP +- +-#include +- +-#endif //WEBSOCKETPP_SERVER_HPP +diff --git a/src/lib/websocketpp/sha1/sha1.hpp b/src/lib/websocketpp/sha1/sha1.hpp +deleted file mode 100644 +index fcd15d9..0000000 +--- a/src/lib/websocketpp/sha1/sha1.hpp ++++ /dev/null +@@ -1,189 +0,0 @@ +-/* +-***** +-sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1 +-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. +- */ +- +-#ifndef SHA1_DEFINED +-#define SHA1_DEFINED +- +-namespace ws_websocketpp { +-namespace sha1 { +- +-namespace { // local +- +-// Rotate an integer value to left. +-inline unsigned int rol(unsigned int value, 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; +- } +-} +- +-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 +- +-/// Calculate a SHA1 hash +-/** +- * @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. +- */ +-inline void calc(void const * src, size_t 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. +- unsigned char const * sarray = (unsigned char const *) src; +- +- // The reusable round buffer +- unsigned int w[80]; +- +- // Loop through all complete 64byte blocks. +- +- size_t endCurrentBlock; +- size_t currentBlock = 0; +- +- if (bytelength >= 64) { +- size_t const endOfFullBlocks = bytelength - 64; +- +- 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); +- size_t 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; +- } +-} +- +-} // namespace sha1 +-} // namespace ws_websocketpp +- +-#endif // SHA1_DEFINED +diff --git a/src/lib/websocketpp/transport/asio/base.hpp b/src/lib/websocketpp/transport/asio/base.hpp +deleted file mode 100644 +index 0649667..0000000 +--- a/src/lib/websocketpp/transport/asio/base.hpp ++++ /dev/null +@@ -1,232 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_ASIO_BASE_HPP +- +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-/// Transport policy that uses asio +-/** +- * This policy uses a single asio io_service to provide transport +- * services to a WebSocket++ endpoint. +- */ +-namespace asio { +- +-// Class to manage the memory to be used for handler-based custom allocation. +-// It contains a single block of memory which may be returned for allocation +-// requests. If the memory is in use when an allocation request is made, the +-// allocator delegates allocation to the global heap. +-class handler_allocator { +-public: +- static const size_t size = 1024; +- +- handler_allocator() : m_in_use(false) {} +- +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- handler_allocator(handler_allocator const & cpy) = delete; +- handler_allocator & operator =(handler_allocator const &) = delete; +-#endif +- +- void * allocate(std::size_t memsize) { +- if (!m_in_use && memsize < size) { +- m_in_use = true; +- return static_cast(&m_storage); +- } else { +- return ::operator new(memsize); +- } +- } +- +- void deallocate(void * pointer) { +- if (pointer == &m_storage) { +- m_in_use = false; +- } else { +- ::operator delete(pointer); +- } +- } +- +-private: +- // Storage space used for handler-based custom memory allocation. +- lib::aligned_storage::type m_storage; +- +- // Whether the handler-based custom allocation storage has been used. +- bool m_in_use; +-}; +- +-// Wrapper class template for handler objects to allow handler memory +-// allocation to be customised. Calls to operator() are forwarded to the +-// encapsulated handler. +-template +-class custom_alloc_handler { +-public: +- custom_alloc_handler(handler_allocator& a, Handler h) +- : allocator_(a), +- handler_(h) +- {} +- +- template +- void operator()(Arg1 arg1) { +- handler_(arg1); +- } +- +- template +- void operator()(Arg1 arg1, Arg2 arg2) { +- handler_(arg1, arg2); +- } +- +- friend void* asio_handler_allocate(std::size_t size, +- custom_alloc_handler * this_handler) +- { +- return this_handler->allocator_.allocate(size); +- } +- +- friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/, +- custom_alloc_handler * this_handler) +- { +- this_handler->allocator_.deallocate(pointer); +- } +- +-private: +- handler_allocator & allocator_; +- Handler handler_; +-}; +- +-// Helper function to wrap a handler object to add custom allocation. +-template +-inline custom_alloc_handler make_custom_alloc_handler( +- handler_allocator & a, Handler h) +-{ +- return custom_alloc_handler(a, h); +-} +- +- +- +- +- +- +- +-// Forward declaration of class endpoint so that it can be friended/referenced +-// before being included. +-template +-class endpoint; +- +-typedef lib::function async_read_handler; +- +-typedef lib::function async_write_handler; +- +-typedef lib::function pre_init_handler; +- +-// handle_timer: dynamic parameters, multiple copies +-// handle_proxy_write +-// handle_proxy_read +-// handle_async_write +-// handle_pre_init +- +- +-/// Asio transport errors +-namespace error { +-enum value { +- /// Catch-all error for transport policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// async_read_at_least call requested more bytes than buffer can store +- invalid_num_bytes, +- +- /// there was an error in the underlying transport library +- pass_through, +- +- /// The connection to the requested proxy server failed +- proxy_failed, +- +- /// Invalid Proxy URI +- proxy_invalid, +- +- /// Invalid host or service +- invalid_host_service +-}; +- +-/// Asio transport error category +-class category : public lib::error_category { +-public: +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport.asio"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case error::general: +- return "Generic asio transport policy error"; +- case error::invalid_num_bytes: +- return "async_read_at_least call requested more bytes than buffer can store"; +- case error::pass_through: +- return "Underlying Transport Error"; +- case error::proxy_failed: +- return "Proxy connection failed"; +- case error::proxy_invalid: +- return "Invalid proxy URI"; +- case error::invalid_host_service: +- return "Invalid host or service"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the asio transport error category +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-/// Create an error code with the given value and the asio transport category +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +-#endif // WEBSOCKETPP_TRANSPORT_ASIO_HPP +diff --git a/src/lib/websocketpp/transport/asio/connection.hpp b/src/lib/websocketpp/transport/asio/connection.hpp +deleted file mode 100644 +index 9ac720d..0000000 +--- a/src/lib/websocketpp/transport/asio/connection.hpp ++++ /dev/null +@@ -1,1197 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP +-#define WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP +- +-#include +- +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace asio { +- +-typedef lib::function tcp_init_handler; +- +-/// Asio based connection transport component +-/** +- * transport::asio::connection implements a connection transport component using +- * Asio that works with the transport::asio::endpoint endpoint transport +- * component. +- */ +-template +-class connection : public config::socket_type::socket_con_type { +-public: +- /// Type of this connection transport component +- typedef connection type; +- /// Type of a shared pointer to this connection transport component +- typedef lib::shared_ptr ptr; +- +- /// Type of the socket connection component +- typedef typename config::socket_type::socket_con_type socket_con_type; +- /// Type of a shared pointer to the socket connection component +- typedef typename socket_con_type::ptr socket_con_ptr; +- /// Type of this transport's access logging policy +- typedef typename config::alog_type alog_type; +- /// Type of this transport's error logging policy +- typedef typename config::elog_type elog_type; +- +- typedef typename config::request_type request_type; +- typedef typename request_type::ptr request_ptr; +- typedef typename config::response_type response_type; +- typedef typename response_type::ptr response_ptr; +- +- /// Type of a pointer to the Asio io_service being used +- typedef lib::asio::io_service * io_service_ptr; +- /// Type of a pointer to the Asio io_service::strand being used +- typedef lib::shared_ptr strand_ptr; +- /// Type of a pointer to the Asio timer class +- typedef lib::shared_ptr 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; +- +- // generate and manage our own io_service +- explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) +- : m_is_server(is_server) +- , m_alog(alog) +- , m_elog(elog) +- { +- m_alog->write(log::alevel::devel,"asio con transport constructor"); +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return lib::static_pointer_cast(socket_con_type::get_shared()); +- } +- +- bool is_secure() const { +- return socket_con_type::is_secure(); +- } +- +- /// Set uri hook +- /** +- * 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 +- * socket layer. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr u) { +- socket_con_type::set_uri(u); +- } +- +- /// Sets the tcp pre init handler +- /** +- * The tcp pre init handler is called after the raw tcp connection has been +- * established but before any additional wrappers (proxy connects, TLS +- * handshakes, etc) have been performed. +- * +- * @since 0.3.0 +- * +- * @param h The handler to call on tcp pre init. +- */ +- void set_tcp_pre_init_handler(tcp_init_handler h) { +- m_tcp_pre_init_handler = h; +- } +- +- /// Sets the tcp pre init handler (deprecated) +- /** +- * The tcp pre init handler is called after the raw tcp connection has been +- * established but before any additional wrappers (proxy connects, TLS +- * handshakes, etc) have been performed. +- * +- * @deprecated Use set_tcp_pre_init_handler instead +- * +- * @param h The handler to call on tcp pre init. +- */ +- void set_tcp_init_handler(tcp_init_handler h) { +- set_tcp_pre_init_handler(h); +- } +- +- /// Sets the tcp post init handler +- /** +- * The tcp post init handler is called after the tcp connection has been +- * established and all additional wrappers (proxy connects, TLS handshakes, +- * etc have been performed. This is fired before any bytes are read or any +- * WebSocket specific handshake logic has been performed. +- * +- * @since 0.3.0 +- * +- * @param h The handler to call on tcp post init. +- */ +- void set_tcp_post_init_handler(tcp_init_handler h) { +- m_tcp_post_init_handler = h; +- } +- +- /// Set the proxy to connect through (exception free) +- /** +- * The URI passed should be a complete URI including scheme. For example: +- * http://proxy.example.com:8080/ +- * +- * The proxy must be set up as an explicit (CONNECT) proxy allowed to +- * connect to the port you specify. Traffic to the proxy is not encrypted. +- * +- * @param uri The full URI of the proxy to connect to. +- * +- * @param ec A status value +- */ +- void set_proxy(std::string const & uri, lib::error_code & ec) { +- // TODO: return errors for illegal URIs here? +- // TODO: should https urls be illegal for the moment? +- m_proxy = uri; +- m_proxy_data = lib::make_shared(); +- ec = lib::error_code(); +- } +- +- /// Set the proxy to connect through (exception) +- void set_proxy(std::string const & uri) { +- lib::error_code ec; +- set_proxy(uri,ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Set the basic auth credentials to use (exception free) +- /** +- * The URI passed should be a complete URI including scheme. For example: +- * http://proxy.example.com:8080/ +- * +- * The proxy must be set up as an explicit proxy +- * +- * @param username The username to send +- * +- * @param password The password to send +- * +- * @param ec A status value +- */ +- void set_proxy_basic_auth(std::string const & username, std::string const & +- password, lib::error_code & ec) +- { +- if (!m_proxy_data) { +- ec = make_error_code(ws_websocketpp::error::invalid_state); +- return; +- } +- +- // TODO: username can't contain ':' +- std::string val = "Basic "+base64_encode(username + ":" + password); +- m_proxy_data->req.replace_header("Proxy-Authorization",val); +- ec = lib::error_code(); +- } +- +- /// Set the basic auth credentials to use (exception) +- void set_proxy_basic_auth(std::string const & username, std::string const & +- password) +- { +- lib::error_code ec; +- set_proxy_basic_auth(username,password,ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Set the proxy timeout duration (exception free) +- /** +- * Duration is in milliseconds. Default value is based on the transport +- * config +- * +- * @param duration The number of milliseconds to wait before aborting the +- * proxy connection. +- * +- * @param ec A status value +- */ +- void set_proxy_timeout(long duration, lib::error_code & ec) { +- if (!m_proxy_data) { +- ec = make_error_code(ws_websocketpp::error::invalid_state); +- return; +- } +- +- m_proxy_data->timeout_proxy = duration; +- ec = lib::error_code(); +- } +- +- /// Set the proxy timeout duration (exception) +- void set_proxy_timeout(long duration) { +- lib::error_code ec; +- set_proxy_timeout(duration,ec); +- if (ec) { throw exception(ec); } +- } +- +- std::string const & get_proxy() const { +- return m_proxy; +- } +- +- /// Get the remote endpoint address +- /** +- * The iostream transport has no information about the ultimate remote +- * endpoint. It will return the string "iostream transport". To indicate +- * this. +- * +- * TODO: allow user settable remote endpoint addresses if this seems useful +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint() const { +- lib::error_code ec; +- +- std::string ret = socket_con_type::get_remote_endpoint(ec); +- +- if (ec) { +- m_elog->write(log::elevel::info,ret); +- return "Unknown"; +- } else { +- return ret; +- } +- } +- +- /// Get the connection handle +- connection_hdl get_handle() const { +- return m_connection_hdl; +- } +- +- /// Call back a function after a period of time. +- /** +- * Sets a timer that calls back a function after the specified period of +- * milliseconds. Returns a handle that can be used to cancel the timer. +- * A cancelled timer will return the error code error::operation_aborted +- * A timer that expired will return no error. +- * +- * @param duration Length of time to wait in milliseconds +- * +- * @param callback The function to call back when the timer has expired +- * +- * @return A handle that can be used to cancel the timer if it is no longer +- * needed. +- */ +- timer_ptr set_timer(long duration, timer_handler callback) { +- timer_ptr new_timer = lib::make_shared( +- lib::ref(*m_io_service), +- lib::asio::milliseconds(duration) +- ); +- +- if (config::enable_multithreading) { +- new_timer->async_wait(m_strand->wrap(lib::bind( +- &type::handle_timer, get_shared(), +- new_timer, +- callback, +- lib::placeholders::_1 +- ))); +- } else { +- new_timer->async_wait(lib::bind( +- &type::handle_timer, get_shared(), +- new_timer, +- callback, +- lib::placeholders::_1 +- )); +- } +- +- return new_timer; +- } +- +- /// Timer callback +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * TODO: candidate for protected status +- * +- * @param post_timer Pointer to the timer in question +- * @param callback The function to call back +- * @param ec The status code +- */ +- void handle_timer(timer_ptr, timer_handler callback, +- lib::asio::error_code const & ec) +- { +- if (ec) { +- 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); +- callback(make_error_code(error::pass_through)); +- } +- } else { +- callback(lib::error_code()); +- } +- } +- +- /// Get a pointer to this connection's strand +- strand_ptr get_strand() { +- return m_strand; +- } +- +- /// Get the internal transport error code for a closed/failed connection +- /** +- * Retrieves a machine readable detailed error code indicating the reason +- * that the connection was closed or failed. Valid only after the close or +- * fail handler is called. +- * +- * 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 +- * library error code type will be coerced into a catch all `pass_through` +- * 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 +- * failed +- */ +- lib::asio::error_code get_transport_ec() const { +- return m_tec; +- } +- +- /// Initialize transport for reading +- /** +- * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service +- * +- * The transport initialization sequence consists of the following steps: +- * - Pre-init: the underlying socket is initialized to the point where +- * bytes may be written. No bytes are actually written in this stage +- * - Proxy negotiation: if a proxy is set, a request is made to it to start +- * a tunnel to the final destination. This stage ends when the proxy is +- * ready to forward the +- * next byte to the remote endpoint. +- * - Post-init: Perform any i/o with the remote endpoint, such as setting up +- * tunnels for encryption. This stage ends when the connection is ready to +- * read or write the WebSocket handshakes. At this point the original +- * callback function is called. +- */ +-protected: +- void init(init_handler callback) { +- 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 +- // actually have an asyncronous pre-init +- +- socket_con_type::pre_init( +- lib::bind( +- &type::handle_pre_init, +- get_shared(), +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- +- /// 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 ws_websocketpp::error::make_error_code( +- ws_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 +- * 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) { +- m_io_service = io_service; +- +- if (config::enable_multithreading) { +- m_strand = lib::make_shared( +- lib::ref(*io_service)); +- } +- +- lib::error_code ec = socket_con_type::init_asio(io_service, m_strand, +- m_is_server); +- +- return ec; +- } +- +- 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_tcp_pre_init_handler) { +- m_tcp_pre_init_handler(m_connection_hdl); +- } +- +- if (ec) { +- callback(ec); +- } +- +- // If we have a proxy set issue a proxy connect, otherwise skip to +- // post_init +- if (!m_proxy.empty()) { +- proxy_write(callback); +- } else { +- post_init(callback); +- } +- } +- +- void post_init(init_handler callback) { +- 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, +- lib::bind( +- &type::handle_post_init_timeout, +- get_shared(), +- post_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- +- socket_con_type::post_init( +- lib::bind( +- &type::handle_post_init, +- get_shared(), +- post_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- +- /// Post init timeout callback +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * @param post_timer Pointer to the timer in question +- * @param callback The function to call back +- * @param ec The status code +- */ +- void handle_post_init_timeout(timer_ptr, init_handler callback, +- lib::error_code const & ec) +- { +- lib::error_code ret_ec; +- +- if (ec) { +- if (ec == transport::error::operation_aborted) { +- m_alog->write(log::alevel::devel, +- "asio post init timer cancelled"); +- return; +- } +- +- log_err(log::elevel::devel,"asio handle_post_init_timeout",ec); +- ret_ec = ec; +- } else { +- if (socket_con_type::get_ec()) { +- ret_ec = socket_con_type::get_ec(); +- } else { +- ret_ec = make_error_code(transport::error::timeout); +- } +- } +- +- m_alog->write(log::alevel::devel, "Asio transport post-init timed out"); +- cancel_socket_checked(); +- callback(ret_ec); +- } +- +- /// Post init timeout callback +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * @param post_timer Pointer to the timer in question +- * @param callback The function to call back +- * @param ec The status code +- */ +- void handle_post_init(timer_ptr post_timer, init_handler callback, +- lib::error_code const & ec) +- { +- 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"); +- return; +- } +- +- if (post_timer) { +- post_timer->cancel(); +- } +- +- 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) { +- m_tcp_post_init_handler(m_connection_hdl); +- } +- +- callback(ec); +- } +- +- 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_proxy_data) { +- m_elog->write(log::elevel::library, +- "assertion failed: !m_proxy_data in asio::connection::proxy_write"); +- callback(make_error_code(error::general)); +- return; +- } +- +- m_proxy_data->write_buf = m_proxy_data->req.raw(); +- +- 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); +- +- // Set a timer so we don't wait forever for the proxy to respond +- m_proxy_data->timer = this->set_timer( +- m_proxy_data->timeout_proxy, +- lib::bind( +- &type::handle_proxy_timeout, +- get_shared(), +- callback, +- lib::placeholders::_1 +- ) +- ); +- +- // Send proxy request +- if (config::enable_multithreading) { +- lib::asio::async_write( +- socket_con_type::get_next_layer(), +- m_bufs, +- m_strand->wrap(lib::bind( +- &type::handle_proxy_write, get_shared(), +- callback, +- lib::placeholders::_1 +- )) +- ); +- } else { +- lib::asio::async_write( +- socket_con_type::get_next_layer(), +- m_bufs, +- lib::bind( +- &type::handle_proxy_write, get_shared(), +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- } +- +- void handle_proxy_timeout(init_handler callback, lib::error_code const & ec) +- { +- 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, +- "asio handle_proxy_write timer expired"); +- cancel_socket_checked(); +- callback(make_error_code(transport::error::timeout)); +- } +- } +- +- 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, +- "asio connection handle_proxy_write"); +- } +- +- m_bufs.clear(); +- +- // 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 == 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"); +- return; +- } +- +- if (ec) { +- log_err(log::elevel::info,"asio handle_proxy_write",ec); +- m_proxy_data->timer->cancel(); +- callback(make_error_code(error::pass_through)); +- return; +- } +- +- proxy_read(callback); +- } +- +- 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_proxy_data) { +- m_elog->write(log::elevel::library, +- "assertion failed: !m_proxy_data in asio::connection::proxy_read"); +- m_proxy_data->timer->cancel(); +- callback(make_error_code(error::general)); +- return; +- } +- +- if (config::enable_multithreading) { +- lib::asio::async_read_until( +- socket_con_type::get_next_layer(), +- m_proxy_data->read_buf, +- "\r\n\r\n", +- m_strand->wrap(lib::bind( +- &type::handle_proxy_read, get_shared(), +- callback, +- lib::placeholders::_1, lib::placeholders::_2 +- )) +- ); +- } else { +- lib::asio::async_read_until( +- socket_con_type::get_next_layer(), +- m_proxy_data->read_buf, +- "\r\n\r\n", +- lib::bind( +- &type::handle_proxy_read, get_shared(), +- callback, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- ); +- } +- } +- +- /// Proxy read callback +- /** +- * @param init_handler The function to call back +- * @param ec The status code +- * @param bytes_transferred The number of bytes read +- */ +- 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, +- "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 == 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"); +- return; +- } +- +- // At this point there is no need to wait for the timer anymore +- m_proxy_data->timer->cancel(); +- +- if (ec) { +- 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, +- "assertion failed: !m_proxy_data in asio::connection::handle_proxy_read"); +- callback(make_error_code(error::general)); +- return; +- } +- +- std::istream input(&m_proxy_data->read_buf); +- +- m_proxy_data->res.consume(input); +- +- if (!m_proxy_data->res.headers_ready()) { +- // we read until the headers were done in theory but apparently +- // they aren't. Internal endpoint error. +- callback(make_error_code(error::general)); +- return; +- } +- +- 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 +- // TODO: expose this error in a programmatically accessible way? +- // if so, see below for an option on how to do this. +- std::stringstream s; +- s << "Proxy connection error: " +- << m_proxy_data->res.get_status_code() +- << " (" +- << m_proxy_data->res.get_status_msg() +- << ")"; +- m_elog->write(log::elevel::info,s.str()); +- callback(make_error_code(error::proxy_failed)); +- return; +- } +- +- // we have successfully established a connection to the proxy, now +- // we can continue and the proxy will transparently forward the +- // WebSocket connection. +- +- // TODO: decide if we want an on_proxy callback that would allow +- // access to the proxy response. +- +- // free the proxy buffers and req/res objects as they aren't needed +- // anymore +- m_proxy_data.reset(); +- +- // Continue with post proxy initialization +- post_init(callback); +- } +- } +- +- /// read at least num_bytes bytes into buf and then call handler. +- 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)) { +- std::stringstream s; +- s << "asio async_read_at_least: " << num_bytes; +- 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, +- "asio async_read_at_least error::invalid_num_bytes"); +- handler(make_error_code(transport::error::invalid_num_bytes), +- size_t(0)); +- return; +- }*/ +- +- if (config::enable_multithreading) { +- lib::asio::async_read( +- socket_con_type::get_socket(), +- lib::asio::buffer(buf,len), +- lib::asio::transfer_at_least(num_bytes), +- m_strand->wrap(make_custom_alloc_handler( +- m_read_handler_allocator, +- lib::bind( +- &type::handle_async_read, get_shared(), +- handler, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- )) +- ); +- } else { +- lib::asio::async_read( +- socket_con_type::get_socket(), +- lib::asio::buffer(buf,len), +- lib::asio::transfer_at_least(num_bytes), +- make_custom_alloc_handler( +- m_read_handler_allocator, +- lib::bind( +- &type::handle_async_read, get_shared(), +- handler, +- 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"); +- +- // translate asio error codes into more lib::error_codes +- lib::error_code tec; +- 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 +- // socket/security policy if it knows more: +- tec = socket_con_type::translate_ec(ec); +- m_tec = ec; +- +- 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 +- // more details about why the upstream method may have failed. +- log_err(log::elevel::info,"asio async_read_at_least",ec); +- } +- } +- if (handler) { +- handler(tec,bytes_transferred); +- } 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, +- "handle_async_read called with null read handler"); +- } +- } +- +- /// Initiate a potentially asyncronous write of the given buffer +- void async_write(const char* buf, size_t len, write_handler handler) { +- m_bufs.push_back(lib::asio::buffer(buf,len)); +- +- if (config::enable_multithreading) { +- lib::asio::async_write( +- socket_con_type::get_socket(), +- m_bufs, +- m_strand->wrap(make_custom_alloc_handler( +- m_write_handler_allocator, +- lib::bind( +- &type::handle_async_write, get_shared(), +- handler, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- )) +- ); +- } else { +- lib::asio::async_write( +- socket_con_type::get_socket(), +- m_bufs, +- make_custom_alloc_handler( +- m_write_handler_allocator, +- lib::bind( +- &type::handle_async_write, get_shared(), +- handler, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- ) +- ); +- } +- } +- +- /// Initiate a potentially asyncronous write of the given buffers +- void async_write(std::vector const & bufs, write_handler handler) { +- std::vector::const_iterator it; +- +- for (it = bufs.begin(); it != bufs.end(); ++it) { +- m_bufs.push_back(lib::asio::buffer((*it).buf,(*it).len)); +- } +- +- if (config::enable_multithreading) { +- lib::asio::async_write( +- socket_con_type::get_socket(), +- m_bufs, +- m_strand->wrap(make_custom_alloc_handler( +- m_write_handler_allocator, +- lib::bind( +- &type::handle_async_write, get_shared(), +- handler, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- )) +- ); +- } else { +- lib::asio::async_write( +- socket_con_type::get_socket(), +- m_bufs, +- make_custom_alloc_handler( +- m_write_handler_allocator, +- lib::bind( +- &type::handle_async_write, get_shared(), +- handler, +- lib::placeholders::_1, lib::placeholders::_2 +- ) +- ) +- ); +- } +- } +- +- /// Async write callback +- /** +- * @param ec The status code +- * @param bytes_transferred The number of bytes read +- */ +- void handle_async_write(write_handler handler, lib::asio::error_code const & ec, size_t) { +- m_bufs.clear(); +- lib::error_code tec; +- if (ec) { +- log_err(log::elevel::info,"asio async_write",ec); +- tec = make_error_code(transport::error::pass_through); +- } +- if (handler) { +- handler(tec); +- } 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, +- "handle_async_write called with null write handler"); +- } +- } +- +- /// Set Connection Handle +- /** +- * See common/connection_hdl.hpp for information +- * +- * @param hdl A connection_hdl that the transport will use to refer +- * to itself +- */ +- void set_handle(connection_hdl hdl) { +- m_connection_hdl = hdl; +- socket_con_type::set_handle(hdl); +- } +- +- /// Trigger the on_interrupt handler +- /** +- * This needs to be thread safe +- */ +- lib::error_code interrupt(interrupt_handler handler) { +- if (config::enable_multithreading) { +- m_io_service->post(m_strand->wrap(handler)); +- } else { +- m_io_service->post(handler); +- } +- return lib::error_code(); +- } +- +- lib::error_code dispatch(dispatch_handler handler) { +- if (config::enable_multithreading) { +- m_io_service->post(m_strand->wrap(handler)); +- } else { +- m_io_service->post(handler); +- } +- return lib::error_code(); +- } +- +- /*void handle_interrupt(interrupt_handler handler) { +- handler(); +- }*/ +- +- /// 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"); +- } +- +- timer_ptr shutdown_timer; +- shutdown_timer = set_timer( +- config::timeout_socket_shutdown, +- lib::bind( +- &type::handle_async_shutdown_timeout, +- get_shared(), +- shutdown_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- +- socket_con_type::async_shutdown( +- lib::bind( +- &type::handle_async_shutdown, +- get_shared(), +- shutdown_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- +- /// Async shutdown timeout handler +- /** +- * @param shutdown_timer A pointer to the timer to keep it in scope +- * @param callback The function to call back +- * @param ec The status code +- */ +- void handle_async_shutdown_timeout(timer_ptr, init_handler callback, +- lib::error_code const & ec) +- { +- lib::error_code ret_ec; +- +- if (ec) { +- if (ec == transport::error::operation_aborted) { +- m_alog->write(log::alevel::devel, +- "asio socket shutdown timer cancelled"); +- return; +- } +- +- log_err(log::elevel::devel,"asio handle_async_shutdown_timeout",ec); +- ret_ec = ec; +- } else { +- ret_ec = make_error_code(transport::error::timeout); +- } +- +- m_alog->write(log::alevel::devel, +- "Asio transport socket shutdown timed out"); +- cancel_socket_checked(); +- callback(ret_ec); +- } +- +- void handle_async_shutdown(timer_ptr shutdown_timer, shutdown_handler +- callback, lib::asio::error_code const & ec) +- { +- 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"); +- return; +- } +- +- shutdown_timer->cancel(); +- +- lib::error_code tec; +- if (ec) { +- 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 +- // level of the stack. +- } else { +- // We don't know anything more about this error, give our +- // socket/security policy a crack at it. +- tec = socket_con_type::translate_ec(ec); +- m_tec = 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, +- "asio con handle_async_shutdown"); +- } +- } +- callback(tec); +- } +- +- /// Cancel the underlying socket and log any errors +- void cancel_socket_checked() { +- lib::asio::error_code cec = socket_con_type::cancel_socket(); +- if (cec) { +- 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"); +- } else { +- log_err(log::elevel::warn, "socket cancel failed", cec); +- } +- } +- } +- +-private: +- /// Convenience method for logging the code and message for an error_code +- template +- 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()); +- } +- +- // static settings +- const bool m_is_server; +- lib::shared_ptr m_alog; +- lib::shared_ptr m_elog; +- +- struct proxy_data { +- proxy_data() : timeout_proxy(config::timeout_proxy) {} +- +- request_type req; +- response_type res; +- std::string write_buf; +- lib::asio::streambuf read_buf; +- long timeout_proxy; +- timer_ptr timer; +- }; +- +- std::string m_proxy; +- lib::shared_ptr m_proxy_data; +- +- // transport resources +- io_service_ptr m_io_service; +- strand_ptr m_strand; +- connection_hdl m_connection_hdl; +- +- std::vector m_bufs; +- +- /// Detailed internal error code +- lib::asio::error_code m_tec; +- +- // Handlers +- tcp_init_handler m_tcp_pre_init_handler; +- tcp_init_handler m_tcp_post_init_handler; +- +- handler_allocator m_read_handler_allocator; +- handler_allocator m_write_handler_allocator; +-}; +- +- +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP +diff --git a/src/lib/websocketpp/transport/asio/endpoint.hpp b/src/lib/websocketpp/transport/asio/endpoint.hpp +deleted file mode 100644 +index 6374bb4..0000000 +--- a/src/lib/websocketpp/transport/asio/endpoint.hpp ++++ /dev/null +@@ -1,1249 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_ASIO_HPP +-#define WEBSOCKETPP_TRANSPORT_ASIO_HPP +- +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace asio { +- +-/*** +- * In current versions of libstdc++, the error_constants.h code associated to mingw32 +- * does not define certain standard enum values for `std::errc`. (In C++11 standard, +- * sections 19.5.2, 19.5.3.) Asio uses these for lib::asio::errc when it is compiled +- * as a stand-alone library, so because of the libstdc++ defect, code below referring +- * to lib::asio::errc::operation_canceled fails to compile on mingw. +- * +- * This workaround detects the defect using SFINAE and returns 'false' for the check +- * if operation_canceled is not defined, instead of failing to compile. +- * +- * If upstream patches this later by defining those enum values, then the workaround +- * will stop having any effect. +- * +- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68307 +- */ +-namespace _workaround_gcc_libstdcpp_issue_68307_missing_values { +-/*** +- * Same as std::enable_if, but don't want to introduce dependency on +- * since that's C++11 only +- */ +-template +-struct enable_if {}; +- +-template +-struct enable_if { typedef T type; }; +- +-/*** +- * Metafunction to test "operation_canceled" value +- */ +-template +-struct op_canceled_helper { +- template +- static inline bool is_op_canceled(const U & u) { return false; } +-}; +- +-template +-struct op_canceled_helper > { +- template +- static inline bool is_op_canceled(const U & u) { return u == T::operation_canceled; } +-}; +- +-/*** +- * This function is intended to be a drop-in replacement for +- * (asio_ec == lib::asio::errc::operation_canceled) +- * +- * except that if lib::asio::errc::operation_canceled does not exist, it returns false, +- * instead of failing to compile. +- * +- * When using boost and not asio standalone, then lib::asio::errc is a namespace, not an enum class. +- * So the template code will fail to compile and we need to block it from being instantiated, with this +- * ifdef. When using boost the standard library symbol definitions aren't relevant afaik. +- */ +-#ifdef ASIO_STANDALONE +-static inline bool is_op_canceled(const lib::asio::error_code & asio_ec) { +- return op_canceled_helper::is_op_canceled(asio_ec); +-} +-#else +-static inline bool is_op_canceled(const lib::asio::error_code & asio_ec) { +- return asio_ec == lib::asio::errc::operation_canceled; +-} +-#endif +-} // namespace _workaround +- +-/// Asio based endpoint transport component +-/** +- * transport::asio::endpoint implements an endpoint transport component using +- * Asio. +- */ +-template +-class endpoint : public config::socket_type { +-public: +- /// Type of this endpoint transport component +- typedef endpoint type; +- +- /// Type of the concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of the socket policy +- typedef typename config::socket_type socket_type; +- /// Type of the error logging policy +- typedef typename config::elog_type elog_type; +- /// Type of the access logging policy +- typedef typename config::alog_type alog_type; +- +- /// Type of the socket connection component +- typedef typename socket_type::socket_con_type socket_con_type; +- /// Type of a shared pointer to the socket connection component +- typedef typename socket_con_type::ptr socket_con_ptr; +- +- /// Type of the connection transport component associated with this +- /// endpoint transport component +- typedef asio::connection transport_con_type; +- /// Type of a shared pointer to the connection transport component +- /// associated with this endpoint transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- /// Type of a pointer to the ASIO io_service being used +- typedef lib::asio::io_service * io_service_ptr; +- /// Type of a shared pointer to the acceptor being used +- typedef lib::shared_ptr acceptor_ptr; +- /// Type of a shared pointer to the resolver being used +- typedef lib::shared_ptr resolver_ptr; +- /// Type of timer handle +- typedef lib::shared_ptr timer_ptr; +- /// Type of a shared pointer to an io_service work object +- typedef lib::shared_ptr work_ptr; +- +- /// Type of socket pre-bind handler +- typedef lib::function tcp_pre_bind_handler; +- +- // generate and manage our own io_service +- explicit endpoint() +- : m_io_service(NULL) +- , m_external_io_service(false) +- , m_listen_backlog(lib::asio::socket_base::max_connections) +- , m_reuse_addr(false) +- , m_state(UNINITIALIZED) +- { +- //std::cout << "transport::asio::endpoint constructor" << std::endl; +- } +- +- ~endpoint() { +- // clean up our io_service if we were initialized with an internal one. +- +- // Explicitly destroy local objects +- m_acceptor.reset(); +- m_resolver.reset(); +- m_work.reset(); +- if (m_state != UNINITIALIZED && !m_external_io_service) { +- delete m_io_service; +- } +- } +- +- /// transport::asio objects are moveable but not copyable or assignable. +- /// The following code sets this situation up based on whether or not we +- /// have C++11 support or not +-#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- endpoint(const endpoint & src) = delete; +- endpoint& operator= (const endpoint & rhs) = delete; +-#else +-private: +- endpoint(const endpoint & src); +- endpoint & operator= (const endpoint & rhs); +-public: +-#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_ +- +-#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ +- endpoint (endpoint && src) +- : config::socket_type(std::move(src)) +- , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler) +- , m_tcp_post_init_handler(src.m_tcp_post_init_handler) +- , m_io_service(src.m_io_service) +- , m_external_io_service(src.m_external_io_service) +- , m_acceptor(src.m_acceptor) +- , m_listen_backlog(lib::asio::socket_base::max_connections) +- , m_reuse_addr(src.m_reuse_addr) +- , m_elog(src.m_elog) +- , m_alog(src.m_alog) +- , m_state(src.m_state) +- { +- src.m_io_service = NULL; +- src.m_external_io_service = false; +- src.m_acceptor = NULL; +- src.m_state = UNINITIALIZED; +- } +- +- /*endpoint & operator= (const endpoint && rhs) { +- if (this != &rhs) { +- m_io_service = rhs.m_io_service; +- m_external_io_service = rhs.m_external_io_service; +- m_acceptor = rhs.m_acceptor; +- m_listen_backlog = rhs.m_listen_backlog; +- m_reuse_addr = rhs.m_reuse_addr; +- m_state = rhs.m_state; +- +- rhs.m_io_service = NULL; +- rhs.m_external_io_service = false; +- rhs.m_acceptor = NULL; +- rhs.m_listen_backlog = lib::asio::socket_base::max_connections; +- rhs.m_state = UNINITIALIZED; +- +- // TODO: this needs to be updated +- } +- return *this; +- }*/ +-#endif // _WEBSOCKETPP_MOVE_SEMANTICS_ +- +- /// Return whether or not the endpoint produces secure connections. +- bool is_secure() const { +- return socket_type::is_secure(); +- } +- +- /// initialize asio transport with external io_service (exception free) +- /** +- * Initialize the ASIO transport policy for this endpoint using the provided +- * io_service object. asio_init must be called exactly once on any endpoint +- * that uses transport::asio before it can be used. +- * +- * @param ptr A pointer to the io_service to use for asio events +- * @param ec Set to indicate what error occurred, if any. +- */ +- void init_asio(io_service_ptr ptr, lib::error_code & ec) { +- if (m_state != UNINITIALIZED) { +- m_elog->write(log::elevel::library, +- "asio::init_asio called from the wrong state"); +- using ws_websocketpp::error::make_error_code; +- ec = make_error_code(ws_websocketpp::error::invalid_state); +- return; +- } +- +- m_alog->write(log::alevel::devel,"asio::init_asio"); +- +- m_io_service = ptr; +- m_external_io_service = true; +- m_acceptor = lib::make_shared( +- lib::ref(*m_io_service)); +- +- m_state = READY; +- ec = lib::error_code(); +- } +- +- /// initialize asio transport with external io_service +- /** +- * Initialize the ASIO transport policy for this endpoint using the provided +- * io_service object. asio_init must be called exactly once on any endpoint +- * that uses transport::asio before it can be used. +- * +- * @param ptr A pointer to the io_service to use for asio events +- */ +- void init_asio(io_service_ptr ptr) { +- lib::error_code ec; +- init_asio(ptr,ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Initialize asio transport with internal io_service (exception free) +- /** +- * This method of initialization will allocate and use an internally managed +- * io_service. +- * +- * @see init_asio(io_service_ptr ptr) +- * +- * @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 +- // successfully been taken. Use unique_ptr when available. +- // TODO: remove the use of auto_ptr when C++98/03 support is no longer +- // necessary. +-#ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- lib::unique_ptr service(new lib::asio::io_service()); +-#else +- lib::auto_ptr service(new lib::asio::io_service()); +-#endif +- init_asio(service.get(), ec); +- if( !ec ) service.release(); // Call was successful, transfer ownership +- m_external_io_service = false; +- } +- +- /// Initialize asio transport with internal io_service +- /** +- * This method of initialization will allocate and use an internally managed +- * io_service. +- * +- * @see init_asio(io_service_ptr ptr) +- */ +- void init_asio() { +- // 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. +-#ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- lib::unique_ptr service(new lib::asio::io_service()); +-#else +- lib::auto_ptr service(new lib::asio::io_service()); +-#endif +- init_asio( service.get() ); +- // If control got this far without an exception, then ownership has successfully been taken +- service.release(); +- 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 +- * established but before any additional wrappers (proxy connects, TLS +- * handshakes, etc) have been performed. +- * +- * @since 0.3.0 +- * +- * @param h The handler to call on tcp pre init. +- */ +- void set_tcp_pre_init_handler(tcp_init_handler h) { +- m_tcp_pre_init_handler = h; +- } +- +- /// Sets the tcp pre init handler (deprecated) +- /** +- * The tcp pre init handler is called after the raw tcp connection has been +- * established but before any additional wrappers (proxy connects, TLS +- * handshakes, etc) have been performed. +- * +- * @deprecated Use set_tcp_pre_init_handler instead +- * +- * @param h The handler to call on tcp pre init. +- */ +- void set_tcp_init_handler(tcp_init_handler h) { +- set_tcp_pre_init_handler(h); +- } +- +- /// Sets the tcp post init handler +- /** +- * The tcp post init handler is called after the tcp connection has been +- * established and all additional wrappers (proxy connects, TLS handshakes, +- * etc have been performed. This is fired before any bytes are read or any +- * WebSocket specific handshake logic has been performed. +- * +- * @since 0.3.0 +- * +- * @param h The handler to call on tcp post init. +- */ +- void set_tcp_post_init_handler(tcp_init_handler h) { +- m_tcp_post_init_handler = h; +- } +- +- /// Sets the maximum length of the queue of pending connections. +- /** +- * Sets the maximum length of the queue of pending connections. Increasing +- * this will allow WebSocket++ to queue additional incoming connections. +- * Setting it higher may prevent failed connections at high connection rates +- * but may cause additional latency. +- * +- * For this value to take effect you may need to adjust operating system +- * settings. +- * +- * New values affect future calls to listen only. +- * +- * 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 +- * +- * @param backlog The maximum length of the queue of pending connections +- */ +- void set_listen_backlog(int backlog) { +- m_listen_backlog = backlog; +- } +- +- /// 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. 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. +- * +- * @since 0.3.0 +- * +- * @param value Whether or not to use the SO_REUSEADDR option +- */ +- void set_reuse_addr(bool value) { +- m_reuse_addr = value; +- } +- +- /// Retrieve a reference to the endpoint's io_service +- /** +- * The io_service may be an internal or external one. This may be used to +- * call methods of the io_service that are not explicitly wrapped by the +- * endpoint. +- * +- * This method is only valid after the endpoint has been initialized with +- * `init_asio`. No error will be returned if it isn't. +- * +- * @return A reference to the endpoint's io_service +- */ +- 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 +- * address that WebSocket++ is listening on. +- * +- * 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. +- * @return The local endpoint +- */ +- lib::asio::ip::tcp::endpoint get_local_endpoint(lib::asio::error_code & ec) { +- if (m_acceptor) { +- return m_acceptor->local_endpoint(ec); +- } else { +- ec = lib::asio::error::make_error_code(lib::asio::error::bad_descriptor); +- return lib::asio::ip::tcp::endpoint(); +- } +- } +- +- /// Set up endpoint for listening manually (exception free) +- /** +- * Bind the internal acceptor using the specified settings. The endpoint +- * must have been initialized by calling init_asio before listening. +- * +- * @param ep An endpoint to read settings from +- * @param ec Set to indicate what error occurred, if any. +- */ +- void listen(lib::asio::ip::tcp::endpoint const & ep, lib::error_code & ec) +- { +- if (m_state != READY) { +- m_elog->write(log::elevel::library, +- "asio::listen called from the wrong state"); +- using ws_websocketpp::error::make_error_code; +- ec = make_error_code(ws_websocketpp::error::invalid_state); +- return; +- } +- +- m_alog->write(log::alevel::devel,"asio::listen"); +- +- lib::asio::error_code bec; +- +- m_acceptor->open(ep.protocol(),bec); +- 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; +- } +- } +- +- 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 +- * +- * @param ep An endpoint to read settings from +- */ +- void listen(lib::asio::ip::tcp::endpoint const & ep) { +- lib::error_code ec; +- listen(ep,ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Set up endpoint for listening with protocol and port (exception free) +- /** +- * Bind the internal acceptor using the given internet protocol and port. +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * Common options include: +- * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6() +- * - IPv4 only: lib::asio::ip::tcp::v4() +- * +- * @param internet_protocol The internet protocol to use. +- * @param port The port to listen on. +- * @param ec Set to indicate what error occurred, if any. +- */ +- template +- void listen(InternetProtocol const & internet_protocol, uint16_t port, +- lib::error_code & ec) +- { +- lib::asio::ip::tcp::endpoint ep(internet_protocol, port); +- listen(ep,ec); +- } +- +- /// Set up endpoint for listening with protocol and port +- /** +- * Bind the internal acceptor using the given internet protocol and port. +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * Common options include: +- * - IPv6 with mapped IPv4 for dual stack hosts lib::asio::ip::tcp::v6() +- * - IPv4 only: lib::asio::ip::tcp::v4() +- * +- * @param internet_protocol The internet protocol to use. +- * @param port The port to listen on. +- */ +- template +- void listen(InternetProtocol const & internet_protocol, uint16_t port) +- { +- lib::asio::ip::tcp::endpoint ep(internet_protocol, port); +- listen(ep); +- } +- +- /// Set up endpoint for listening on a port (exception free) +- /** +- * Bind the internal acceptor using the given port. The IPv6 protocol with +- * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use +- * the overload that allows specifying the protocol explicitly. +- * +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * @param port The port to listen on. +- * @param ec Set to indicate what error occurred, if any. +- */ +- void listen(uint16_t port, lib::error_code & ec) { +- listen(lib::asio::ip::tcp::v6(), port, ec); +- } +- +- /// Set up endpoint for listening on a port +- /** +- * Bind the internal acceptor using the given port. The IPv6 protocol with +- * mapped IPv4 for dual stack hosts will be used. If you need IPv4 only use +- * the overload that allows specifying the protocol explicitly. +- * +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * @param port The port to listen on. +- * @param ec Set to indicate what error occurred, if any. +- */ +- void listen(uint16_t port) { +- listen(lib::asio::ip::tcp::v6(), port); +- } +- +- /// Set up endpoint for listening on a host and service (exception free) +- /** +- * Bind the internal acceptor using the given host and service. More details +- * about what host and service can be are available in the Asio +- * documentation for ip::basic_resolver_query::basic_resolver_query's +- * constructors. +- * +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * @param host A string identifying a location. May be a descriptive name or +- * a numeric address string. +- * @param service A string identifying the requested service. This may be a +- * descriptive name or a numeric string corresponding to a port number. +- * @param ec Set to indicate what error occurred, if any. +- */ +- void listen(std::string const & host, std::string const & service, +- lib::error_code & ec) +- { +- using lib::asio::ip::tcp; +- tcp::resolver r(*m_io_service); +- tcp::resolver::query query(host, service); +- tcp::resolver::iterator endpoint_iterator = r.resolve(query); +- tcp::resolver::iterator end; +- if (endpoint_iterator == end) { +- m_elog->write(log::elevel::library, +- "asio::listen could not resolve the supplied host or service"); +- ec = make_error_code(error::invalid_host_service); +- return; +- } +- listen(*endpoint_iterator,ec); +- } +- +- /// Set up endpoint for listening on a host and service +- /** +- * Bind the internal acceptor using the given host and service. More details +- * about what host and service can be are available in the Asio +- * documentation for ip::basic_resolver_query::basic_resolver_query's +- * constructors. +- * +- * The endpoint must have been initialized by calling init_asio before +- * listening. +- * +- * @param host A string identifying a location. May be a descriptive name or +- * a numeric address string. +- * @param service A string identifying the requested service. This may be a +- * descriptive name or a numeric string corresponding to a port number. +- * @param ec Set to indicate what error occurred, if any. +- */ +- void listen(std::string const & host, std::string const & service) +- { +- lib::error_code ec; +- listen(host,service,ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Stop listening (exception free) +- /** +- * Stop listening and accepting new connections. This will not end any +- * existing connections. +- * +- * @since 0.3.0-alpha4 +- * @param ec A status code indicating an error, if any. +- */ +- void stop_listening(lib::error_code & ec) { +- if (m_state != LISTENING) { +- m_elog->write(log::elevel::library, +- "asio::listen called from the wrong state"); +- using ws_websocketpp::error::make_error_code; +- ec = make_error_code(ws_websocketpp::error::invalid_state); +- return; +- } +- +- m_acceptor->close(); +- m_state = READY; +- ec = lib::error_code(); +- } +- +- /// Stop listening +- /** +- * Stop listening and accepting new connections. This will not end any +- * existing connections. +- * +- * @since 0.3.0-alpha4 +- */ +- void stop_listening() { +- lib::error_code ec; +- stop_listening(ec); +- if (ec) { throw exception(ec); } +- } +- +- /// Check if the endpoint is listening +- /** +- * @return Whether or not the endpoint is listening. +- */ +- bool is_listening() const { +- return (m_state == LISTENING); +- } +- +- /// wraps the run method of the internal io_service object +- std::size_t run() { +- return m_io_service->run(); +- } +- +- /// wraps the run_one method of the internal io_service object +- /** +- * @since 0.3.0-alpha4 +- */ +- std::size_t run_one() { +- return m_io_service->run_one(); +- } +- +- /// wraps the stop method of the internal io_service object +- void stop() { +- m_io_service->stop(); +- } +- +- /// wraps the poll method of the internal io_service object +- std::size_t poll() { +- return m_io_service->poll(); +- } +- +- /// wraps the poll_one method of the internal io_service object +- std::size_t poll_one() { +- return m_io_service->poll_one(); +- } +- +- /// wraps the reset method of the internal io_service object +- void reset() { +- m_io_service->reset(); +- } +- +- /// wraps the stopped method of the internal io_service object +- bool stopped() const { +- return m_io_service->stopped(); +- } +- +- /// Marks the endpoint as perpetual, stopping it from exiting when empty +- /** +- * Marks the endpoint as perpetual. Perpetual endpoints will not +- * automatically exit when they run out of connections to process. To stop +- * a perpetual endpoint call `end_perpetual`. +- * +- * An endpoint may be marked perpetual at any time by any thread. It must be +- * called either before the endpoint has run out of work or before it was +- * started +- * +- * @since 0.3.0 +- */ +- void start_perpetual() { +- m_work = lib::make_shared( +- lib::ref(*m_io_service) +- ); +- } +- +- /// Clears the endpoint's perpetual flag, allowing it to exit when empty +- /** +- * Clears the endpoint's perpetual flag. This will cause the endpoint's run +- * method to exit normally when it runs out of connections. If there are +- * currently active connections it will not end until they are complete. +- * +- * @since 0.3.0 +- */ +- void stop_perpetual() { +- m_work.reset(); +- } +- +- /// Call back a function after a period of time. +- /** +- * Sets a timer that calls back a function after the specified period of +- * milliseconds. Returns a handle that can be used to cancel the timer. +- * A cancelled timer will return the error code error::operation_aborted +- * A timer that expired will return no error. +- * +- * @param duration Length of time to wait in milliseconds +- * @param callback The function to call back when the timer has expired +- * @return A handle that can be used to cancel the timer if it is no longer +- * needed. +- */ +- timer_ptr set_timer(long duration, timer_handler callback) { +- timer_ptr new_timer = lib::make_shared( +- *m_io_service, +- lib::asio::milliseconds(duration) +- ); +- +- new_timer->async_wait( +- lib::bind( +- &type::handle_timer, +- this, +- new_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- +- return new_timer; +- } +- +- /// Timer handler +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * @param t Pointer to the timer in question +- * @param callback The function to call back +- * @param ec A status code indicating an error, if any. +- */ +- void handle_timer(timer_ptr, timer_handler callback, +- lib::asio::error_code const & ec) +- { +- if (ec) { +- if (ec == lib::asio::error::operation_aborted) { +- callback(make_error_code(transport::error::operation_aborted)); +- } else { +- m_elog->write(log::elevel::info, +- "asio handle_timer error: "+ec.message()); +- log_err(log::elevel::info,"asio handle_timer",ec); +- callback(socket_con_type::translate_ec(ec)); +- } +- } else { +- callback(lib::error_code()); +- } +- } +- +- /// Accept the next connection attempt and assign it to con (exception free) +- /** +- * @param tcon The connection to accept into. +- * @param callback The function to call when the operation is complete. +- * @param ec A status code indicating an error, if any. +- */ +- void async_accept(transport_con_ptr tcon, accept_handler callback, +- lib::error_code & ec) +- { +- if (m_state != LISTENING || !m_acceptor) { +- using ws_websocketpp::error::make_error_code; +- ec = make_error_code(ws_websocketpp::error::async_accept_not_listening); +- return; +- } +- +- m_alog->write(log::alevel::devel, "asio::async_accept"); +- +- if (config::enable_multithreading) { +- m_acceptor->async_accept( +- tcon->get_raw_socket(), +- tcon->get_strand()->wrap(lib::bind( +- &type::handle_accept, +- this, +- callback, +- lib::placeholders::_1 +- )) +- ); +- } else { +- m_acceptor->async_accept( +- tcon->get_raw_socket(), +- lib::bind( +- &type::handle_accept, +- this, +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- } +- +- /// Accept the next connection attempt and assign it to con. +- /** +- * @param tcon The connection to accept into. +- * @param callback The function to call when the operation is complete. +- */ +- void async_accept(transport_con_ptr tcon, accept_handler callback) { +- lib::error_code ec; +- async_accept(tcon,callback,ec); +- if (ec) { throw exception(ec); } +- } +-protected: +- /// Initialize logging +- /** +- * The loggers are located in the main endpoint class. As such, the +- * transport doesn't have direct access to them. This method is called +- * by the endpoint constructor to allow shared logging from the transport +- * component. These are raw pointers to member variables of the endpoint. +- * In particular, they cannot be used in the transport constructor as they +- * haven't been constructed yet, and cannot be used in the transport +- * destructor as they will have been destroyed by then. +- */ +- void init_logging(const lib::shared_ptr& a, const lib::shared_ptr& e) { +- m_alog = a; +- m_elog = e; +- } +- +- void handle_accept(accept_handler callback, lib::asio::error_code const & +- asio_ec) +- { +- lib::error_code ret_ec; +- +- m_alog->write(log::alevel::devel, "asio::handle_accept"); +- +- if (asio_ec) { +- if (_workaround_gcc_libstdcpp_issue_68307_missing_values::is_op_canceled(asio_ec)) { +- ret_ec = make_error_code(ws_websocketpp::error::operation_canceled); +- } else { +- log_err(log::elevel::info,"asio handle_accept",asio_ec); +- ret_ec = socket_con_type::translate_ec(asio_ec); +- } +- } +- +- callback(ret_ec); +- } +- +- /// Initiate a new connection +- // TODO: there have to be some more failure conditions here +- void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) { +- using namespace lib::asio::ip; +- +- // Create a resolver +- if (!m_resolver) { +- m_resolver = lib::make_shared( +- lib::ref(*m_io_service)); +- } +- +- tcon->set_uri(u); +- +- std::string proxy = tcon->get_proxy(); +- std::string host; +- std::string port; +- +- if (proxy.empty()) { +- host = u->get_host(); +- port = u->get_port_str(); +- } else { +- lib::error_code ec; +- +- uri_ptr pu = lib::make_shared(proxy); +- +- if (!pu->get_valid()) { +- cb(make_error_code(error::proxy_invalid)); +- return; +- } +- +- ec = tcon->proxy_init(u->get_authority()); +- if (ec) { +- cb(ec); +- return; +- } +- +- host = pu->get_host(); +- port = pu->get_port_str(); +- } +- +- tcp::resolver::query query(host,port); +- +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel, +- "starting async DNS resolve for "+host+":"+port); +- } +- +- timer_ptr dns_timer; +- +- dns_timer = tcon->set_timer( +- config::timeout_dns_resolve, +- lib::bind( +- &type::handle_resolve_timeout, +- this, +- dns_timer, +- cb, +- lib::placeholders::_1 +- ) +- ); +- +- if (config::enable_multithreading) { +- m_resolver->async_resolve( +- query, +- tcon->get_strand()->wrap(lib::bind( +- &type::handle_resolve, +- this, +- tcon, +- dns_timer, +- cb, +- lib::placeholders::_1, +- lib::placeholders::_2 +- )) +- ); +- } else { +- m_resolver->async_resolve( +- query, +- lib::bind( +- &type::handle_resolve, +- this, +- tcon, +- dns_timer, +- cb, +- lib::placeholders::_1, +- lib::placeholders::_2 +- ) +- ); +- } +- } +- +- /// DNS resolution timeout handler +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * @param dns_timer Pointer to the timer in question +- * @param callback The function to call back +- * @param ec A status code indicating an error, if any. +- */ +- void handle_resolve_timeout(timer_ptr, connect_handler callback, +- lib::error_code const & ec) +- { +- lib::error_code ret_ec; +- +- if (ec) { +- if (ec == transport::error::operation_aborted) { +- m_alog->write(log::alevel::devel, +- "asio handle_resolve_timeout timer cancelled"); +- return; +- } +- +- log_err(log::elevel::devel,"asio handle_resolve_timeout",ec); +- ret_ec = ec; +- } else { +- ret_ec = make_error_code(transport::error::timeout); +- } +- +- m_alog->write(log::alevel::devel,"DNS resolution timed out"); +- m_resolver->cancel(); +- callback(ret_ec); +- } +- +- void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, +- connect_handler callback, lib::asio::error_code const & ec, +- lib::asio::ip::tcp::resolver::iterator iterator) +- { +- if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(dns_timer->expires_from_now())) +- { +- m_alog->write(log::alevel::devel,"async_resolve cancelled"); +- return; +- } +- +- dns_timer->cancel(); +- +- if (ec) { +- log_err(log::elevel::info,"asio async_resolve",ec); +- callback(socket_con_type::translate_ec(ec)); +- return; +- } +- +- if (m_alog->static_test(log::alevel::devel)) { +- std::stringstream s; +- s << "Async DNS resolve successful. Results: "; +- +- lib::asio::ip::tcp::resolver::iterator it, end; +- for (it = iterator; it != end; ++it) { +- s << (*it).endpoint() << " "; +- } +- +- m_alog->write(log::alevel::devel,s.str()); +- } +- +- m_alog->write(log::alevel::devel,"Starting async connect"); +- +- timer_ptr con_timer; +- +- con_timer = tcon->set_timer( +- config::timeout_connect, +- lib::bind( +- &type::handle_connect_timeout, +- this, +- tcon, +- con_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- +- if (config::enable_multithreading) { +- lib::asio::async_connect( +- tcon->get_raw_socket(), +- iterator, +- tcon->get_strand()->wrap(lib::bind( +- &type::handle_connect, +- this, +- tcon, +- con_timer, +- callback, +- lib::placeholders::_1 +- )) +- ); +- } else { +- lib::asio::async_connect( +- tcon->get_raw_socket(), +- iterator, +- lib::bind( +- &type::handle_connect, +- this, +- tcon, +- con_timer, +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- } +- +- /// Asio connect timeout handler +- /** +- * The timer pointer is included to ensure the timer isn't destroyed until +- * after it has expired. +- * +- * @param tcon Pointer to the transport connection that is being connected +- * @param con_timer Pointer to the timer in question +- * @param callback The function to call back +- * @param ec A status code indicating an error, if any. +- */ +- void handle_connect_timeout(transport_con_ptr tcon, timer_ptr, +- connect_handler callback, lib::error_code const & ec) +- { +- lib::error_code ret_ec; +- +- if (ec) { +- if (ec == transport::error::operation_aborted) { +- m_alog->write(log::alevel::devel, +- "asio handle_connect_timeout timer cancelled"); +- return; +- } +- +- log_err(log::elevel::devel,"asio handle_connect_timeout",ec); +- ret_ec = ec; +- } else { +- ret_ec = make_error_code(transport::error::timeout); +- } +- +- m_alog->write(log::alevel::devel,"TCP connect timed out"); +- tcon->cancel_socket_checked(); +- callback(ret_ec); +- } +- +- void handle_connect(transport_con_ptr tcon, timer_ptr con_timer, +- connect_handler callback, lib::asio::error_code const & ec) +- { +- if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(con_timer->expires_from_now())) +- { +- m_alog->write(log::alevel::devel,"async_connect cancelled"); +- return; +- } +- +- con_timer->cancel(); +- +- if (ec) { +- log_err(log::elevel::info,"asio async_connect",ec); +- callback(socket_con_type::translate_ec(ec)); +- return; +- } +- +- if (m_alog->static_test(log::alevel::devel)) { +- m_alog->write(log::alevel::devel, +- "Async connect to "+tcon->get_remote_endpoint()+" successful."); +- } +- +- callback(lib::error_code()); +- } +- +- /// Initialize a connection +- /** +- * init is called by an endpoint once for each newly created connection. +- * It's purpose is to give the transport policy the chance to perform any +- * transport specific initialization that couldn't be done via the default +- * constructor. +- * +- * @param tcon A pointer to the transport portion of the connection. +- * +- * @return A status code indicating the success or failure of the operation +- */ +- lib::error_code init(transport_con_ptr tcon) { +- m_alog->write(log::alevel::devel, "transport::asio::init"); +- +- // Initialize the connection socket component +- socket_type::init(lib::static_pointer_cast(tcon)); +- +- lib::error_code ec; +- +- ec = tcon->init_asio(m_io_service); +- if (ec) {return ec;} +- +- tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler); +- tcon->set_tcp_post_init_handler(m_tcp_post_init_handler); +- +- return lib::error_code(); +- } +-private: +- /// Convenience method for logging the code and message for an error_code +- template +- 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()); +- } +- +- /// Helper for cleaning up in the listen method after an error +- template +- lib::error_code clean_up_listen_after_error(error_type const & ec) { +- if (m_acceptor->is_open()) { +- m_acceptor->close(); +- } +- log_err(log::elevel::info,"asio listen",ec); +- return socket_con_type::translate_ec(ec); +- } +- +- enum state { +- UNINITIALIZED = 0, +- READY = 1, +- LISTENING = 2 +- }; +- +- // 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; +- +- // Network Resources +- io_service_ptr m_io_service; +- bool m_external_io_service; +- acceptor_ptr m_acceptor; +- resolver_ptr m_resolver; +- work_ptr m_work; +- +- // Network constants +- int m_listen_backlog; +- bool m_reuse_addr; +- +- lib::shared_ptr m_elog; +- lib::shared_ptr m_alog; +- +- // Transport state +- state m_state; +-}; +- +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_ASIO_HPP +diff --git a/src/lib/websocketpp/transport/asio/security/base.hpp b/src/lib/websocketpp/transport/asio/security/base.hpp +deleted file mode 100644 +index cb0ca9d..0000000 +--- a/src/lib/websocketpp/transport/asio/security/base.hpp ++++ /dev/null +@@ -1,159 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-// Interface that sockets/security policies must implement +- +-/* +- * Endpoint Interface +- * +- * bool is_secure() const; +- * @return Whether or not the endpoint creates secure connections +- * +- * lib::error_code init(socket_con_ptr scon); +- * Called by the transport after a new connection is created to initialize +- * the socket component of the connection. +- * @param scon Pointer to the socket component of the connection +- * @return Error code (empty on success) +- */ +- +- +-// Connection +-// TODO +-// set_hostname(std::string hostname) +-// pre_init(init_handler); +-// post_init(init_handler); +- +-namespace ws_websocketpp { +-namespace transport { +-namespace asio { +-namespace socket { +- +-typedef lib::function shutdown_handler; +- +-/** +- * The transport::asio::socket::* classes are a set of security/socket related +- * policies and support code for the ASIO transport types. +- */ +- +-/// Errors related to asio transport sockets +-namespace error { +- enum value { +- /// Catch-all error for security policy errors that don't fit in other +- /// categories +- security = 1, +- +- /// Catch-all error for socket component errors that don't fit in other +- /// categories +- socket, +- +- /// A function was called in a state that it was illegal to do so. +- invalid_state, +- +- /// The application was prompted to provide a TLS context and it was +- /// empty or otherwise invalid +- invalid_tls_context, +- +- /// TLS Handshake Timeout +- tls_handshake_timeout, +- +- /// pass_through from underlying library +- pass_through, +- +- /// Required tls_init handler not present +- missing_tls_init_handler, +- +- /// TLS Handshake Failed +- tls_handshake_failed, +- +- /// Failed to set TLS SNI hostname +- tls_failed_sni_hostname +- }; +-} // namespace error +- +-/// Error category related to asio transport socket policies +-class socket_category : public lib::error_category { +-public: +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport.asio.socket"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case error::security: +- return "Security policy error"; +- case error::socket: +- return "Socket component error"; +- case error::invalid_state: +- return "Invalid state"; +- case error::invalid_tls_context: +- return "Invalid or empty TLS context supplied"; +- case error::tls_handshake_timeout: +- return "TLS handshake timed out"; +- case error::pass_through: +- return "Pass through from socket policy"; +- case error::missing_tls_init_handler: +- return "Required tls_init handler not present."; +- case error::tls_handshake_failed: +- return "TLS handshake failed"; +- case error::tls_failed_sni_hostname: +- return "Failed to set TLS SNI hostname"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-inline lib::error_category const & get_socket_category() { +- static socket_category instance; +- return instance; +-} +- +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_socket_category()); +-} +- +-/// Type of asio transport socket policy initialization handlers +-typedef lib::function init_handler; +- +-} // namespace socket +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_ASIO_SOCKET_BASE_HPP +diff --git a/src/lib/websocketpp/transport/asio/security/none.hpp b/src/lib/websocketpp/transport/asio/security/none.hpp +deleted file mode 100644 +index b780568..0000000 +--- a/src/lib/websocketpp/transport/asio/security/none.hpp ++++ /dev/null +@@ -1,373 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_SECURITY_NONE_HPP +-#define WEBSOCKETPP_TRANSPORT_SECURITY_NONE_HPP +- +-#include +- +-#include +-#include +- +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace asio { +-/// A socket policy for the asio transport that implements a plain, unencrypted +-/// socket +-namespace basic_socket { +- +-/// The signature of the socket init handler for this socket policy +-typedef lib::function +- socket_init_handler; +- +-/// Basic Asio connection socket component +-/** +- * transport::asio::basic_socket::connection implements a connection socket +- * component using Asio ip::tcp::socket. +- */ +-class connection : public lib::enable_shared_from_this { +-public: +- /// Type of this connection socket component +- typedef connection type; +- /// Type of a shared pointer to this connection socket component +- typedef lib::shared_ptr ptr; +- +- /// Type of a pointer to the Asio io_service being used +- typedef lib::asio::io_service* io_service_ptr; +- /// Type of a pointer to the Asio io_service strand being used +- typedef lib::shared_ptr strand_ptr; +- /// Type of the ASIO socket being used +- typedef lib::asio::ip::tcp::socket socket_type; +- /// Type of a shared pointer to the socket being used. +- typedef lib::shared_ptr socket_ptr; +- +- explicit connection() : m_state(UNINITIALIZED) { +- //std::cout << "transport::asio::basic_socket::connection constructor" +- // << std::endl; +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return shared_from_this(); +- } +- +- /// Check whether or not this connection is secure +- /** +- * @return Whether or not this connection is secure +- */ +- bool is_secure() const { +- return false; +- } +- +- /// Set the socket initialization handler +- /** +- * The socket initialization handler is called after the socket object is +- * created but before it is used. This gives the application a chance to +- * set any Asio socket options it needs. +- * +- * @param h The new socket_init_handler +- */ +- void set_socket_init_handler(socket_init_handler h) { +- m_socket_init_handler = h; +- } +- +- /// Retrieve a pointer to the underlying socket +- /** +- * This is used internally. It can also be used to set socket options, etc +- */ +- lib::asio::ip::tcp::socket & get_socket() { +- return *m_socket; +- } +- +- /// Retrieve a pointer to the underlying socket +- /** +- * This is used internally. +- */ +- lib::asio::ip::tcp::socket & get_next_layer() { +- return *m_socket; +- } +- +- /// Retrieve a pointer to the underlying socket +- /** +- * This is used internally. It can also be used to set socket options, etc +- */ +- lib::asio::ip::tcp::socket & get_raw_socket() { +- return *m_socket; +- } +- +- /// Get the remote endpoint address +- /** +- * The iostream transport has no information about the ultimate remote +- * endpoint. It will return the string "iostream transport". To indicate +- * this. +- * +- * TODO: allow user settable remote endpoint addresses if this seems useful +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint(lib::error_code & ec) const { +- std::stringstream s; +- +- lib::asio::error_code aec; +- lib::asio::ip::tcp::endpoint ep = m_socket->remote_endpoint(aec); +- +- if (aec) { +- ec = error::make_error_code(error::pass_through); +- s << "Error getting remote endpoint: " << aec +- << " (" << aec.message() << ")"; +- return s.str(); +- } else { +- ec = lib::error_code(); +- s << ep; +- return s.str(); +- } +- } +-protected: +- /// Perform one time initializations +- /** +- * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service +- * +- * @param service A pointer to the endpoint's io_service +- * @param strand A shared pointer to the connection's asio strand +- * @param is_server Whether or not the endpoint is a server or not. +- */ +- lib::error_code init_asio (io_service_ptr service, strand_ptr, bool) +- { +- if (m_state != UNINITIALIZED) { +- return socket::make_error_code(socket::error::invalid_state); +- } +- +- m_socket = lib::make_shared( +- lib::ref(*service)); +- +- if (m_socket_init_handler) { +- m_socket_init_handler(m_hdl, *m_socket); +- } +- +- m_state = READY; +- +- return lib::error_code(); +- } +- +- /// Set uri hook +- /** +- * Called by the transport as a connection is being established to provide +- * the uri being connected to to the security/socket layer. +- * +- * This socket policy doesn't use the uri so it is ignored. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr) {} +- +- /// Pre-initialize security policy +- /** +- * Called by the transport after a new connection is created to initialize +- * the socket component of the connection. This method is not allowed to +- * write any bytes to the wire. This initialization happens before any +- * proxies or other intermediate wrappers are negotiated. +- * +- * @param callback Handler to call back with completion information +- */ +- void pre_init(init_handler callback) { +- if (m_state != READY) { +- callback(socket::make_error_code(socket::error::invalid_state)); +- return; +- } +- +- m_state = READING; +- +- callback(lib::error_code()); +- } +- +- /// Post-initialize security policy +- /** +- * Called by the transport after all intermediate proxies have been +- * negotiated. This gives the security policy the chance to talk with the +- * real remote endpoint for a bit before the websocket handshake. +- * +- * @param callback Handler to call back with completion information +- */ +- void post_init(init_handler callback) { +- callback(lib::error_code()); +- } +- +- /// Sets the connection handle +- /** +- * The connection handle is passed to any handlers to identify the +- * connection +- * +- * @param hdl The new handle +- */ +- void set_handle(connection_hdl hdl) { +- m_hdl = hdl; +- } +- +- /// Cancel all async operations on this socket +- /** +- * Attempts to cancel all async operations on this socket and reports any +- * failures. +- * +- * NOTE: Windows XP and earlier do not support socket cancellation. +- * +- * @return The error that occurred, if any. +- */ +- lib::asio::error_code cancel_socket() { +- lib::asio::error_code ec; +- m_socket->cancel(ec); +- return ec; +- } +- +- void async_shutdown(socket::shutdown_handler h) { +- lib::asio::error_code ec; +- m_socket->shutdown(lib::asio::ip::tcp::socket::shutdown_both, ec); +- h(ec); +- } +- +- lib::error_code get_ec() const { +- 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 +- * 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 +- * any additional information so all such errors will be reported as the +- * generic transport pass_through error. +- * +- * @since 0.3.0 +- * +- * @param ec The error code to translate_ec +- * @return The translated error code +- */ +- template +- static +- lib::error_code translate_ec(ErrorCodeType) { +- // We don't know any more information about this error so pass through +- return make_error_code(transport::error::pass_through); +- } +- +- 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 +- // the same type as the one we are translating to, so pass through +- // untranslated. +- return ec; +- } +-private: +- enum state { +- UNINITIALIZED = 0, +- READY = 1, +- READING = 2 +- }; +- +- socket_ptr m_socket; +- state m_state; +- +- connection_hdl m_hdl; +- socket_init_handler m_socket_init_handler; +-}; +- +-/// Basic ASIO endpoint socket component +-/** +- * transport::asio::basic_socket::endpoint implements an endpoint socket +- * component that uses Boost ASIO's ip::tcp::socket. +- */ +-class endpoint { +-public: +- /// The type of this endpoint socket component +- typedef endpoint type; +- +- /// The type of the corresponding connection socket component +- typedef connection socket_con_type; +- /// The type of a shared pointer to the corresponding connection socket +- /// component. +- typedef socket_con_type::ptr socket_con_ptr; +- +- explicit endpoint() {} +- +- /// Checks whether the endpoint creates secure connections +- /** +- * @return Whether or not the endpoint creates secure connections +- */ +- bool is_secure() const { +- return false; +- } +- +- /// Set socket init handler +- /** +- * The socket init handler is called after a connection's socket is created +- * but before it is used. This gives the end application an opportunity to +- * set asio socket specific parameters. +- * +- * @param h The new socket_init_handler +- */ +- void set_socket_init_handler(socket_init_handler h) { +- m_socket_init_handler = h; +- } +-protected: +- /// Initialize a connection +- /** +- * Called by the transport after a new connection is created to initialize +- * the socket component of the connection. +- * +- * @param scon Pointer to the socket component of the connection +- * +- * @return Error code (empty on success) +- */ +- lib::error_code init(socket_con_ptr scon) { +- scon->set_socket_init_handler(m_socket_init_handler); +- return lib::error_code(); +- } +-private: +- socket_init_handler m_socket_init_handler; +-}; +- +-} // namespace basic_socket +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_SECURITY_NONE_HPP +diff --git a/src/lib/websocketpp/transport/asio/security/tls.hpp b/src/lib/websocketpp/transport/asio/security/tls.hpp +deleted file mode 100644 +index 5b3bf3b..0000000 +--- a/src/lib/websocketpp/transport/asio/security/tls.hpp ++++ /dev/null +@@ -1,475 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_SECURITY_TLS_HPP +-#define WEBSOCKETPP_TRANSPORT_SECURITY_TLS_HPP +- +-#include +- +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace asio { +-/// A socket policy for the asio transport that implements a TLS encrypted +-/// socket by wrapping with an asio::ssl::stream +-namespace tls_socket { +- +-/// The signature of the socket_init_handler for this socket policy +-typedef lib::function&)> socket_init_handler; +-/// The signature of the tls_init_handler for this socket policy +-typedef lib::function(connection_hdl)> +- tls_init_handler; +- +-/// TLS enabled Asio connection socket component +-/** +- * transport::asio::tls_socket::connection implements a secure connection socket +- * component that uses Asio's ssl::stream to wrap an ip::tcp::socket. +- */ +-class connection : public lib::enable_shared_from_this { +-public: +- /// Type of this connection socket component +- typedef connection type; +- /// Type of a shared pointer to this connection socket component +- typedef lib::shared_ptr ptr; +- +- /// Type of the ASIO socket being used +- typedef lib::asio::ssl::stream socket_type; +- /// Type of a shared pointer to the ASIO socket being used +- typedef lib::shared_ptr socket_ptr; +- /// Type of a pointer to the ASIO io_service being used +- typedef lib::asio::io_service * io_service_ptr; +- /// Type of a pointer to the ASIO io_service strand being used +- typedef lib::shared_ptr strand_ptr; +- /// Type of a shared pointer to the ASIO TLS context being used +- typedef lib::shared_ptr context_ptr; +- +- explicit connection() { +- //std::cout << "transport::asio::tls_socket::connection constructor" +- // << std::endl; +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return shared_from_this(); +- } +- +- /// Check whether or not this connection is secure +- /** +- * @return Whether or not this connection is secure +- */ +- bool is_secure() const { +- return true; +- } +- +- /// Retrieve a pointer to the underlying socket +- /** +- * This is used internally. It can also be used to set socket options, etc +- */ +- socket_type::lowest_layer_type & get_raw_socket() { +- return m_socket->lowest_layer(); +- } +- +- /// Retrieve a pointer to the layer below the ssl stream +- /** +- * This is used internally. +- */ +- socket_type::next_layer_type & get_next_layer() { +- return m_socket->next_layer(); +- } +- +- /// Retrieve a pointer to the wrapped socket +- /** +- * This is used internally. +- */ +- socket_type & get_socket() { +- return *m_socket; +- } +- +- /// Set the socket initialization handler +- /** +- * The socket initialization handler is called after the socket object is +- * created but before it is used. This gives the application a chance to +- * set any ASIO socket options it needs. +- * +- * @param h The new socket_init_handler +- */ +- void set_socket_init_handler(socket_init_handler h) { +- m_socket_init_handler = h; +- } +- +- /// Set TLS init handler +- /** +- * The tls init handler is called when needed to request a TLS context for +- * the library to use. A TLS init handler must be set and it must return a +- * valid TLS context in order for this endpoint to be able to initialize +- * TLS connections +- * +- * @param h The new tls_init_handler +- */ +- void set_tls_init_handler(tls_init_handler h) { +- m_tls_init_handler = h; +- } +- +- /// Get the remote endpoint address +- /** +- * The iostream transport has no information about the ultimate remote +- * endpoint. It will return the string "iostream transport". To indicate +- * this. +- * +- * TODO: allow user settable remote endpoint addresses if this seems useful +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint(lib::error_code & ec) const { +- std::stringstream s; +- +- lib::asio::error_code aec; +- lib::asio::ip::tcp::endpoint ep = m_socket->lowest_layer().remote_endpoint(aec); +- +- if (aec) { +- ec = error::make_error_code(error::pass_through); +- s << "Error getting remote endpoint: " << aec +- << " (" << aec.message() << ")"; +- return s.str(); +- } else { +- ec = lib::error_code(); +- s << ep; +- return s.str(); +- } +- } +-protected: +- /// Perform one time initializations +- /** +- * init_asio is called once immediately after construction to initialize +- * Asio components to the 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. +- */ +- lib::error_code init_asio (io_service_ptr service, strand_ptr strand, +- bool is_server) +- { +- if (!m_tls_init_handler) { +- return socket::make_error_code(socket::error::missing_tls_init_handler); +- } +- m_context = m_tls_init_handler(m_hdl); +- +- if (!m_context) { +- return socket::make_error_code(socket::error::invalid_tls_context); +- } +- m_socket = lib::make_shared( +- _WEBSOCKETPP_REF(*service),lib::ref(*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; +- +- return lib::error_code(); +- } +- +- /// Set hostname hook +- /** +- * Called by the transport as a connection is being established to provide +- * the hostname being connected to to the security/socket layer. +- * +- * This socket policy uses the hostname to set the appropriate TLS SNI +- * header. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr u) { +- m_uri = u; +- } +- +- /// Pre-initialize security policy +- /** +- * Called by the transport after a new connection is created to initialize +- * the socket component of the connection. This method is not allowed to +- * write any bytes to the wire. This initialization happens before any +- * proxies or other intermediate wrappers are negotiated. +- * +- * @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 +- // available in the version of OpenSSL being used? +- // TODO: consider case where host is an IP address +-#if OPENSSL_VERSION_NUMBER >= 0x90812f +- if (!m_is_server) { +- // For clients on systems with a suitable OpenSSL version, set the +- // TLS SNI hostname header so connecting to TLS servers using SNI +- // will work. +- long res = SSL_set_tlsext_host_name( +- get_socket().native_handle(), m_uri->get_host().c_str()); +- if (!(1 == res)) { +- callback(socket::make_error_code(socket::error::tls_failed_sni_hostname)); +- } +- } +-#endif +- +- callback(lib::error_code()); +- } +- +- /// Post-initialize security policy +- /** +- * Called by the transport after all intermediate proxies have been +- * negotiated. This gives the security policy the chance to talk with the +- * real remote endpoint for a bit before the websocket handshake. +- * +- * @param callback Handler to call back with completion information +- */ +- void post_init(init_handler callback) { +- m_ec = socket::make_error_code(socket::error::tls_handshake_timeout); +- +- // TLS handshake +- if (m_strand) { +- m_socket->async_handshake( +- get_handshake_type(), +- m_strand->wrap(lib::bind( +- &type::handle_init, get_shared(), +- callback, +- lib::placeholders::_1 +- )) +- ); +- } else { +- m_socket->async_handshake( +- get_handshake_type(), +- lib::bind( +- &type::handle_init, get_shared(), +- callback, +- lib::placeholders::_1 +- ) +- ); +- } +- } +- +- /// Sets the connection handle +- /** +- * The connection handle is passed to any handlers to identify the +- * connection +- * +- * @param hdl The new handle +- */ +- void set_handle(connection_hdl hdl) { +- m_hdl = hdl; +- } +- +- void handle_init(init_handler callback,lib::asio::error_code const & ec) { +- if (ec) { +- m_ec = socket::make_error_code(socket::error::tls_handshake_failed); +- } else { +- m_ec = lib::error_code(); +- } +- +- callback(m_ec); +- } +- +- lib::error_code get_ec() const { +- return m_ec; +- } +- +- /// Cancel all async operations on this socket +- /** +- * Attempts to cancel all async operations on this socket and reports any +- * failures. +- * +- * NOTE: Windows XP and earlier do not support socket cancellation. +- * +- * @return The error that occurred, if any. +- */ +- lib::asio::error_code cancel_socket() { +- lib::asio::error_code ec; +- get_raw_socket().cancel(ec); +- return ec; +- } +- +- void async_shutdown(socket::shutdown_handler callback) { +- if (m_strand) { +- m_socket->async_shutdown(m_strand->wrap(callback)); +- } else { +- m_socket->async_shutdown(callback); +- } +- } +- +-public: +- /// Translate any security policy specific information about an error code +- /** +- * 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. Any error that is determined to be +- * related to TLS but does not have a more specific websocketpp error code +- * is returned under the catch all error `tls_error`. Non-TLS related errors +- * are returned as the transport generic error `pass_through` +- * +- * @since 0.3.0 +- * +- * @param ec The error code to translate_ec +- * @return The translated error code +- */ +- template +- static +- lib::error_code translate_ec(ErrorCodeType ec) { +- if (ec.category() == lib::asio::error::get_ssl_category()) { +- // 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 +- return make_error_code(transport::error::pass_through); +- } +- } +- +- 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) { +- return ec; +- } +-private: +- socket_type::handshake_type get_handshake_type() { +- if (m_is_server) { +- return lib::asio::ssl::stream_base::server; +- } else { +- return lib::asio::ssl::stream_base::client; +- } +- } +- +- io_service_ptr m_io_service; +- strand_ptr m_strand; +- context_ptr m_context; +- socket_ptr m_socket; +- uri_ptr m_uri; +- bool m_is_server; +- +- lib::error_code m_ec; +- +- connection_hdl m_hdl; +- socket_init_handler m_socket_init_handler; +- tls_init_handler m_tls_init_handler; +-}; +- +-/// TLS enabled Asio endpoint socket component +-/** +- * transport::asio::tls_socket::endpoint implements a secure endpoint socket +- * component that uses Asio's ssl::stream to wrap an ip::tcp::socket. +- */ +-class endpoint { +-public: +- /// The type of this endpoint socket component +- typedef endpoint type; +- +- /// The type of the corresponding connection socket component +- typedef connection socket_con_type; +- /// The type of a shared pointer to the corresponding connection socket +- /// component. +- typedef socket_con_type::ptr socket_con_ptr; +- +- explicit endpoint() {} +- +- /// Checks whether the endpoint creates secure connections +- /** +- * @return Whether or not the endpoint creates secure connections +- */ +- bool is_secure() const { +- return true; +- } +- +- /// Set socket init handler +- /** +- * The socket init handler is called after a connection's socket is created +- * but before it is used. This gives the end application an opportunity to +- * set asio socket specific parameters. +- * +- * @param h The new socket_init_handler +- */ +- void set_socket_init_handler(socket_init_handler h) { +- m_socket_init_handler = h; +- } +- +- /// Set TLS init handler +- /** +- * The tls init handler is called when needed to request a TLS context for +- * the library to use. A TLS init handler must be set and it must return a +- * valid TLS context in order for this endpoint to be able to initialize +- * TLS connections +- * +- * @param h The new tls_init_handler +- */ +- void set_tls_init_handler(tls_init_handler h) { +- m_tls_init_handler = h; +- } +-protected: +- /// Initialize a connection +- /** +- * Called by the transport after a new connection is created to initialize +- * the socket component of the connection. +- * +- * @param scon Pointer to the socket component of the connection +- * +- * @return Error code (empty on success) +- */ +- lib::error_code init(socket_con_ptr scon) { +- scon->set_socket_init_handler(m_socket_init_handler); +- scon->set_tls_init_handler(m_tls_init_handler); +- return lib::error_code(); +- } +- +-private: +- socket_init_handler m_socket_init_handler; +- tls_init_handler m_tls_init_handler; +-}; +- +-} // namespace tls_socket +-} // namespace asio +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_SECURITY_TLS_HPP +diff --git a/src/lib/websocketpp/transport/base/connection.hpp b/src/lib/websocketpp/transport/base/connection.hpp +deleted file mode 100644 +index 6b83188..0000000 +--- a/src/lib/websocketpp/transport/base/connection.hpp ++++ /dev/null +@@ -1,238 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_BASE_CON_HPP +-#define WEBSOCKETPP_TRANSPORT_BASE_CON_HPP +- +-#include +-#include +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-/// Transport policies provide network connectivity and timers +-/** +- * ### Connection Interface +- * +- * Transport connection components needs to provide: +- * +- * **init**\n +- * `void init(init_handler handler)`\n +- * Called once shortly after construction to give the policy the chance to +- * perform one time initialization. When complete, the policy must call the +- * supplied `init_handler` to continue setup. The handler takes one argument +- * with the error code if any. If an error is returned here setup will fail and +- * the connection will be aborted or terminated. +- * +- * WebSocket++ will call init only once. The transport must call `handler` +- * exactly once. +- * +- * **async_read_at_least**\n +- * `void async_read_at_least(size_t num_bytes, char *buf, size_t len, +- * read_handler handler)`\n +- * start an async read for at least num_bytes and at most len +- * bytes into buf. Call handler when done with number of bytes read. +- * +- * WebSocket++ promises to have only one async_read_at_least in flight at a +- * time. The transport must promise to only call read_handler once per async +- * read. +- * +- * **async_write**\n +- * `void async_write(const char* buf, size_t len, write_handler handler)`\n +- * `void async_write(std::vector & bufs, write_handler handler)`\n +- * Start a write of all of the data in buf or bufs. In second case data is +- * written sequentially and in place without copying anything to a temporary +- * location. +- * +- * Websocket++ promises to have only one async_write in flight at a time. +- * The transport must promise to only call the write_handler once per async +- * write +- * +- * **set_handle**\n +- * `void set_handle(connection_hdl hdl)`\n +- * Called by WebSocket++ to let this policy know the hdl to the connection. It +- * may be stored for later use or ignored/discarded. This handle should be used +- * if the policy adds any connection handlers. Connection handlers must be +- * called with the handle as the first argument so that the handler code knows +- * which connection generated the callback. +- * +- * **set_timer**\n +- * `timer_ptr set_timer(long duration, timer_handler handler)`\n +- * WebSocket++ uses the timers provided by the transport policy as the +- * implementation of timers is often highly coupled with the implementation of +- * the networking event loops. +- * +- * Transport timer support is an optional feature. A transport method may elect +- * to implement a dummy timer object and have this method return an empty +- * pointer. If so, all timer related features of WebSocket++ core will be +- * disabled. This includes many security features designed to prevent denial of +- * service attacks. Use timer-free transport policies with caution. +- * +- * **get_remote_endpoint**\n +- * `std::string get_remote_endpoint()`\n +- * retrieve address of remote endpoint +- * +- * **is_secure**\n +- * `void is_secure()`\n +- * whether or not the connection to the remote endpoint is secure +- * +- * **dispatch**\n +- * `lib::error_code dispatch(dispatch_handler handler)`: invoke handler within +- * the transport's event system if it uses one. Otherwise, this method should +- * simply call `handler` immediately. +- * +- * **async_shutdown**\n +- * `void async_shutdown(shutdown_handler handler)`\n +- * Perform any cleanup necessary (if any). Call `handler` when complete. +- */ +-namespace transport { +- +-/// The type and signature of the callback passed to the init hook +-typedef lib::function init_handler; +- +-/// The type and signature of the callback passed to the read method +-typedef lib::function read_handler; +- +-/// The type and signature of the callback passed to the write method +-typedef lib::function write_handler; +- +-/// The type and signature of the callback passed to the read method +-typedef lib::function timer_handler; +- +-/// The type and signature of the callback passed to the shutdown method +-typedef lib::function shutdown_handler; +- +-/// The type and signature of the callback passed to the interrupt method +-typedef lib::function interrupt_handler; +- +-/// The type and signature of the callback passed to the dispatch method +-typedef lib::function dispatch_handler; +- +-/// A simple utility buffer class +-struct buffer { +- buffer(char const * b, size_t l) : buf(b),len(l) {} +- +- char const * buf; +- size_t len; +-}; +- +-/// Generic transport related errors +-namespace error { +-enum value { +- /// Catch-all error for transport policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// underlying transport pass through +- pass_through, +- +- /// async_read_at_least call requested more bytes than buffer can store +- invalid_num_bytes, +- +- /// async_read called while another async_read was in progress +- double_read, +- +- /// Operation aborted +- operation_aborted, +- +- /// Operation not supported +- operation_not_supported, +- +- /// End of file +- eof, +- +- /// TLS short read +- tls_short_read, +- +- /// Timer expired +- timeout, +- +- /// read or write after shutdown +- action_after_shutdown, +- +- /// Other TLS error +- tls_error +-}; +- +-class category : public lib::error_category { +- public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic transport policy error"; +- case pass_through: +- return "Underlying Transport Error"; +- case invalid_num_bytes: +- return "async_read_at_least call requested more bytes than buffer can store"; +- case operation_aborted: +- return "The operation was aborted"; +- case operation_not_supported: +- return "The operation is not supported by this transport"; +- case eof: +- return "End of File"; +- case tls_short_read: +- return "TLS Short Read"; +- case timeout: +- return "Timer Expired"; +- case action_after_shutdown: +- return "A transport action was requested after shutdown"; +- case tls_error: +- return "Generic TLS related error"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace transport +-} // namespace ws_websocketpp +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif // WEBSOCKETPP_TRANSPORT_BASE_CON_HPP +diff --git a/src/lib/websocketpp/transport/base/endpoint.hpp b/src/lib/websocketpp/transport/base/endpoint.hpp +deleted file mode 100644 +index d1fbb88..0000000 +--- a/src/lib/websocketpp/transport/base/endpoint.hpp ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_BASE_HPP +- +-#include +-#include +- +-namespace ws_websocketpp { +-/// Transport policies provide network connectivity and timers +-/** +- * ### Endpoint Interface +- * +- * Transport endpoint components needs to provide: +- * +- * **init**\n +- * `lib::error_code init(transport_con_ptr tcon)`\n +- * init is called by an endpoint once for each newly created connection. +- * It's purpose is to give the transport policy the chance to perform any +- * transport specific initialization that couldn't be done via the default +- * constructor. +- * +- * **is_secure**\n +- * `bool is_secure() const`\n +- * Test whether the transport component of this endpoint is capable of secure +- * connections. +- * +- * **async_connect**\n +- * `void async_connect(transport_con_ptr tcon, uri_ptr location, +- * connect_handler handler)`\n +- * Initiate a connection to `location` using the given connection `tcon`. `tcon` +- * is a pointer to the transport connection component of the connection. When +- * complete, `handler` should be called with the the connection's +- * `connection_hdl` and any error that occurred. +- * +- * **init_logging** +- * `void init_logging(const lib::shared_ptr& a, const lib::shared_ptr& e)`\n +- * Called once after construction to provide pointers to the endpoint's access +- * and error loggers. These may be stored and used to log messages or ignored. +- */ +-namespace transport { +- +-/// The type and signature of the callback passed to the accept method +-typedef lib::function accept_handler; +- +-/// The type and signature of the callback passed to the connect method +-typedef lib::function connect_handler; +- +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_BASE_HPP +diff --git a/src/lib/websocketpp/transport/debug/base.hpp b/src/lib/websocketpp/transport/debug/base.hpp +deleted file mode 100644 +index e067d23..0000000 +--- a/src/lib/websocketpp/transport/debug/base.hpp ++++ /dev/null +@@ -1,104 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_DEBUG_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_DEBUG_BASE_HPP +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-/// Debug transport policy that is used for various mocking and stubbing duties +-/// in unit tests. +-namespace debug { +- +-/// debug transport errors +-namespace error { +-enum value { +- /// Catch-all error for transport policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// not implemented +- not_implemented, +- +- invalid_num_bytes, +- +- double_read +-}; +- +-/// debug transport error category +-class category : public lib::error_category { +- public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport.debug"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic stub transport policy error"; +- case not_implemented: +- return "feature not implemented"; +- case invalid_num_bytes: +- return "Invalid number of bytes"; +- case double_read: +- return "Read while another read was outstanding"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the debug transport error category +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-/// Get an error code with the given value and the debug transport category +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace debug +-} // namespace transport +-} // namespace ws_websocketpp +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif // WEBSOCKETPP_TRANSPORT_DEBUG_BASE_HPP +diff --git a/src/lib/websocketpp/transport/debug/connection.hpp b/src/lib/websocketpp/transport/debug/connection.hpp +deleted file mode 100644 +index 18ff3c2..0000000 +--- a/src/lib/websocketpp/transport/debug/connection.hpp ++++ /dev/null +@@ -1,412 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_DEBUG_CON_HPP +-#define WEBSOCKETPP_TRANSPORT_DEBUG_CON_HPP +- +-#include +- +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace debug { +- +-/// Empty timer class to stub out for timer functionality that stub +-/// transport doesn't support +-struct timer { +- void cancel() {} +-}; +- +-template +-class connection : public lib::enable_shared_from_this< connection > { +-public: +- /// Type of this connection transport component +- typedef connection type; +- /// Type of a shared pointer to this connection transport component +- typedef lib::shared_ptr ptr; +- +- /// transport concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this transport's access logging policy +- typedef typename config::alog_type alog_type; +- /// Type of this transport's error logging policy +- typedef typename config::elog_type elog_type; +- +- // Concurrency policy types +- typedef typename concurrency_type::scoped_lock_type scoped_lock_type; +- typedef typename concurrency_type::mutex_type mutex_type; +- +- typedef lib::shared_ptr timer_ptr; +- +- explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) +- : m_reading(false), m_is_server(is_server), m_alog(alog), m_elog(elog) +- { +- m_alog->write(log::alevel::devel,"debug con transport constructor"); +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return type::shared_from_this(); +- } +- +- /// Set whether or not this connection is secure +- /** +- * Todo: docs +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not this connection is secure. +- */ +- void set_secure(bool) {} +- +- /// Tests whether or not the underlying transport is secure +- /** +- * TODO: docs +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return false; +- } +- +- /// Set uri hook +- /** +- * Called by the endpoint as a connection is being established to provide +- * the uri being connected to to the transport layer. +- * +- * Implementation is optional and can be ignored if the transport has no +- * need for this information. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr) {} +- +- /// Set human readable remote endpoint address +- /** +- * Sets the remote endpoint address returned by `get_remote_endpoint`. This +- * value should be a human readable string that describes the remote +- * endpoint. Typically an IP address or hostname, perhaps with a port. But +- * may be something else depending on the nature of the underlying +- * transport. +- * +- * If none is set a default is returned. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value The remote endpoint address to set. +- */ +- void set_remote_endpoint(std::string) {} +- +- /// Get human readable remote endpoint address +- /** +- * TODO: docs +- * +- * This value is used in access and error logs and is available to the end +- * application for including in user facing interfaces and messages. +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint() const { +- return "unknown (debug transport)"; +- } +- +- /// Get the connection handle +- /** +- * @return The handle for this connection. +- */ +- connection_hdl get_handle() const { +- return connection_hdl(); +- } +- +- /// Call back a function after a period of time. +- /** +- * Timers are not implemented in this transport. The timer pointer will +- * always be empty. The handler will never be called. +- * +- * @param duration Length of time to wait in milliseconds +- * @param callback The function to call back when the timer has expired +- * @return A handle that can be used to cancel the timer if it is no longer +- * needed. +- */ +- timer_ptr set_timer(long, timer_handler handler) { +- m_alog->write(log::alevel::devel,"debug connection set timer"); +- m_timer_handler = handler; +- return timer_ptr(); +- } +- +- /// Manual input supply (read all) +- /** +- * Similar to read_some, but continues to read until all bytes in the +- * supplied buffer have been read or the connection runs out of read +- * requests. +- * +- * This method still may not read all of the bytes in the input buffer. if +- * it doesn't it indicates that the connection was most likely closed or +- * is in an error state where it is no longer accepting new input. +- * +- * @since 0.3.0 +- * +- * @param buf Char buffer to read into the websocket +- * @param len Length of buf +- * @return The number of characters from buf actually read. +- */ +- size_t read_all(char const * buf, size_t len) { +- size_t total_read = 0; +- size_t temp_read = 0; +- +- do { +- temp_read = this->read_some_impl(buf+total_read,len-total_read); +- total_read += temp_read; +- } while (temp_read != 0 && total_read < len); +- +- return total_read; +- } +- +- // debug stuff to invoke the async handlers +- void expire_timer(lib::error_code const & ec) { +- m_timer_handler(ec); +- } +- +- void fullfil_write() { +- m_write_handler(lib::error_code()); +- } +-protected: +- /// Initialize the connection transport +- /** +- * Initialize the connection's transport component. +- * +- * @param handler The `init_handler` to call when initialization is done +- */ +- void init(init_handler handler) { +- m_alog->write(log::alevel::devel,"debug connection init"); +- handler(lib::error_code()); +- } +- +- /// Initiate an async_read for at least num_bytes bytes into buf +- /** +- * Initiates an async_read request for at least num_bytes bytes. The input +- * will be read into buf. A maximum of len bytes will be input. When the +- * operation is complete, handler will be called with the status and number +- * of bytes read. +- * +- * This method may or may not call handler from within the initial call. The +- * application should be prepared to accept either. +- * +- * The application should never call this method a second time before it has +- * been called back for the first read. If this is done, the second read +- * will be called back immediately with a double_read error. +- * +- * If num_bytes or len are zero handler will be called back immediately +- * indicating success. +- * +- * @param num_bytes Don't call handler until at least this many bytes have +- * been read. +- * @param buf The buffer to read bytes into +- * @param len The size of buf. At maximum, this many bytes will be read. +- * @param handler The callback to invoke when the operation is complete or +- * ends in an error +- */ +- void async_read_at_least(size_t num_bytes, char * buf, size_t len, +- read_handler handler) +- { +- std::stringstream s; +- s << "debug_con async_read_at_least: " << num_bytes; +- m_alog->write(log::alevel::devel,s.str()); +- +- if (num_bytes > len) { +- handler(make_error_code(error::invalid_num_bytes),size_t(0)); +- return; +- } +- +- if (m_reading == true) { +- handler(make_error_code(error::double_read),size_t(0)); +- return; +- } +- +- if (num_bytes == 0 || len == 0) { +- handler(lib::error_code(),size_t(0)); +- return; +- } +- +- m_buf = buf; +- m_len = len; +- m_bytes_needed = num_bytes; +- m_read_handler = handler; +- m_cursor = 0; +- m_reading = true; +- } +- +- /// Asyncronous Transport Write +- /** +- * Write len bytes in buf to the output stream. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. +- * +- * @param buf buffer to read bytes from +- * @param len number of bytes to write +- * @param handler Callback to invoke with operation status. +- */ +- void async_write(char const *, size_t, write_handler handler) { +- m_alog->write(log::alevel::devel,"debug_con async_write"); +- m_write_handler = handler; +- } +- +- /// Asyncronous Transport Write (scatter-gather) +- /** +- * Write a sequence of buffers to the output stream. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. +- * +- * @param bufs vector of buffers to write +- * @param handler Callback to invoke with operation status. +- */ +- void async_write(std::vector const &, write_handler handler) { +- m_alog->write(log::alevel::devel,"debug_con async_write buffer list"); +- m_write_handler = handler; +- } +- +- /// Set Connection Handle +- /** +- * @param hdl The new handle +- */ +- void set_handle(connection_hdl) {} +- +- /// Call given handler back within the transport's event system (if present) +- /** +- * Invoke a callback within the transport's event system if it has one. If +- * it doesn't, the handler will be invoked immediately before this function +- * returns. +- * +- * @param handler The callback to invoke +- * +- * @return Whether or not the transport was able to register the handler for +- * callback. +- */ +- lib::error_code dispatch(dispatch_handler handler) { +- handler(); +- return lib::error_code(); +- } +- +- /// Perform cleanup on socket shutdown_handler +- /** +- * @param h The `shutdown_handler` to call back when complete +- */ +- void async_shutdown(shutdown_handler handler) { +- handler(lib::error_code()); +- } +- +- size_t read_some_impl(char const * buf, size_t len) { +- m_alog->write(log::alevel::devel,"debug_con read_some"); +- +- if (!m_reading) { +- m_elog->write(log::elevel::devel,"write while not reading"); +- return 0; +- } +- +- size_t bytes_to_copy = (std::min)(len,m_len-m_cursor); +- +- std::copy(buf,buf+bytes_to_copy,m_buf+m_cursor); +- +- m_cursor += bytes_to_copy; +- +- if (m_cursor >= m_bytes_needed) { +- complete_read(lib::error_code()); +- } +- +- return bytes_to_copy; +- } +- +- /// Signal that a requested read is complete +- /** +- * Sets the reading flag to false and returns the handler that should be +- * called back with the result of the read. The cursor position that is sent +- * is whatever the value of m_cursor is. +- * +- * It MUST NOT be called when m_reading is false. +- * it MUST be called while holding the read lock +- * +- * It is important to use this method rather than directly setting/calling +- * m_read_handler back because this function makes sure to delete the +- * locally stored handler which contains shared pointers that will otherwise +- * cause circular reference based memory leaks. +- * +- * @param ec The error code to forward to the read handler +- */ +- void complete_read(lib::error_code const & ec) { +- m_reading = false; +- +- read_handler handler = m_read_handler; +- m_read_handler = read_handler(); +- +- handler(ec,m_cursor); +- } +-private: +- timer_handler m_timer_handler; +- +- // Read space (Protected by m_read_mutex) +- char * m_buf; +- size_t m_len; +- size_t m_bytes_needed; +- read_handler m_read_handler; +- size_t m_cursor; +- +- // transport resources +- connection_hdl m_connection_hdl; +- write_handler m_write_handler; +- shutdown_handler m_shutdown_handler; +- +- bool m_reading; +- bool const m_is_server; +- bool m_is_secure; +- lib::shared_ptr m_alog; +- lib::shared_ptr m_elog; +- std::string m_remote_endpoint; +-}; +- +- +-} // namespace debug +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_DEBUG_CON_HPP +diff --git a/src/lib/websocketpp/transport/debug/endpoint.hpp b/src/lib/websocketpp/transport/debug/endpoint.hpp +deleted file mode 100644 +index eb233f1..0000000 +--- a/src/lib/websocketpp/transport/debug/endpoint.hpp ++++ /dev/null +@@ -1,140 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_DEBUG_HPP +-#define WEBSOCKETPP_TRANSPORT_DEBUG_HPP +- +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace debug { +- +-template +-class endpoint { +-public: +- /// Type of this endpoint transport component +- typedef endpoint type; +- /// Type of a pointer to this endpoint transport component +- typedef lib::shared_ptr ptr; +- +- /// Type of this endpoint's concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this endpoint's error logging policy +- typedef typename config::elog_type elog_type; +- /// Type of this endpoint's access logging policy +- typedef typename config::alog_type alog_type; +- +- /// Type of this endpoint transport component's associated connection +- /// transport component. +- typedef debug::connection transport_con_type; +- /// Type of a shared pointer to this endpoint transport component's +- /// associated connection transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- // generate and manage our own io_service +- explicit endpoint() +- { +- //std::cout << "transport::iostream::endpoint constructor" << std::endl; +- } +- +- /// Set whether or not endpoint can create secure connections +- /** +- * TODO: docs +- * +- * Setting this value only indicates whether or not the endpoint is capable +- * of producing and managing secure connections. Connections produced by +- * this endpoint must also be individually flagged as secure if they are. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not the endpoint can create secure connections. +- */ +- void set_secure(bool) {} +- +- /// Tests whether or not the underlying transport is secure +- /** +- * TODO: docs +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return false; +- } +-protected: +- /// Initialize logging +- /** +- * The loggers are located in the main endpoint class. As such, the +- * transport doesn't have direct access to them. This method is called +- * by the endpoint constructor to allow shared logging from the transport +- * component. These are raw pointers to member variables of the endpoint. +- * In particular, they cannot be used in the transport constructor as they +- * haven't been constructed yet, and cannot be used in the transport +- * destructor as they will have been destroyed by then. +- * +- * @param a A pointer to the access logger to use. +- * @param e A pointer to the error logger to use. +- */ +- void init_logging(lib::shared_ptr, lib::shared_ptr) {} +- +- /// Initiate a new connection +- /** +- * @param tcon A pointer to the transport connection component of the +- * connection to connect. +- * @param u A URI pointer to the URI to connect to. +- * @param cb The function to call back with the results when complete. +- */ +- void async_connect(transport_con_ptr, uri_ptr, connect_handler cb) { +- cb(lib::error_code()); +- } +- +- /// Initialize a connection +- /** +- * Init is called by an endpoint once for each newly created connection. +- * It's purpose is to give the transport policy the chance to perform any +- * transport specific initialization that couldn't be done via the default +- * constructor. +- * +- * @param tcon A pointer to the transport portion of the connection. +- * @return A status code indicating the success or failure of the operation +- */ +- lib::error_code init(transport_con_ptr) { +- return lib::error_code(); +- } +-private: +- +-}; +- +-} // namespace debug +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_DEBUG_HPP +diff --git a/src/lib/websocketpp/transport/iostream/base.hpp b/src/lib/websocketpp/transport/iostream/base.hpp +deleted file mode 100644 +index 3795696..0000000 +--- a/src/lib/websocketpp/transport/iostream/base.hpp ++++ /dev/null +@@ -1,133 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_IOSTREAM_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_IOSTREAM_BASE_HPP +- +-#include +-#include +-#include +-#include +- +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-/// Transport policy that uses STL iostream for I/O and does not support timers +-namespace iostream { +- +-/// The type and signature of the callback used by iostream transport to write +-typedef lib::function +- write_handler; +- +-/// The type and signature of the callback used by iostream transport to perform +-/// vectored writes. +-/** +- * If a vectored write handler is not set the standard write handler will be +- * called multiple times. +- */ +-typedef lib::function const +- & bufs)> vector_write_handler; +- +-/// The type and signature of the callback used by iostream transport to signal +-/// a transport shutdown. +-typedef lib::function shutdown_handler; +- +-/// iostream transport errors +-namespace error { +-enum value { +- /// Catch-all error for transport policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// async_read_at_least call requested more bytes than buffer can store +- invalid_num_bytes, +- +- /// async_read called while another async_read was in progress +- double_read, +- +- /// An operation that requires an output stream was attempted before +- /// setting one. +- output_stream_required, +- +- /// stream error +- bad_stream +-}; +- +-/// iostream transport error category +-class category : public lib::error_category { +- public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport.iostream"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic iostream transport policy error"; +- case invalid_num_bytes: +- return "async_read_at_least call requested more bytes than buffer can store"; +- case double_read: +- return "Async read already in progress"; +- case output_stream_required: +- return "An output stream to be set before async_write can be used"; +- case bad_stream: +- return "A stream operation returned ios::bad"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the iostream transport error category +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-/// Get an error code with the given value and the iostream transport category +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace iostream +-} // namespace transport +-} // namespace ws_websocketpp +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif // WEBSOCKETPP_TRANSPORT_IOSTREAM_BASE_HPP +diff --git a/src/lib/websocketpp/transport/iostream/connection.hpp b/src/lib/websocketpp/transport/iostream/connection.hpp +deleted file mode 100644 +index 5e2f76a..0000000 +--- a/src/lib/websocketpp/transport/iostream/connection.hpp ++++ /dev/null +@@ -1,714 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP +-#define WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP +- +-#include +- +-#include +- +-#include +- +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace iostream { +- +-/// Empty timer class to stub out for timer functionality that iostream +-/// transport doesn't support +-struct timer { +- void cancel() {} +-}; +- +-template +-class connection : public lib::enable_shared_from_this< connection > { +-public: +- /// Type of this connection transport component +- typedef connection type; +- /// Type of a shared pointer to this connection transport component +- typedef lib::shared_ptr ptr; +- +- /// transport concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this transport's access logging policy +- typedef typename config::alog_type alog_type; +- /// Type of this transport's error logging policy +- typedef typename config::elog_type elog_type; +- +- // Concurrency policy types +- typedef typename concurrency_type::scoped_lock_type scoped_lock_type; +- typedef typename concurrency_type::mutex_type mutex_type; +- +- typedef lib::shared_ptr timer_ptr; +- +- explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) +- : m_output_stream(NULL) +- , m_reading(false) +- , m_is_server(is_server) +- , m_is_secure(false) +- , m_alog(alog) +- , m_elog(elog) +- , m_remote_endpoint("iostream transport") +- { +- m_alog->write(log::alevel::devel,"iostream con transport constructor"); +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return type::shared_from_this(); +- } +- +- /// Register a std::ostream with the transport for writing output +- /** +- * Register a std::ostream with the transport. All future writes will be +- * done to this output stream. +- * +- * @param o A pointer to the ostream to use for output. +- */ +- void register_ostream(std::ostream * o) { +- // TODO: lock transport state? +- scoped_lock_type lock(m_read_mutex); +- m_output_stream = o; +- } +- +- /// Set uri hook +- /** +- * 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 so it is ignored. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr) {} +- +- /// Overloaded stream input operator +- /** +- * Attempts to read input from the given stream into the transport. Bytes +- * will be extracted from the input stream to fulfill any pending reads. +- * Input in this manner will only read until the current read buffer has +- * been filled. Then it will signal the library to process the input. If the +- * library's input handler adds a new async_read, additional bytes will be +- * read, otherwise the input operation will end. +- * +- * When this function returns one of the following conditions is true: +- * - There is no outstanding read operation +- * - There are no more bytes available in the input stream +- * +- * You can use tellg() on the input stream to determine if all of the input +- * bytes were read or not. +- * +- * If there is no pending read operation when the input method is called, it +- * will return immediately and tellg() will not have changed. +- */ +- friend std::istream & operator>> (std::istream & in, type & t) { +- // this serializes calls to external read. +- scoped_lock_type lock(t.m_read_mutex); +- +- t.read(in); +- +- return in; +- } +- +- /// Manual input supply (read some) +- /** +- * Copies bytes from buf into WebSocket++'s input buffers. Bytes will be +- * copied from the supplied buffer to fulfill any pending library reads. It +- * will return the number of bytes successfully processed. If there are no +- * pending reads read_some will return immediately. Not all of the bytes may +- * be able to be read in one call. +- * +- * @since 0.3.0-alpha4 +- * +- * @param buf Char buffer to read into the websocket +- * @param len Length of buf +- * @return The number of characters from buf actually read. +- */ +- size_t read_some(char const * buf, size_t len) { +- // this serializes calls to external read. +- scoped_lock_type lock(m_read_mutex); +- +- return this->read_some_impl(buf,len); +- } +- +- /// Manual input supply (read all) +- /** +- * Similar to read_some, but continues to read until all bytes in the +- * supplied buffer have been read or the connection runs out of read +- * requests. +- * +- * This method still may not read all of the bytes in the input buffer. if +- * it doesn't it indicates that the connection was most likely closed or +- * is in an error state where it is no longer accepting new input. +- * +- * @since 0.3.0 +- * +- * @param buf Char buffer to read into the websocket +- * @param len Length of buf +- * @return The number of characters from buf actually read. +- */ +- size_t read_all(char const * buf, size_t len) { +- // this serializes calls to external read. +- scoped_lock_type lock(m_read_mutex); +- +- size_t total_read = 0; +- size_t temp_read = 0; +- +- do { +- temp_read = this->read_some_impl(buf+total_read,len-total_read); +- total_read += temp_read; +- } while (temp_read != 0 && total_read < len); +- +- return total_read; +- } +- +- /// Manual input supply (DEPRECATED) +- /** +- * @deprecated DEPRECATED in favor of read_some() +- * @see read_some() +- */ +- size_t readsome(char const * buf, size_t len) { +- return this->read_some(buf,len); +- } +- +- /// Signal EOF +- /** +- * Signals to the transport that data stream being read has reached EOF and +- * that no more bytes may be read or written to/from the transport. +- * +- * @since 0.3.0-alpha4 +- */ +- void eof() { +- // this serializes calls to external read. +- scoped_lock_type lock(m_read_mutex); +- +- if (m_reading) { +- complete_read(make_error_code(transport::error::eof)); +- } +- } +- +- /// Signal transport error +- /** +- * Signals to the transport that a fatal data stream error has occurred and +- * that no more bytes may be read or written to/from the transport. +- * +- * @since 0.3.0-alpha4 +- */ +- void fatal_error() { +- // this serializes calls to external read. +- scoped_lock_type lock(m_read_mutex); +- +- if (m_reading) { +- complete_read(make_error_code(transport::error::pass_through)); +- } +- } +- +- /// Set whether or not this connection is secure +- /** +- * The iostream transport does not provide any security features. As such +- * it defaults to returning false when `is_secure` is called. However, the +- * iostream transport may be used to wrap an external socket API that may +- * provide secure transport. This method allows that external API to flag +- * whether or not this connection is secure so that users of the WebSocket++ +- * API will get more accurate information. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not this connection is secure. +- */ +- void set_secure(bool value) { +- m_is_secure = value; +- } +- +- /// Tests whether or not the underlying transport is secure +- /** +- * iostream transport will return false always because it has no information +- * about the ultimate remote endpoint. This may or may not be accurate +- * depending on the real source of bytes being input. The `set_secure` +- * method may be used to flag connections that are secured by an external +- * API +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return m_is_secure; +- } +- +- /// Set human readable remote endpoint address +- /** +- * Sets the remote endpoint address returned by `get_remote_endpoint`. This +- * value should be a human readable string that describes the remote +- * endpoint. Typically an IP address or hostname, perhaps with a port. But +- * may be something else depending on the nature of the underlying +- * transport. +- * +- * If none is set the default is "iostream transport". +- * +- * @since 0.3.0-alpha4 +- * +- * @param value The remote endpoint address to set. +- */ +- void set_remote_endpoint(std::string value) { +- m_remote_endpoint = value; +- } +- +- /// Get human readable remote endpoint address +- /** +- * The iostream transport has no information about the ultimate remote +- * endpoint. It will return the string "iostream transport". The +- * `set_remote_endpoint` method may be used by external network code to set +- * a more accurate value. +- * +- * This value is used in access and error logs and is available to the end +- * application for including in user facing interfaces and messages. +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint() const { +- return m_remote_endpoint; +- } +- +- /// Get the connection handle +- /** +- * @return The handle for this connection. +- */ +- connection_hdl get_handle() const { +- return m_connection_hdl; +- } +- +- /// Call back a function after a period of time. +- /** +- * Timers are not implemented in this transport. The timer pointer will +- * always be empty. The handler will never be called. +- * +- * @param duration Length of time to wait in milliseconds +- * @param callback The function to call back when the timer has expired +- * @return A handle that can be used to cancel the timer if it is no longer +- * needed. +- */ +- timer_ptr set_timer(long, timer_handler) { +- return timer_ptr(); +- } +- +- /// Sets the write handler +- /** +- * The write handler is called when the iostream transport receives data +- * that needs to be written to the appropriate output location. This handler +- * can be used in place of registering an ostream for output. +- * +- * The signature of the handler is +- * `lib::error_code (connection_hdl, char const *, size_t)` The +- * code returned will be reported and logged by the core library. +- * +- * See also, set_vector_write_handler, for an optional write handler that +- * allows more efficient handling of multiple writes at once. +- * +- * @see set_vector_write_handler +- * +- * @since 0.5.0 +- * +- * @param h The handler to call when data is to be written. +- */ +- void set_write_handler(write_handler h) { +- m_write_handler = h; +- } +- +- /// Sets the vectored write handler +- /** +- * The vectored write handler is called when the iostream transport receives +- * multiple chunks of data that need to be written to the appropriate output +- * location. This handler can be used in conjunction with the write_handler +- * in place of registering an ostream for output. +- * +- * The sequence of buffers represents bytes that should be written +- * consecutively and it is suggested to group the buffers into as few next +- * layer packets as possible. Vector write is used to allow implementations +- * that support it to coalesce writes into a single TCP packet or TLS +- * segment for improved efficiency. +- * +- * This is an optional handler. If it is not defined then multiple calls +- * will be made to the standard write handler. +- * +- * The signature of the handler is +- * `lib::error_code (connection_hdl, std::vector +- * const & bufs)`. The code returned will be reported and logged by the core +- * library. The `ws_websocketpp::transport::buffer` type is a struct with two +- * data members. buf (char const *) and len (size_t). +- * +- * @since 0.6.0 +- * +- * @param h The handler to call when vectored data is to be written. +- */ +- void set_vector_write_handler(vector_write_handler h) { +- m_vector_write_handler = h; +- } +- +- /// Sets the shutdown handler +- /** +- * The shutdown handler is called when the iostream transport receives a +- * notification from the core library that it is finished with all read and +- * write operations and that the underlying transport can be cleaned up. +- * +- * If you are using iostream transport with another socket library, this is +- * a good time to close/shutdown the socket for this connection. +- * +- * The signature of the handler is `lib::error_code (connection_hdl)`. The +- * code returned will be reported and logged by the core library. +- * +- * @since 0.5.0 +- * +- * @param h The handler to call on connection shutdown. +- */ +- void set_shutdown_handler(shutdown_handler h) { +- m_shutdown_handler = h; +- } +-protected: +- /// Initialize the connection transport +- /** +- * Initialize the connection's transport component. +- * +- * @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"); +- handler(lib::error_code()); +- } +- +- /// Initiate an async_read for at least num_bytes bytes into buf +- /** +- * Initiates an async_read request for at least num_bytes bytes. The input +- * will be read into buf. A maximum of len bytes will be input. When the +- * operation is complete, handler will be called with the status and number +- * of bytes read. +- * +- * This method may or may not call handler from within the initial call. The +- * application should be prepared to accept either. +- * +- * The application should never call this method a second time before it has +- * been called back for the first read. If this is done, the second read +- * will be called back immediately with a double_read error. +- * +- * If num_bytes or len are zero handler will be called back immediately +- * indicating success. +- * +- * @param num_bytes Don't call handler until at least this many bytes have +- * been read. +- * @param buf The buffer to read bytes into +- * @param len The size of buf. At maximum, this many bytes will be read. +- * @param handler The callback to invoke when the operation is complete or +- * ends in an error +- */ +- void async_read_at_least(size_t num_bytes, char *buf, size_t len, +- read_handler handler) +- { +- std::stringstream s; +- s << "iostream_con async_read_at_least: " << num_bytes; +- m_alog->write(log::alevel::devel,s.str()); +- +- if (num_bytes > len) { +- handler(make_error_code(error::invalid_num_bytes),size_t(0)); +- return; +- } +- +- if (m_reading == true) { +- handler(make_error_code(error::double_read),size_t(0)); +- return; +- } +- +- if (num_bytes == 0 || len == 0) { +- handler(lib::error_code(),size_t(0)); +- return; +- } +- +- m_buf = buf; +- m_len = len; +- m_bytes_needed = num_bytes; +- m_read_handler = handler; +- m_cursor = 0; +- m_reading = true; +- } +- +- /// Asyncronous Transport Write +- /** +- * Write len bytes in buf to the output method. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. Other possible errors (not exhaustive) +- * output_stream_required: No output stream was registered to write to +- * bad_stream: a ostream pass through error +- * +- * This method will attempt to write to the registered ostream first. If an +- * ostream is not registered it will use the write handler. If neither are +- * registered then an error is passed up to the connection. +- * +- * @param buf buffer to read bytes from +- * @param len number of bytes to write +- * @param handler Callback to invoke with operation status. +- */ +- void async_write(char const * buf, size_t len, transport::write_handler +- handler) +- { +- m_alog->write(log::alevel::devel,"iostream_con async_write"); +- // TODO: lock transport state? +- +- lib::error_code ec; +- +- if (m_output_stream) { +- m_output_stream->write(buf,len); +- +- if (m_output_stream->bad()) { +- ec = make_error_code(error::bad_stream); +- } +- } else if (m_write_handler) { +- ec = m_write_handler(m_connection_hdl, buf, len); +- } else { +- ec = make_error_code(error::output_stream_required); +- } +- +- handler(ec); +- } +- +- /// Asyncronous Transport Write (scatter-gather) +- /** +- * Write a sequence of buffers to the output method. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. Other possible errors (not exhaustive) +- * output_stream_required: No output stream was registered to write to +- * bad_stream: a ostream pass through error +- * +- * This method will attempt to write to the registered ostream first. If an +- * ostream is not registered it will use the write handler. If neither are +- * registered then an error is passed up to the connection. +- * +- * @param bufs vector of buffers to write +- * @param handler Callback to invoke with operation status. +- */ +- void async_write(std::vector const & bufs, transport::write_handler +- handler) +- { +- m_alog->write(log::alevel::devel,"iostream_con async_write buffer list"); +- // TODO: lock transport state? +- +- lib::error_code ec; +- +- if (m_output_stream) { +- std::vector::const_iterator it; +- for (it = bufs.begin(); it != bufs.end(); it++) { +- m_output_stream->write((*it).buf,(*it).len); +- +- if (m_output_stream->bad()) { +- ec = make_error_code(error::bad_stream); +- break; +- } +- } +- } else if (m_vector_write_handler) { +- ec = m_vector_write_handler(m_connection_hdl, bufs); +- } else if (m_write_handler) { +- std::vector::const_iterator it; +- for (it = bufs.begin(); it != bufs.end(); it++) { +- ec = m_write_handler(m_connection_hdl, (*it).buf, (*it).len); +- if (ec) {break;} +- } +- +- } else { +- ec = make_error_code(error::output_stream_required); +- } +- +- handler(ec); +- } +- +- /// Set Connection Handle +- /** +- * @param hdl The new handle +- */ +- void set_handle(connection_hdl hdl) { +- m_connection_hdl = hdl; +- } +- +- /// Call given handler back within the transport's event system (if present) +- /** +- * Invoke a callback within the transport's event system if it has one. If +- * it doesn't, the handler will be invoked immediately before this function +- * returns. +- * +- * @param handler The callback to invoke +- * +- * @return Whether or not the transport was able to register the handler for +- * callback. +- */ +- lib::error_code dispatch(dispatch_handler handler) { +- handler(); +- return lib::error_code(); +- } +- +- /// Perform cleanup on socket shutdown_handler +- /** +- * If a shutdown handler is set, call it and pass through its return error +- * code. Otherwise assume there is nothing to do and pass through a success +- * code. +- * +- * @param handler The `shutdown_handler` to call back when complete +- */ +- void async_shutdown(transport::shutdown_handler handler) { +- lib::error_code ec; +- +- if (m_shutdown_handler) { +- ec = m_shutdown_handler(m_connection_hdl); +- } +- +- handler(ec); +- } +-private: +- void read(std::istream &in) { +- 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"); +- break; +- } +- +- in.read(m_buf+m_cursor,static_cast(m_len-m_cursor)); +- +- if (in.gcount() == 0) { +- m_elog->write(log::elevel::devel,"read zero bytes"); +- break; +- } +- +- m_cursor += static_cast(in.gcount()); +- +- // TODO: error handling +- if (in.bad()) { +- m_reading = false; +- complete_read(make_error_code(error::bad_stream)); +- } +- +- if (m_cursor >= m_bytes_needed) { +- m_reading = false; +- complete_read(lib::error_code()); +- } +- } +- } +- +- size_t read_some_impl(char const * buf, size_t len) { +- m_alog->write(log::alevel::devel,"iostream_con read_some"); +- +- if (!m_reading) { +- m_elog->write(log::elevel::devel,"write while not reading"); +- return 0; +- } +- +- size_t bytes_to_copy = (std::min)(len,m_len-m_cursor); +- +- std::copy(buf,buf+bytes_to_copy,m_buf+m_cursor); +- +- m_cursor += bytes_to_copy; +- +- if (m_cursor >= m_bytes_needed) { +- complete_read(lib::error_code()); +- } +- +- return bytes_to_copy; +- } +- +- /// Signal that a requested read is complete +- /** +- * Sets the reading flag to false and returns the handler that should be +- * called back with the result of the read. The cursor position that is sent +- * is whatever the value of m_cursor is. +- * +- * It MUST NOT be called when m_reading is false. +- * it MUST be called while holding the read lock +- * +- * It is important to use this method rather than directly setting/calling +- * m_read_handler back because this function makes sure to delete the +- * locally stored handler which contains shared pointers that will otherwise +- * cause circular reference based memory leaks. +- * +- * @param ec The error code to forward to the read handler +- */ +- void complete_read(lib::error_code const & ec) { +- m_reading = false; +- +- read_handler handler = m_read_handler; +- m_read_handler = read_handler(); +- +- handler(ec,m_cursor); +- } +- +- // Read space (Protected by m_read_mutex) +- char * m_buf; +- size_t m_len; +- size_t m_bytes_needed; +- read_handler m_read_handler; +- size_t m_cursor; +- +- // transport resources +- std::ostream * m_output_stream; +- connection_hdl m_connection_hdl; +- write_handler m_write_handler; +- vector_write_handler m_vector_write_handler; +- shutdown_handler m_shutdown_handler; +- +- bool m_reading; +- bool const m_is_server; +- bool m_is_secure; +- lib::shared_ptr m_alog; +- lib::shared_ptr m_elog; +- std::string m_remote_endpoint; +- +- // This lock ensures that only one thread can edit read data for this +- // connection. This is a very coarse lock that is basically locked all the +- // time. The nature of the connection is such that it cannot be +- // parallelized, the locking is here to prevent intra-connection concurrency +- // in order to allow inter-connection concurrency. +- mutex_type m_read_mutex; +-}; +- +- +-} // namespace iostream +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP +diff --git a/src/lib/websocketpp/transport/iostream/endpoint.hpp b/src/lib/websocketpp/transport/iostream/endpoint.hpp +deleted file mode 100644 +index 581cb5a..0000000 +--- a/src/lib/websocketpp/transport/iostream/endpoint.hpp ++++ /dev/null +@@ -1,222 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_IOSTREAM_HPP +-#define WEBSOCKETPP_TRANSPORT_IOSTREAM_HPP +- +-#include +-#include +- +-#include +-#include +- +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace iostream { +- +-template +-class endpoint { +-public: +- /// Type of this endpoint transport component +- typedef endpoint type; +- /// Type of a pointer to this endpoint transport component +- typedef lib::shared_ptr ptr; +- +- /// Type of this endpoint's concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this endpoint's error logging policy +- typedef typename config::elog_type elog_type; +- /// Type of this endpoint's access logging policy +- typedef typename config::alog_type alog_type; +- +- /// Type of this endpoint transport component's associated connection +- /// transport component. +- typedef iostream::connection transport_con_type; +- /// Type of a shared pointer to this endpoint transport component's +- /// associated connection transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- // generate and manage our own io_service +- explicit endpoint() : m_output_stream(NULL), m_is_secure(false) +- { +- //std::cout << "transport::iostream::endpoint constructor" << std::endl; +- } +- +- /// Register a default output stream +- /** +- * The specified output stream will be assigned to future connections as the +- * default output stream. +- * +- * @param o The ostream to use as the default output stream. +- */ +- void register_ostream(std::ostream * o) { +- m_alog->write(log::alevel::devel,"register_ostream"); +- m_output_stream = o; +- } +- +- /// Set whether or not endpoint can create secure connections +- /** +- * The iostream transport does not provide any security features. As such +- * it defaults to returning false when `is_secure` is called. However, the +- * iostream transport may be used to wrap an external socket API that may +- * provide secure transport. This method allows that external API to flag +- * whether or not it can create secure connections so that users of the +- * WebSocket++ API will get more accurate information. +- * +- * Setting this value only indicates whether or not the endpoint is capable +- * of producing and managing secure connections. Connections produced by +- * this endpoint must also be individually flagged as secure if they are. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not the endpoint can create secure connections. +- */ +- void set_secure(bool value) { +- m_is_secure = value; +- } +- +- /// Tests whether or not the underlying transport is secure +- /** +- * iostream transport will return false by default because it has no +- * information about the ultimate remote endpoint. This may or may not be +- * accurate depending on the real source of bytes being input. `set_secure` +- * may be used by a wrapper API to correct the return value in the case that +- * secure connections are in fact possible. +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return m_is_secure; +- } +- +- /// Sets the write handler +- /** +- * The write handler is called when the iostream transport receives data +- * that needs to be written to the appropriate output location. This handler +- * can be used in place of registering an ostream for output. +- * +- * The signature of the handler is +- * `lib::error_code (connection_hdl, char const *, size_t)` The +- * code returned will be reported and logged by the core library. +- * +- * @since 0.5.0 +- * +- * @param h The handler to call on connection shutdown. +- */ +- void set_write_handler(write_handler h) { +- m_write_handler = h; +- } +- +- /// Sets the shutdown handler +- /** +- * The shutdown handler is called when the iostream transport receives a +- * notification from the core library that it is finished with all read and +- * write operations and that the underlying transport can be cleaned up. +- * +- * If you are using iostream transport with another socket library, this is +- * a good time to close/shutdown the socket for this connection. +- * +- * The signature of the handler is lib::error_code (connection_hdl). The +- * code returned will be reported and logged by the core library. +- * +- * @since 0.5.0 +- * +- * @param h The handler to call on connection shutdown. +- */ +- void set_shutdown_handler(shutdown_handler h) { +- m_shutdown_handler = h; +- } +-protected: +- /// Initialize logging +- /** +- * The loggers are located in the main endpoint class. As such, the +- * transport doesn't have direct access to them. This method is called +- * by the endpoint constructor to allow shared logging from the transport +- * component. These are raw pointers to member variables of the endpoint. +- * In particular, they cannot be used in the transport constructor as they +- * haven't been constructed yet, and cannot be used in the transport +- * destructor as they will have been destroyed by then. +- * +- * @param a A pointer to the access logger to use. +- * @param e A pointer to the error logger to use. +- */ +- void init_logging(lib::shared_ptr a, lib::shared_ptr e) { +- m_elog = e; +- m_alog = a; +- } +- +- /// Initiate a new connection +- /** +- * @param tcon A pointer to the transport connection component of the +- * connection to connect. +- * @param u A URI pointer to the URI to connect to. +- * @param cb The function to call back with the results when complete. +- */ +- void async_connect(transport_con_ptr, uri_ptr, connect_handler cb) { +- cb(lib::error_code()); +- } +- +- /// Initialize a connection +- /** +- * Init is called by an endpoint once for each newly created connection. +- * It's purpose is to give the transport policy the chance to perform any +- * transport specific initialization that couldn't be done via the default +- * constructor. +- * +- * @param tcon A pointer to the transport portion of the connection. +- * @return A status code indicating the success or failure of the operation +- */ +- lib::error_code init(transport_con_ptr tcon) { +- tcon->register_ostream(m_output_stream); +- if (m_shutdown_handler) { +- tcon->set_shutdown_handler(m_shutdown_handler); +- } +- if (m_write_handler) { +- tcon->set_write_handler(m_write_handler); +- } +- return lib::error_code(); +- } +-private: +- std::ostream * m_output_stream; +- shutdown_handler m_shutdown_handler; +- write_handler m_write_handler; +- +- lib::shared_ptr m_elog; +- lib::shared_ptr m_alog; +- bool m_is_secure; +-}; +- +- +-} // namespace iostream +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_IOSTREAM_HPP +diff --git a/src/lib/websocketpp/transport/stub/base.hpp b/src/lib/websocketpp/transport/stub/base.hpp +deleted file mode 100644 +index db9bfe9..0000000 +--- a/src/lib/websocketpp/transport/stub/base.hpp ++++ /dev/null +@@ -1,95 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP +-#define WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP +- +-#include +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-/// Stub transport policy that has no input or output. +-namespace stub { +- +-/// stub transport errors +-namespace error { +-enum value { +- /// Catch-all error for transport policy errors that don't fit in other +- /// categories +- general = 1, +- +- /// not implemented +- not_implemented +-}; +- +-/// stub transport error category +-class category : public lib::error_category { +- public: +- category() {} +- +- char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ { +- return "websocketpp.transport.stub"; +- } +- +- std::string message(int value) const { +- switch(value) { +- case general: +- return "Generic stub transport policy error"; +- case not_implemented: +- return "feature not implemented"; +- default: +- return "Unknown"; +- } +- } +-}; +- +-/// Get a reference to a static copy of the stub transport error category +-inline lib::error_category const & get_category() { +- static category instance; +- return instance; +-} +- +-/// Get an error code with the given value and the stub transport category +-inline lib::error_code make_error_code(error::value e) { +- return lib::error_code(static_cast(e), get_category()); +-} +- +-} // namespace error +-} // namespace stub +-} // namespace transport +-} // namespace ws_websocketpp +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_ +-template<> struct is_error_code_enum +-{ +- static bool const value = true; +-}; +-_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_ +- +-#endif // WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP +diff --git a/src/lib/websocketpp/transport/stub/connection.hpp b/src/lib/websocketpp/transport/stub/connection.hpp +deleted file mode 100644 +index 7d83975..0000000 +--- a/src/lib/websocketpp/transport/stub/connection.hpp ++++ /dev/null +@@ -1,286 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_STUB_CON_HPP +-#define WEBSOCKETPP_TRANSPORT_STUB_CON_HPP +- +-#include +- +-#include +- +-#include +- +-#include +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace stub { +- +-/// Empty timer class to stub out for timer functionality that stub +-/// transport doesn't support +-struct timer { +- void cancel() {} +-}; +- +-template +-class connection : public lib::enable_shared_from_this< connection > { +-public: +- /// Type of this connection transport component +- typedef connection type; +- /// Type of a shared pointer to this connection transport component +- typedef lib::shared_ptr ptr; +- +- /// transport concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this transport's access logging policy +- typedef typename config::alog_type alog_type; +- /// Type of this transport's error logging policy +- typedef typename config::elog_type elog_type; +- +- // Concurrency policy types +- typedef typename concurrency_type::scoped_lock_type scoped_lock_type; +- typedef typename concurrency_type::mutex_type mutex_type; +- +- typedef lib::shared_ptr timer_ptr; +- +- explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) +- : m_alog(alog), m_elog(elog) +- { +- m_alog->write(log::alevel::devel,"stub con transport constructor"); +- } +- +- /// Get a shared pointer to this component +- ptr get_shared() { +- return type::shared_from_this(); +- } +- +- /// Set whether or not this connection is secure +- /** +- * Todo: docs +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not this connection is secure. +- */ +- void set_secure(bool value) {} +- +- /// Tests whether or not the underlying transport is secure +- /** +- * TODO: docs +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return false; +- } +- +- /// Set uri hook +- /** +- * Called by the endpoint as a connection is being established to provide +- * the uri being connected to to the transport layer. +- * +- * Implementation is optional and can be ignored if the transport has no +- * need for this information. +- * +- * @since 0.6.0 +- * +- * @param u The uri to set +- */ +- void set_uri(uri_ptr) {} +- +- /// Set human readable remote endpoint address +- /** +- * Sets the remote endpoint address returned by `get_remote_endpoint`. This +- * value should be a human readable string that describes the remote +- * endpoint. Typically an IP address or hostname, perhaps with a port. But +- * may be something else depending on the nature of the underlying +- * transport. +- * +- * If none is set a default is returned. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value The remote endpoint address to set. +- */ +- void set_remote_endpoint(std::string value) {} +- +- /// Get human readable remote endpoint address +- /** +- * TODO: docs +- * +- * This value is used in access and error logs and is available to the end +- * application for including in user facing interfaces and messages. +- * +- * @return A string identifying the address of the remote endpoint +- */ +- std::string get_remote_endpoint() const { +- return "unknown (stub transport)"; +- } +- +- /// Get the connection handle +- /** +- * @return The handle for this connection. +- */ +- connection_hdl get_handle() const { +- return connection_hdl(); +- } +- +- /// Call back a function after a period of time. +- /** +- * Timers are not implemented in this transport. The timer pointer will +- * always be empty. The handler will never be called. +- * +- * @param duration Length of time to wait in milliseconds +- * @param callback The function to call back when the timer has expired +- * @return A handle that can be used to cancel the timer if it is no longer +- * needed. +- */ +- timer_ptr set_timer(long duration, timer_handler handler) { +- return timer_ptr(); +- } +-protected: +- /// Initialize the connection transport +- /** +- * Initialize the connection's transport component. +- * +- * @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"); +- handler(make_error_code(error::not_implemented)); +- } +- +- /// Initiate an async_read for at least num_bytes bytes into buf +- /** +- * Initiates an async_read request for at least num_bytes bytes. The input +- * will be read into buf. A maximum of len bytes will be input. When the +- * operation is complete, handler will be called with the status and number +- * of bytes read. +- * +- * This method may or may not call handler from within the initial call. The +- * application should be prepared to accept either. +- * +- * The application should never call this method a second time before it has +- * been called back for the first read. If this is done, the second read +- * will be called back immediately with a double_read error. +- * +- * If num_bytes or len are zero handler will be called back immediately +- * indicating success. +- * +- * @param num_bytes Don't call handler until at least this many bytes have +- * been read. +- * @param buf The buffer to read bytes into +- * @param len The size of buf. At maximum, this many bytes will be read. +- * @param handler The callback to invoke when the operation is complete or +- * ends in an error +- */ +- 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"); +- handler(make_error_code(error::not_implemented), 0); +- } +- +- /// Asyncronous Transport Write +- /** +- * Write len bytes in buf to the output stream. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. +- * +- * @param buf buffer to read bytes from +- * @param len number of bytes to write +- * @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"); +- handler(make_error_code(error::not_implemented)); +- } +- +- /// Asyncronous Transport Write (scatter-gather) +- /** +- * Write a sequence of buffers to the output stream. Call handler to report +- * success or failure. handler may or may not be called during async_write, +- * but it must be safe for this to happen. +- * +- * Will return 0 on success. +- * +- * @param bufs vector of buffers to write +- * @param handler Callback to invoke with operation status. +- */ +- void async_write(std::vector const & bufs, write_handler handler) { +- m_alog->write(log::alevel::devel,"stub_con async_write buffer list"); +- handler(make_error_code(error::not_implemented)); +- } +- +- /// Set Connection Handle +- /** +- * @param hdl The new handle +- */ +- void set_handle(connection_hdl hdl) {} +- +- /// Call given handler back within the transport's event system (if present) +- /** +- * Invoke a callback within the transport's event system if it has one. If +- * it doesn't, the handler will be invoked immediately before this function +- * returns. +- * +- * @param handler The callback to invoke +- * +- * @return Whether or not the transport was able to register the handler for +- * callback. +- */ +- lib::error_code dispatch(dispatch_handler handler) { +- handler(); +- return lib::error_code(); +- } +- +- /// Perform cleanup on socket shutdown_handler +- /** +- * @param h The `shutdown_handler` to call back when complete +- */ +- void async_shutdown(shutdown_handler handler) { +- handler(lib::error_code()); +- } +-private: +- // member variables! +- lib::shared_ptr m_alog; +- lib::shared_ptr m_elog; +-}; +- +- +-} // namespace stub +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_STUB_CON_HPP +diff --git a/src/lib/websocketpp/transport/stub/endpoint.hpp b/src/lib/websocketpp/transport/stub/endpoint.hpp +deleted file mode 100644 +index c5247fe..0000000 +--- a/src/lib/websocketpp/transport/stub/endpoint.hpp ++++ /dev/null +@@ -1,140 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_TRANSPORT_STUB_HPP +-#define WEBSOCKETPP_TRANSPORT_STUB_HPP +- +-#include +-#include +- +-#include +-#include +- +-namespace ws_websocketpp { +-namespace transport { +-namespace stub { +- +-template +-class endpoint { +-public: +- /// Type of this endpoint transport component +- typedef endpoint type; +- /// Type of a pointer to this endpoint transport component +- typedef lib::shared_ptr ptr; +- +- /// Type of this endpoint's concurrency policy +- typedef typename config::concurrency_type concurrency_type; +- /// Type of this endpoint's error logging policy +- typedef typename config::elog_type elog_type; +- /// Type of this endpoint's access logging policy +- typedef typename config::alog_type alog_type; +- +- /// Type of this endpoint transport component's associated connection +- /// transport component. +- typedef stub::connection transport_con_type; +- /// Type of a shared pointer to this endpoint transport component's +- /// associated connection transport component +- typedef typename transport_con_type::ptr transport_con_ptr; +- +- // generate and manage our own io_service +- explicit endpoint() +- { +- //std::cout << "transport::iostream::endpoint constructor" << std::endl; +- } +- +- /// Set whether or not endpoint can create secure connections +- /** +- * TODO: docs +- * +- * Setting this value only indicates whether or not the endpoint is capable +- * of producing and managing secure connections. Connections produced by +- * this endpoint must also be individually flagged as secure if they are. +- * +- * @since 0.3.0-alpha4 +- * +- * @param value Whether or not the endpoint can create secure connections. +- */ +- void set_secure(bool value) {} +- +- /// Tests whether or not the underlying transport is secure +- /** +- * TODO: docs +- * +- * @return Whether or not the underlying transport is secure +- */ +- bool is_secure() const { +- return false; +- } +-protected: +- /// Initialize logging +- /** +- * The loggers are located in the main endpoint class. As such, the +- * transport doesn't have direct access to them. This method is called +- * by the endpoint constructor to allow shared logging from the transport +- * component. These are raw pointers to member variables of the endpoint. +- * In particular, they cannot be used in the transport constructor as they +- * haven't been constructed yet, and cannot be used in the transport +- * destructor as they will have been destroyed by then. +- * +- * @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) {} +- +- /// Initiate a new connection +- /** +- * @param tcon A pointer to the transport connection component of the +- * connection to connect. +- * @param u A URI pointer to the URI to connect to. +- * @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) { +- cb(make_error_code(error::not_implemented)); +- } +- +- /// Initialize a connection +- /** +- * Init is called by an endpoint once for each newly created connection. +- * It's purpose is to give the transport policy the chance to perform any +- * transport specific initialization that couldn't be done via the default +- * constructor. +- * +- * @param tcon A pointer to the transport portion of the connection. +- * @return A status code indicating the success or failure of the operation +- */ +- lib::error_code init(transport_con_ptr tcon) { +- return make_error_code(error::not_implemented); +- } +-private: +- +-}; +- +-} // namespace stub +-} // namespace transport +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_TRANSPORT_STUB_HPP +diff --git a/src/lib/websocketpp/uri.hpp b/src/lib/websocketpp/uri.hpp +deleted file mode 100644 +index ac8991d..0000000 +--- a/src/lib/websocketpp/uri.hpp ++++ /dev/null +@@ -1,356 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_URI_HPP +-#define WEBSOCKETPP_URI_HPP +- +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-namespace ws_websocketpp { +- +-// TODO: figure out why this fixes horrible linking errors. +- +-/// Default port for ws:// +-static uint16_t const uri_default_port = 80; +-/// Default port for wss:// +-static uint16_t const uri_default_secure_port = 443; +- +-class uri { +-public: +- explicit uri(std::string const & uri_string) : m_valid(false) { +- std::string::const_iterator it; +- std::string::const_iterator temp; +- +- int state = 0; +- +- it = uri_string.begin(); +- size_t uri_len = uri_string.length(); +- +- if (uri_len >= 7 && std::equal(it,it+6,"wss://")) { +- m_secure = true; +- m_scheme = "wss"; +- it += 6; +- } else if (uri_len >= 6 && std::equal(it,it+5,"ws://")) { +- m_secure = false; +- m_scheme = "ws"; +- it += 5; +- } else if (uri_len >= 8 && std::equal(it,it+7,"http://")) { +- m_secure = false; +- m_scheme = "http"; +- it += 7; +- } else if (uri_len >= 9 && std::equal(it,it+8,"https://")) { +- m_secure = true; +- m_scheme = "https"; +- it += 8; +- } else { +- return; +- } +- +- // extract host. +- // either a host string +- // an IPv4 address +- // or an IPv6 address +- if (*it == '[') { +- ++it; +- // IPv6 literal +- // extract IPv6 digits until ] +- +- // TODO: this doesn't work on g++... not sure why +- //temp = std::find(it,it2,']'); +- +- temp = it; +- while (temp != uri_string.end()) { +- if (*temp == ']') { +- break; +- } +- ++temp; +- } +- +- if (temp == uri_string.end()) { +- return; +- } else { +- // validate IPv6 literal parts +- // can contain numbers, a-f and A-F +- m_host.append(it,temp); +- } +- it = temp+1; +- if (it == uri_string.end()) { +- state = 2; +- } else if (*it == '/') { +- state = 2; +- ++it; +- } else if (*it == ':') { +- state = 1; +- ++it; +- } else { +- // problem +- return; +- } +- } else { +- // IPv4 or hostname +- // extract until : or / +- while (state == 0) { +- if (it == uri_string.end()) { +- state = 2; +- break; +- } else if (*it == '/') { +- state = 2; +- } else if (*it == ':') { +- // end hostname start port +- state = 1; +- } else { +- m_host += *it; +- } +- ++it; +- } +- } +- +- // parse port +- std::string port; +- while (state == 1) { +- if (it == uri_string.end()) { +- // state is not used after this point presently. +- // this should be re-enabled if it ever is needed in a future +- // refactoring +- //state = 3; +- break; +- } else if (*it == '/') { +- state = 3; +- } else { +- port += *it; +- } +- ++it; +- } +- +- lib::error_code ec; +- m_port = get_port_from_string(port, ec); +- +- if (ec) { +- return; +- } +- +- m_resource = "/"; +- m_resource.append(it,uri_string.end()); +- +- +- m_valid = true; +- } +- +- uri(bool secure, std::string const & host, uint16_t port, +- std::string const & resource) +- : m_scheme(secure ? "wss" : "ws") +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_port(port) +- , m_secure(secure) +- , m_valid(true) {} +- +- uri(bool secure, std::string const & host, std::string const & resource) +- : m_scheme(secure ? "wss" : "ws") +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_port(secure ? uri_default_secure_port : uri_default_port) +- , m_secure(secure) +- , m_valid(true) {} +- +- uri(bool secure, std::string const & host, std::string const & port, +- std::string const & resource) +- : m_scheme(secure ? "wss" : "ws") +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_secure(secure) +- { +- lib::error_code ec; +- m_port = get_port_from_string(port,ec); +- m_valid = !ec; +- } +- +- uri(std::string const & scheme, std::string const & host, uint16_t port, +- std::string const & resource) +- : m_scheme(scheme) +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_port(port) +- , m_secure(scheme == "wss" || scheme == "https") +- , m_valid(true) {} +- +- uri(std::string scheme, std::string const & host, std::string const & resource) +- : m_scheme(scheme) +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_port((scheme == "wss" || scheme == "https") ? uri_default_secure_port : uri_default_port) +- , m_secure(scheme == "wss" || scheme == "https") +- , m_valid(true) {} +- +- uri(std::string const & scheme, std::string const & host, +- std::string const & port, std::string const & resource) +- : m_scheme(scheme) +- , m_host(host) +- , m_resource(resource.empty() ? "/" : resource) +- , m_secure(scheme == "wss" || scheme == "https") +- { +- lib::error_code ec; +- m_port = get_port_from_string(port,ec); +- m_valid = !ec; +- } +- +- bool get_valid() const { +- return m_valid; +- } +- +- bool get_secure() const { +- return m_secure; +- } +- +- std::string const & get_scheme() const { +- return m_scheme; +- } +- +- std::string const & get_host() const { +- return m_host; +- } +- +- std::string get_host_port() const { +- if (m_port == (m_secure ? uri_default_secure_port : uri_default_port)) { +- return m_host; +- } else { +- std::stringstream p; +- p << m_host << ":" << m_port; +- return p.str(); +- } +- } +- +- std::string get_authority() const { +- std::stringstream p; +- p << m_host << ":" << m_port; +- return p.str(); +- } +- +- uint16_t get_port() const { +- return m_port; +- } +- +- std::string get_port_str() const { +- std::stringstream p; +- p << m_port; +- return p.str(); +- } +- +- std::string const & get_resource() const { +- return m_resource; +- } +- +- std::string str() const { +- std::stringstream s; +- +- s << m_scheme << "://" << m_host; +- +- if (m_port != (m_secure ? uri_default_secure_port : uri_default_port)) { +- s << ":" << m_port; +- } +- +- s << m_resource; +- return s.str(); +- } +- +- /// Return the query portion +- /** +- * Returns the query portion (after the ?) of the URI or an empty string if +- * there is none. +- * +- * @return query portion of the URI. +- */ +- std::string get_query() const { +- std::size_t found = m_resource.find('?'); +- if (found != std::string::npos) { +- return m_resource.substr(found + 1); +- } else { +- return ""; +- } +- } +- +- // get fragment +- +- // hi <3 +- +- // get the string representation of this URI +- +- //std::string base() const; // is this still needed? +- +- // setter methods set some or all (in the case of parse) based on the input. +- // These functions throw a uri_exception on failure. +- /*void set_uri(const std::string& uri); +- +- void set_secure(bool secure); +- void set_host(const std::string& host); +- void set_port(uint16_t port); +- void set_port(const std::string& port); +- void set_resource(const std::string& resource);*/ +-private: +- uint16_t get_port_from_string(std::string const & port, lib::error_code & +- ec) const +- { +- ec = lib::error_code(); +- +- if (port.empty()) { +- return (m_secure ? uri_default_secure_port : uri_default_port); +- } +- +- unsigned int t_port = static_cast(atoi(port.c_str())); +- +- if (t_port > 65535) { +- ec = error::make_error_code(error::invalid_port); +- } +- +- if (t_port == 0) { +- ec = error::make_error_code(error::invalid_port); +- } +- +- return static_cast(t_port); +- } +- +- std::string m_scheme; +- std::string m_host; +- std::string m_resource; +- uint16_t m_port; +- bool m_secure; +- bool m_valid; +-}; +- +-/// Pointer to a URI +-typedef lib::shared_ptr uri_ptr; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_URI_HPP +diff --git a/src/lib/websocketpp/utf8_validator.hpp b/src/lib/websocketpp/utf8_validator.hpp +deleted file mode 100644 +index bee383e..0000000 +--- a/src/lib/websocketpp/utf8_validator.hpp ++++ /dev/null +@@ -1,154 +0,0 @@ +-/* +- * The following code is adapted from code originally written by Bjoern +- * Hoehrmann . See +- * http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. +- * +- * The original license: +- * +- * Copyright (c) 2008-2009 Bjoern Hoehrmann +- * +- * Permission is hereby granted, free of charge, to any person obtaining a copy +- * of this software and associated documentation files (the "Software"), to deal +- * in the Software without restriction, including without limitation the rights +- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +- * copies of the Software, and to permit persons to whom the Software is +- * furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +- * SOFTWARE. +-*/ +- +-#ifndef UTF8_VALIDATOR_HPP +-#define UTF8_VALIDATOR_HPP +- +-#include +- +-#include +- +-namespace ws_websocketpp { +-namespace utf8_validator { +- +-/// State that represents a valid utf8 input sequence +-static unsigned int const utf8_accept = 0; +-/// State that represents an invalid utf8 input sequence +-static unsigned int const utf8_reject = 1; +- +-/// Lookup table for the UTF8 decode state machine +-static uint8_t const utf8d[] = { +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f +- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f +- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f +- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf +- 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df +- 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef +- 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff +- 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 +- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 +- 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 +- 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 +- 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +-}; +- +-/// Decode the next byte of a UTF8 sequence +-/** +- * @param [out] state The decoder state to advance +- * @param [out] codep The codepoint to fill in +- * @param [in] byte The byte to input +- * @return The ending state of the decode operation +- */ +-inline uint32_t decode(uint32_t * state, uint32_t * codep, uint8_t byte) { +- uint32_t type = utf8d[byte]; +- +- *codep = (*state != utf8_accept) ? +- (byte & 0x3fu) | (*codep << 6) : +- (0xff >> type) & (byte); +- +- *state = utf8d[256 + *state*16 + type]; +- return *state; +-} +- +-/// Provides streaming UTF8 validation functionality +-class validator { +-public: +- /// Construct and initialize the validator +- validator() : m_state(utf8_accept),m_codepoint(0) {} +- +- /// Advance the state of the validator with the next input byte +- /** +- * @param byte The byte to advance the validation state with +- * @return Whether or not the byte resulted in a validation error. +- */ +- bool consume (uint8_t byte) { +- if (utf8_validator::decode(&m_state,&m_codepoint,byte) == utf8_reject) { +- return false; +- } +- return true; +- } +- +- /// Advance validator state with input from an iterator pair +- /** +- * @param begin Input iterator to the start of the input range +- * @param end Input iterator to the end of the input range +- * @return Whether or not decoding the bytes resulted in a validation error. +- */ +- template +- bool decode (iterator_type begin, iterator_type end) { +- for (iterator_type it = begin; it != end; ++it) { +- unsigned int result = utf8_validator::decode( +- &m_state, +- &m_codepoint, +- static_cast(*it) +- ); +- +- if (result == utf8_reject) { +- return false; +- } +- } +- return true; +- } +- +- /// Return whether the input sequence ended on a valid utf8 codepoint +- /** +- * @return Whether or not the input sequence ended on a valid codepoint. +- */ +- bool complete() { +- return m_state == utf8_accept; +- } +- +- /// Reset the validator to decode another message +- void reset() { +- m_state = utf8_accept; +- m_codepoint = 0; +- } +-private: +- uint32_t m_state; +- uint32_t m_codepoint; +-}; +- +-/// Validate a UTF8 string +-/** +- * convenience function that creates a validator, validates a complete string +- * and returns the result. +- */ +-inline bool validate(std::string const & s) { +- validator v; +- if (!v.decode(s.begin(),s.end())) { +- return false; +- } +- return v.complete(); +-} +- +-} // namespace utf8_validator +-} // namespace ws_websocketpp +- +-#endif // UTF8_VALIDATOR_HPP +diff --git a/src/lib/websocketpp/utilities.hpp b/src/lib/websocketpp/utilities.hpp +deleted file mode 100644 +index 08809ec..0000000 +--- a/src/lib/websocketpp/utilities.hpp ++++ /dev/null +@@ -1,180 +0,0 @@ +-/* +- * 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. +- * +- */ +- +-#ifndef WEBSOCKETPP_UTILITIES_HPP +-#define WEBSOCKETPP_UTILITIES_HPP +- +-#include +- +-#include +-#include +-#include +- +-namespace ws_websocketpp { +-/// Generic non-websocket specific utility functions and data structures +-namespace utility { +- +-/// Helper functor for case insensitive find +-/** +- * Based on code from +- * http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find +- * +- * templated version of my_equal so it could work with both char and wchar_t +- */ +-template +-struct my_equal { +- /// Construct the functor with the given locale +- /** +- * @param [in] loc The locale to use for determining the case of values +- */ +- my_equal(std::locale const & loc ) : m_loc(loc) {} +- +- /// Perform a case insensitive comparison +- /** +- * @param ch1 The first value to compare +- * @param ch2 The second value to compare +- * @return Whether or not the two values are equal when both are converted +- * to uppercase using the given locale. +- */ +- bool operator()(charT ch1, charT ch2) { +- return std::toupper(ch1, m_loc) == std::toupper(ch2, m_loc); +- } +-private: +- std::locale const & m_loc; +-}; +- +-/// Helper less than functor for case insensitive find +-/** +- * Based on code from +- * http://stackoverflow.com/questions/3152241/case-insensitive-stdstring-find +- */ +-struct ci_less { +- // case-independent (ci) compare_less binary function +- struct nocase_compare { +- bool operator() (unsigned char const & c1, unsigned char const & c2) const { +- return tolower (c1) < tolower (c2); +- } +- }; +- bool operator() (std::string const & s1, std::string const & s2) const { +- return std::lexicographical_compare +- (s1.begin (), s1.end (), // source range +- s2.begin (), s2.end (), // dest range +- nocase_compare ()); // comparison +- } +-}; +- +-/// Find substring (case insensitive) +-/** +- * @param [in] haystack The string to search in +- * @param [in] needle The string to search for +- * @param [in] loc The locale to use for determining the case of values. +- * Defaults to the current locale. +- * @return An iterator to the first element of the first occurrance of needle in +- * haystack. If the sequence is not found, the function returns +- * haystack.end() +- */ +-template +-typename T::const_iterator ci_find_substr(T const & haystack, T const & needle, +- std::locale const & loc = std::locale()) +-{ +- return std::search( haystack.begin(), haystack.end(), +- needle.begin(), needle.end(), my_equal(loc) ); +-} +- +-/// Find substring (case insensitive) +-/** +- * @todo Is this still used? This method may not make sense.. should use +- * iterators or be less generic. As is it is too tightly coupled to std::string +- * +- * @param [in] haystack The string to search in +- * @param [in] needle The string to search for as a char array of values +- * @param [in] size Length of needle +- * @param [in] loc The locale to use for determining the case of values. +- * Defaults to the current locale. +- * @return An iterator to the first element of the first occurrance of needle in +- * haystack. If the sequence is not found, the function returns +- * haystack.end() +- */ +-template +-typename T::const_iterator ci_find_substr(T const & haystack, +- typename T::value_type const * needle, typename T::size_type size, +- std::locale const & loc = std::locale()) +-{ +- return std::search( haystack.begin(), haystack.end(), +- needle, needle+size, my_equal(loc) ); +-} +- +-/// Convert a string to lowercase +-/** +- * @param [in] in The string to convert +- * @return The converted string +- */ +-std::string to_lower(std::string const & in); +- +-/// Replace all occurrances of a substring with another +-/** +- * @param [in] subject The string to search in +- * @param [in] search The string to search for +- * @param [in] replace The string to replace with +- * @return A copy of `subject` with all occurances of `search` replaced with +- * `replace` +- */ +-std::string string_replace_all(std::string subject, std::string const & search, +- std::string const & replace); +- +-/// Convert std::string to ascii printed string of hex digits +-/** +- * @param [in] input The string to print +- * @return A copy of `input` converted to the printable representation of the +- * hex values of its data. +- */ +-std::string to_hex(std::string const & input); +- +-/// Convert byte array (uint8_t) to ascii printed string of hex digits +-/** +- * @param [in] input The byte array to print +- * @param [in] length The length of input +- * @return A copy of `input` converted to the printable representation of the +- * hex values of its data. +- */ +-std::string to_hex(uint8_t const * input, size_t length); +- +-/// Convert char array to ascii printed string of hex digits +-/** +- * @param [in] input The char array to print +- * @param [in] length The length of input +- * @return A copy of `input` converted to the printable representation of the +- * hex values of its data. +- */ +-std::string to_hex(char const * input, size_t length); +- +-} // namespace utility +-} // namespace ws_websocketpp +- +-#include +- +-#endif // WEBSOCKETPP_UTILITIES_HPP +diff --git a/src/lib/websocketpp/version.hpp b/src/lib/websocketpp/version.hpp +deleted file mode 100644 +index b2ade4d..0000000 +--- a/src/lib/websocketpp/version.hpp ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* +- * Copyright (c) 2015, Peter Thorson. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions are met: +- * * Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * * Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * * Neither the name of the WebSocket++ Project nor the +- * names of its contributors may be used to endorse or promote products +- * derived from this software without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY +- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- */ +- +-#ifndef WEBSOCKETPP_VERSION_HPP +-#define WEBSOCKETPP_VERSION_HPP +- +-/// Namespace for the WebSocket++ project +-namespace ws_websocketpp { +- +-/* +- other places where version information is kept +- - readme.md +- - changelog.md +- - Doxyfile +- - CMakeLists.txt +-*/ +- +-/// Library major version number +-static int const major_version = 0; +-/// Library minor version number +-static int const minor_version = 8; +-/// Library patch version number +-static int const patch_version = 1; +-/// Library pre-release flag +-/** +- * 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. +- */ +- +-static char const prerelease_flag[] = ""; +- +-/// Default user agent string +-static char const user_agent[] = "WebSocket++/0.8.1"; +- +-} // namespace ws_websocketpp +- +-#endif // WEBSOCKETPP_VERSION_HPP +-- +2.21.0 + diff --git a/0002-Use-local-echo-server-for-testing-websockets.patch b/0002-Use-local-echo-server-for-testing-websockets.patch new file mode 100644 index 0000000..0feaf71 --- /dev/null +++ b/0002-Use-local-echo-server-for-testing-websockets.patch @@ -0,0 +1,104 @@ +From 5d360a0d22ed131ca0073a3f554b85ca78ae953c Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Wed, 25 Sep 2019 05:43:49 -0400 +Subject: [PATCH 2/2] Use local echo server for testing websockets. + +Signed-off-by: Elliott Sales de Andrade +--- + tests/testthat/test-client.R | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/tests/testthat/test-client.R b/tests/testthat/test-client.R +index ef1124b..226c100 100644 +--- a/tests/testthat/test-client.R ++++ b/tests/testthat/test-client.R +@@ -1,7 +1,7 @@ + + test_that("Connection can't be defined with invalid maxMessageSize", { +- expect_error(WebSocket$new("ws://echo.websocket.org/", maxMessageSize=-1), "maxMessageSize must be a non-negative integer") +- expect_error(WebSocket$new("ws://echo.websocket.org/", maxMessageSize=1:2), "maxMessageSize must be a non-negative integer") ++ expect_error(WebSocket$new("ws://localhost:8765/", maxMessageSize=-1), "maxMessageSize must be a non-negative integer") ++ expect_error(WebSocket$new("ws://localhost:8765/", maxMessageSize=1:2), "maxMessageSize must be a non-negative integer") + }) + + check_later <- function( +@@ -44,7 +44,7 @@ test_that("small maxMessageSizes break simple connections", { + state <- NULL + didFail <- FALSE + +- ws <- WebSocket$new("ws://echo.websocket.org/", maxMessageSize=2) ++ ws <- WebSocket$new("ws://localhost:8765/", maxMessageSize=2) + ws$onMessage(function(event) { + + }) +@@ -143,13 +143,13 @@ check_ws <- function(wsUrl) { + + context("Basic WebSocket") + test_that("Basic websocket communication", { +- check_ws("ws://echo.websocket.org/") ++ check_ws("ws://localhost:8765/") + }) + + test_that("WebSocket object can be garbage collected", { + collected <- FALSE + local({ +- ws <- WebSocket$new("ws://echo.websocket.org/") ++ ws <- WebSocket$new("ws://localhost:8765/") + ws$onOpen(function(event) { + ws$close() + }) +@@ -167,7 +167,7 @@ test_that("WebSocket object can be garbage collected", { + }) + + test_that("Open is async", { +- ws <- WebSocket$new("ws://echo.websocket.org") ++ ws <- WebSocket$new("ws://localhost:8765") + ws$onOpen(function(event) { + ws$close() + }) +@@ -193,7 +193,7 @@ test_that("Connection errors are reported", { + test_that("Connect can be delayed", { + # With autoConnect = TRUE (the default), you can miss the onOpen event + connected <- FALSE +- ws <- WebSocket$new("ws://echo.websocket.org") ++ ws <- WebSocket$new("ws://localhost:8765") + for (i in 1:100) { + later::run_now(0.1) + if (later::loop_empty() || ws$readyState() >= 1L) { +@@ -211,7 +211,7 @@ test_that("Connect can be delayed", { + # With autoConnect = FALSE, the open event is guaranteed not to fire + # until after connect() is called + connected <- FALSE +- ws <- WebSocket$new("ws://echo.websocket.org", autoConnect = FALSE) ++ ws <- WebSocket$new("ws://localhost:8765", autoConnect = FALSE) + for (i in 1:100) { + later::run_now(0.1) + if (later::loop_empty() || ws$readyState() >= 1L) { +@@ -234,7 +234,7 @@ test_that("Connect can be delayed", { + + test_that("WebSocket can be closed before being opened or after being closed", { + onCloseCalled <- FALSE +- ws <- WebSocket$new("ws://echo.websocket.org") ++ ws <- WebSocket$new("ws://localhost:8765") + ws$close() + ws$onClose(function(event) { + onCloseCalled <<- TRUE +@@ -250,7 +250,7 @@ test_that("WebSocket event handlers can be registered more than once", { + a_called <- FALSE + b_called <- FALSE + c_called <- FALSE +- ws <- WebSocket$new("ws://echo.websocket.org") ++ ws <- WebSocket$new("ws://localhost:8765") + ws$onOpen(function(event) { + a_called <<- TRUE + }) +@@ -274,5 +274,6 @@ test_that("WebSocket event handlers can be registered more than once", { + + context("Basic SSL WebSocket") + test_that("Basic ssl websocket communication", { ++ skip_if_offline() + check_ws("wss://echo.websocket.org/") + }) +-- +2.21.0 + diff --git a/R-websocket.spec b/R-websocket.spec new file mode 100644 index 0000000..05a8d29 --- /dev/null +++ b/R-websocket.spec @@ -0,0 +1,89 @@ +%global packname websocket +%global rlibdir %{_libdir}/R/library + +Name: R-%{packname} +Version: 1.1.0 +Release: 1%{?dist} +Summary: 'WebSocket' Client Library + +License: GPLv2 +URL: https://CRAN.R-project.org/package=%{packname} +Source0: https://cran.r-project.org/src/contrib/%{packname}_%{version}.tar.gz +# For testing only. +Source1: echo.py +# https://github.com/rstudio/websocket/issues/59 +Patch0001: 0001-Unbundle-websocketpp.patch +# For no-network testing. +Patch0002: 0002-Use-local-echo-server-for-testing-websockets.patch + +# Here's the R view of the dependencies world: +# Depends: +# Imports: R-Rcpp, R-R6, R-later +# Suggests: R-testthat, R-knitr, R-rmarkdown +# LinkingTo: R-Rcpp, R-BH, R-AsioHeaders +# Enhances: + +BuildRequires: R-devel +BuildRequires: tex(latex) +BuildRequires: R-Rcpp-devel +BuildRequires: R-R6 +BuildRequires: R-later +BuildRequires: R-testthat +BuildRequires: R-knitr +BuildRequires: R-rmarkdown +BuildRequires: R-BH-devel +BuildRequires: R-AsioHeaders-devel +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(websocketpp) +BuildRequires: python3dist(websockets) + +%description +Provides a WebSocket client interface for R. WebSocket is a protocol for +low-overhead real-time communication: +. + + +%prep +%setup -q -c -n %{packname} + +pushd %{packname} +# Unbundle websocketpp +%patch0001 -p1 +# Disable network usage +%patch0002 -p1 +popd + + +%build + + +%install +mkdir -p %{buildroot}%{rlibdir} +%{_bindir}/R CMD INSTALL -l %{buildroot}%{rlibdir} %{packname} +test -d %{packname}/src && (cd %{packname}/src; rm -f *.o *.so) +rm -f %{buildroot}%{rlibdir}/R.css + + +%check +%{__python3} %SOURCE1 & +%{_bindir}/R CMD check %{packname} + + +%files +%dir %{rlibdir}/%{packname} +%doc %{rlibdir}/%{packname}/doc +%doc %{rlibdir}/%{packname}/html +%{rlibdir}/%{packname}/DESCRIPTION +%doc %{rlibdir}/%{packname}/NEWS.md +%{rlibdir}/%{packname}/INDEX +%{rlibdir}/%{packname}/NAMESPACE +%{rlibdir}/%{packname}/Meta +%{rlibdir}/%{packname}/R +%{rlibdir}/%{packname}/help +%dir %{rlibdir}/%{packname}/libs +%{rlibdir}/%{packname}/libs/%{packname}.so + + +%changelog +* Wed Sep 11 2019 Elliott Sales de Andrade - 1.1.0-1 +- initial package for Fedora diff --git a/echo.py b/echo.py new file mode 100644 index 0000000..a993409 --- /dev/null +++ b/echo.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 + +import asyncio +import websockets + + +async def echo(websocket, path): + while True: + try: + async for message in websocket: + await websocket.send(message) + except websockets.exceptions.ConnectionClosedError: + # Ignore too-large messages, sent as part of the test. + pass + + +server = websockets.serve(echo, 'localhost', 8765) +asyncio.get_event_loop().run_until_complete(server) +asyncio.get_event_loop().run_forever() diff --git a/sources b/sources new file mode 100644 index 0000000..feea373 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (websocket_1.1.0.tar.gz) = 9d34c8f0335ffb3cbbe35b06cc111d1249cf7255d4af9f082d40b0b271d204b9b0eca470bfa2e14d214f8f8e8eec0423addc0a2b93d9c8a146b5d0d0ad305e0b