Updating websocketpp to latest git.
This commit is contained in:
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
Main Library:
|
Main Library:
|
||||||
|
|
||||||
Copyright (c) 2013, Peter Thorson. All rights reserved.
|
Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+35
-13
@@ -45,6 +45,11 @@ static std::string const base64_chars =
|
|||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
"0123456789+/";
|
"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) {
|
static inline bool is_base64(unsigned char c) {
|
||||||
return (c == 43 || // +
|
return (c == 43 || // +
|
||||||
(c >= 47 && c <= 57) || // /-9
|
(c >= 47 && c <= 57) || // /-9
|
||||||
@@ -52,17 +57,21 @@ static inline bool is_base64(unsigned char c) {
|
|||||||
(c >= 97 && c <= 122)); // a-z
|
(c >= 97 && c <= 122)); // a-z
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
/// Encode a char buffer into a base64 string
|
||||||
int in_len)
|
/**
|
||||||
{
|
* @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;
|
std::string ret;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
unsigned char char_array_3[3];
|
unsigned char char_array_3[3];
|
||||||
unsigned char char_array_4[4];
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
while (in_len--) {
|
while (len--) {
|
||||||
char_array_3[i++] = *(bytes_to_encode++);
|
char_array_3[i++] = *(input++);
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
|
||||||
@@ -97,25 +106,38 @@ inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
|||||||
while((i++ < 3)) {
|
while((i++ < 3)) {
|
||||||
ret += '=';
|
ret += '=';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string base64_encode(std::string const & data) {
|
/// Encode a string into a base64 string
|
||||||
return base64_encode(reinterpret_cast<const unsigned char *>(data.data()),data.size());
|
/**
|
||||||
|
* @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<const unsigned char *>(input.data()),
|
||||||
|
input.size()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string base64_decode(std::string const & encoded_string) {
|
/// Decode a base64 encoded string into a string of raw bytes
|
||||||
size_t in_len = encoded_string.size();
|
/**
|
||||||
|
* @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 i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
int in_ = 0;
|
int in_ = 0;
|
||||||
unsigned char char_array_4[4], char_array_3[3];
|
unsigned char char_array_4[4], char_array_3[3];
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
||||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
|
||||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
char_array_4[i++] = input[in_]; in_++;
|
||||||
if (i ==4) {
|
if (i ==4) {
|
||||||
for (i = 0; i <4; i++) {
|
for (i = 0; i <4; i++) {
|
||||||
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
|
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+41
-1
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -199,6 +199,46 @@ namespace status {
|
|||||||
code == policy_violation || code == message_too_big ||
|
code == policy_violation || code == message_too_big ||
|
||||||
code == internal_endpoint_error);
|
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 tls_handshake:
|
||||||
|
return "TLS handshake failure";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace status
|
} // namespace status
|
||||||
|
|
||||||
/// Type used to convert close statuses between integer and wire representations
|
/// Type used to convert close statuses between integer and wire representations
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,7 +34,7 @@ namespace websocketpp {
|
|||||||
|
|
||||||
/// A handle to uniquely identify a connection.
|
/// A handle to uniquely identify a connection.
|
||||||
/**
|
/**
|
||||||
* This type uniquely identifies a connection. It is implimented as a weak
|
* This type uniquely identifies a connection. It is implemented as a weak
|
||||||
* pointer to the connection in question. This provides uniqueness across
|
* pointer to the connection in question. This provides uniqueness across
|
||||||
* multiple endpoints and ensures that IDs never conflict or run out.
|
* multiple endpoints and ensures that IDs never conflict or run out.
|
||||||
*
|
*
|
||||||
|
|||||||
+54
-4
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -40,10 +40,29 @@
|
|||||||
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
|
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
|
||||||
#endif
|
#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.
|
||||||
|
|
||||||
#ifdef _WEBSOCKETPP_CPP11_STL_
|
#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_)
|
||||||
// This flag indicates that all of the C++11 language features are available
|
// This check tests for blanket c++11 coverage. It can be activated in one
|
||||||
// to us.
|
// 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:
|
||||||
|
|
||||||
|
// _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_
|
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
||||||
#endif
|
#endif
|
||||||
@@ -53,7 +72,19 @@
|
|||||||
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
|
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
|
||||||
|
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||||
|
#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
|
#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
|
// Test for noexcept
|
||||||
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||||
#ifdef _WEBSOCKETPP_NOEXCEPT_
|
#ifdef _WEBSOCKETPP_NOEXCEPT_
|
||||||
@@ -90,6 +121,25 @@
|
|||||||
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
|
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
|
||||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||||
#endif
|
#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 _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
|
||||||
|
|
||||||
#endif // WEBSOCKETPP_COMMON_CPP11_HPP
|
#endif // WEBSOCKETPP_COMMON_CPP11_HPP
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -39,8 +39,11 @@
|
|||||||
#else
|
#else
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace lib {
|
namespace lib {
|
||||||
|
|
||||||
@@ -49,6 +52,18 @@ namespace lib {
|
|||||||
using std::bind;
|
using std::bind;
|
||||||
using std::ref;
|
using std::ref;
|
||||||
namespace placeholders = std::placeholders;
|
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 <typename T>
|
||||||
|
void clear_function(T & x) {
|
||||||
|
x = nullptr;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
using boost::function;
|
using boost::function;
|
||||||
using boost::bind;
|
using boost::bind;
|
||||||
@@ -58,6 +73,14 @@ namespace lib {
|
|||||||
using ::_1;
|
using ::_1;
|
||||||
using ::_2;
|
using ::_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See above definition for more details on what this is and why it exists
|
||||||
|
#define _WEBSOCKETPP_REF(x) boost::ref(x)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void clear_function(T & x) {
|
||||||
|
x.clear();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace lib
|
} // namespace lib
|
||||||
|
|||||||
+70
-70
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||||
text is available at
|
text is available at
|
||||||
http://www.ietf.org/rfc/rfc1321.txt
|
http://www.ietf.org/rfc/rfc1321.txt
|
||||||
The code is derived from the text of the RFC, including the test suite
|
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
|
(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
|
any code or documentation that is identified in the RFC as being
|
||||||
@@ -45,12 +45,12 @@
|
|||||||
that follows (in reverse chronological order):
|
that follows (in reverse chronological order):
|
||||||
|
|
||||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||||
references to Ghostscript; clarified derivation from RFC 1321;
|
references to Ghostscript; clarified derivation from RFC 1321;
|
||||||
now handles byte order either statically or dynamically.
|
now handles byte order either statically or dynamically.
|
||||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||||
added conditionalization for C++ compilation from Martin
|
added conditionalization for C++ compilation from Martin
|
||||||
Purschke <purschke@bnl.gov>.
|
Purschke <purschke@bnl.gov>.
|
||||||
1999-05-03 lpd Original version.
|
1999-05-03 lpd Original version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ typedef unsigned int md5_word_t; /* 32-bit word */
|
|||||||
|
|
||||||
/* Define the state of the MD5 Algorithm. */
|
/* Define the state of the MD5 Algorithm. */
|
||||||
typedef struct md5_state_s {
|
typedef struct md5_state_s {
|
||||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||||
md5_word_t abcd[4]; /* digest buffer */
|
md5_word_t abcd[4]; /* digest buffer */
|
||||||
md5_byte_t buf[64]; /* accumulate block */
|
md5_byte_t buf[64]; /* accumulate block */
|
||||||
} md5_state_t;
|
} md5_state_t;
|
||||||
|
|
||||||
/* Initialize the algorithm. */
|
/* Initialize the algorithm. */
|
||||||
@@ -94,7 +94,7 @@ inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes)
|
|||||||
/* Finish the message and return the digest. */
|
/* Finish the message and return the digest. */
|
||||||
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
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 */
|
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||||
#ifdef ARCH_IS_BIG_ENDIAN
|
#ifdef ARCH_IS_BIG_ENDIAN
|
||||||
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||||
#else
|
#else
|
||||||
@@ -169,8 +169,8 @@ inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
|||||||
|
|
||||||
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||||
md5_word_t
|
md5_word_t
|
||||||
a = pms->abcd[0], b = pms->abcd[1],
|
a = pms->abcd[0], b = pms->abcd[1],
|
||||||
c = pms->abcd[2], d = pms->abcd[3];
|
c = pms->abcd[2], d = pms->abcd[3];
|
||||||
md5_word_t t;
|
md5_word_t t;
|
||||||
#if ZSW_MD5_BYTE_ORDER > 0
|
#if ZSW_MD5_BYTE_ORDER > 0
|
||||||
/* Define storage only for big-endian CPUs. */
|
/* Define storage only for big-endian CPUs. */
|
||||||
@@ -183,51 +183,51 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
#if ZSW_MD5_BYTE_ORDER == 0
|
#if ZSW_MD5_BYTE_ORDER == 0
|
||||||
/*
|
/*
|
||||||
* Determine dynamically whether this is a big-endian or
|
* Determine dynamically whether this is a big-endian or
|
||||||
* little-endian machine, since we can use a more efficient
|
* little-endian machine, since we can use a more efficient
|
||||||
* algorithm on the latter.
|
* algorithm on the latter.
|
||||||
*/
|
*/
|
||||||
static int const w = 1;
|
static int const w = 1;
|
||||||
|
|
||||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On little-endian machines, we can process properly aligned
|
* On little-endian machines, we can process properly aligned
|
||||||
* data without copying it.
|
* data without copying it.
|
||||||
*/
|
*/
|
||||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||||
/* data are properly aligned */
|
/* data are properly aligned */
|
||||||
X = (md5_word_t const *)data;
|
X = (md5_word_t const *)data;
|
||||||
} else {
|
} else {
|
||||||
/* not aligned */
|
/* not aligned */
|
||||||
std::memcpy(xbuf, data, 64);
|
std::memcpy(xbuf, data, 64);
|
||||||
X = xbuf;
|
X = xbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER == 0
|
#if ZSW_MD5_BYTE_ORDER == 0
|
||||||
else /* dynamic big-endian */
|
else /* dynamic big-endian */
|
||||||
#endif
|
#endif
|
||||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* On big-endian machines, we must arrange the bytes in the
|
* On big-endian machines, we must arrange the bytes in the
|
||||||
* right order.
|
* right order.
|
||||||
*/
|
*/
|
||||||
const md5_byte_t *xp = data;
|
const md5_byte_t *xp = data;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
# if ZSW_MD5_BYTE_ORDER == 0
|
# if ZSW_MD5_BYTE_ORDER == 0
|
||||||
X = xbuf; /* (dynamic only) */
|
X = xbuf; /* (dynamic only) */
|
||||||
# else
|
# else
|
||||||
# define xbuf X /* (static only) */
|
# define xbuf X /* (static only) */
|
||||||
# endif
|
# endif
|
||||||
for (i = 0; i < 16; ++i, xp += 4)
|
for (i = 0; i < 16; ++i, xp += 4)
|
||||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,71 +361,71 @@ void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
|
|||||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||||
|
|
||||||
if (nbytes <= 0)
|
if (nbytes <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Update the message length. */
|
/* Update the message length. */
|
||||||
pms->count[1] += nbytes >> 29;
|
pms->count[1] += nbytes >> 29;
|
||||||
pms->count[0] += nbits;
|
pms->count[0] += nbits;
|
||||||
if (pms->count[0] < nbits)
|
if (pms->count[0] < nbits)
|
||||||
pms->count[1]++;
|
pms->count[1]++;
|
||||||
|
|
||||||
/* Process an initial partial block. */
|
/* Process an initial partial block. */
|
||||||
if (offset) {
|
if (offset) {
|
||||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||||
|
|
||||||
std::memcpy(pms->buf + offset, p, copy);
|
std::memcpy(pms->buf + offset, p, copy);
|
||||||
if (offset + copy < 64)
|
if (offset + copy < 64)
|
||||||
return;
|
return;
|
||||||
p += copy;
|
p += copy;
|
||||||
left -= copy;
|
left -= copy;
|
||||||
md5_process(pms, pms->buf);
|
md5_process(pms, pms->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process full blocks. */
|
/* Process full blocks. */
|
||||||
for (; left >= 64; p += 64, left -= 64)
|
for (; left >= 64; p += 64, left -= 64)
|
||||||
md5_process(pms, p);
|
md5_process(pms, p);
|
||||||
|
|
||||||
/* Process a final partial block. */
|
/* Process a final partial block. */
|
||||||
if (left)
|
if (left)
|
||||||
std::memcpy(pms->buf, p, left);
|
std::memcpy(pms->buf, p, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||||
static md5_byte_t const pad[64] = {
|
static md5_byte_t const pad[64] = {
|
||||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
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,
|
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];
|
md5_byte_t data[8];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Save the length before padding. */
|
/* Save the length before padding. */
|
||||||
for (i = 0; i < 8; ++i)
|
for (i = 0; i < 8; ++i)
|
||||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||||
/* Pad to 56 bytes mod 64. */
|
/* Pad to 56 bytes mod 64. */
|
||||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||||
/* Append the length. */
|
/* Append the length. */
|
||||||
md5_append(pms, data, 8);
|
md5_append(pms, data, 8);
|
||||||
for (i = 0; i < 16; ++i)
|
for (i = 0; i < 16; ++i)
|
||||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
// some convenience c++ functions
|
// some convenience c++ functions
|
||||||
inline std::string md5_hash_string(std::string const & s) {
|
inline std::string md5_hash_string(std::string const & s) {
|
||||||
char digest[16];
|
char digest[16];
|
||||||
|
|
||||||
md5_state_t state;
|
md5_state_t state;
|
||||||
|
|
||||||
md5_init(&state);
|
md5_init(&state);
|
||||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||||
md5_finish(&state, (md5_byte_t *)digest);
|
md5_finish(&state, (md5_byte_t *)digest);
|
||||||
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.resize(16);
|
ret.resize(16);
|
||||||
std::copy(digest,digest+16,ret.begin());
|
std::copy(digest,digest+16,ret.begin());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#else
|
#else
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/scoped_array.hpp>
|
#include <boost/scoped_array.hpp>
|
||||||
#include <boost/enable_shared_from_this.hpp>
|
#include <boost/enable_shared_from_this.hpp>
|
||||||
#include <boost/pointer_cast.hpp>
|
#include <boost/pointer_cast.hpp>
|
||||||
@@ -51,6 +52,7 @@ namespace lib {
|
|||||||
using std::weak_ptr;
|
using std::weak_ptr;
|
||||||
using std::enable_shared_from_this;
|
using std::enable_shared_from_this;
|
||||||
using std::static_pointer_cast;
|
using std::static_pointer_cast;
|
||||||
|
using std::make_shared;
|
||||||
|
|
||||||
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
|
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
|
||||||
#else
|
#else
|
||||||
@@ -58,6 +60,7 @@ namespace lib {
|
|||||||
using boost::weak_ptr;
|
using boost::weak_ptr;
|
||||||
using boost::enable_shared_from_this;
|
using boost::enable_shared_from_this;
|
||||||
using boost::static_pointer_cast;
|
using boost::static_pointer_cast;
|
||||||
|
using boost::make_shared;
|
||||||
|
|
||||||
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
|
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+27
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
#define WEBSOCKETPP_COMMON_NETWORK_HPP
|
#define WEBSOCKETPP_COMMON_NETWORK_HPP
|
||||||
|
|
||||||
// For ntohs and htons
|
// For ntohs and htons
|
||||||
#if defined(WIN32)
|
#if defined(_WIN32)
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
//#include <arpa/inet.h>
|
//#include <arpa/inet.h>
|
||||||
@@ -50,7 +50,18 @@ inline bool is_little_endian() {
|
|||||||
#define TYP_SMLE 1
|
#define TYP_SMLE 1
|
||||||
#define TYP_BIGE 2
|
#define TYP_BIGE 2
|
||||||
|
|
||||||
inline uint64_t htonll(uint64_t src) {
|
/// 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;
|
static int typ = TYP_INIT;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
union {
|
union {
|
||||||
@@ -71,8 +82,19 @@ inline uint64_t htonll(uint64_t src) {
|
|||||||
return x.ull;
|
return x.ull;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t ntohll(uint64_t src) {
|
/// Convert 64 bit value to host byte order
|
||||||
return htonll(src);
|
/**
|
||||||
|
* 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
|
} // net
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
* don't fit somewhere else better.
|
* don't fit somewhere else better.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(NOMINMAX)
|
#if defined(_WIN32) && !defined(NOMINMAX)
|
||||||
// don't define min and max macros that conflict with std::min and std::max
|
// don't define min and max macros that conflict with std::min and std::max
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
#define __STDC_LIMIT_MACROS 1
|
#define __STDC_LIMIT_MACROS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WIN32 && (_MSC_VER < 1600)
|
#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600)
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
using boost::int8_t;
|
using boost::int8_t;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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 <time.h>
|
||||||
|
|
||||||
|
namespace 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(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
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -29,26 +29,48 @@
|
|||||||
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
|
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
|
|
||||||
|
/// Concurrency handling support
|
||||||
namespace concurrency {
|
namespace concurrency {
|
||||||
|
|
||||||
|
/// Implementation for no-op locking primitives
|
||||||
namespace none_impl {
|
namespace none_impl {
|
||||||
|
/// A fake mutex implementation that does nothing
|
||||||
class fake_mutex {
|
class fake_mutex {
|
||||||
public:
|
public:
|
||||||
fake_mutex() {}
|
fake_mutex() {}
|
||||||
~fake_mutex() {}
|
~fake_mutex() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A fake lock guard implementation that does nothing
|
||||||
class fake_lock_guard {
|
class fake_lock_guard {
|
||||||
public:
|
public:
|
||||||
explicit fake_lock_guard(fake_mutex foo) {}
|
explicit fake_lock_guard(fake_mutex) {}
|
||||||
~fake_lock_guard() {}
|
~fake_lock_guard() {}
|
||||||
};
|
};
|
||||||
} // namespace none_impl
|
} // namespace none_impl
|
||||||
|
|
||||||
/// Stub Concurrency policy to remove locking in single threaded projects
|
/// 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 {
|
class none {
|
||||||
public:
|
public:
|
||||||
|
/// The type of a mutex primitive
|
||||||
|
/**
|
||||||
|
* std::mutex is an example.
|
||||||
|
*/
|
||||||
typedef none_impl::fake_mutex mutex_type;
|
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;
|
typedef none_impl::fake_lock_guard scoped_lock_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -25,9 +25,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This header defines WebSocket++ macros for C++11 compatibility based on the Boost.Config library.
|
// This header defines WebSocket++ macros for C++11 compatibility based on the
|
||||||
// This will correctly configure most target platforms simply by including this header before
|
// Boost.Config library. This will correctly configure most target platforms
|
||||||
// any other WebSocket++ header.
|
// simply by including this header before any other WebSocket++ header.
|
||||||
|
|
||||||
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||||
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BOOST_ASIO_HAS_STD_CHRONO
|
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||||
#define _WEBSOCKETPP_CPP11_CHRONO_
|
#define _WEBSOCKETPP_CPP11_CHRONO_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -67,5 +67,6 @@
|
|||||||
|
|
||||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
|
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
|
||||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
|
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
|
||||||
|
// TODO: nullptr support
|
||||||
|
|
||||||
#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
#endif // WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||||
|
|||||||
+13
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -215,6 +215,18 @@ struct core {
|
|||||||
*/
|
*/
|
||||||
static const bool silent_close = false;
|
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;
|
||||||
|
|
||||||
/// Global flag for enabling/disabling extensions
|
/// Global flag for enabling/disabling extensions
|
||||||
static const bool enable_extensions = true;
|
static const bool enable_extensions = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,7 +34,11 @@
|
|||||||
#include <websocketpp/common/stdint.hpp>
|
#include <websocketpp/common/stdint.hpp>
|
||||||
|
|
||||||
// Concurrency
|
// Concurrency
|
||||||
|
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||||
#include <websocketpp/concurrency/basic.hpp>
|
#include <websocketpp/concurrency/basic.hpp>
|
||||||
|
#else
|
||||||
|
#include <websocketpp/concurrency/none.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Transport
|
// Transport
|
||||||
#include <websocketpp/transport/iostream/endpoint.hpp>
|
#include <websocketpp/transport/iostream/endpoint.hpp>
|
||||||
@@ -68,7 +72,11 @@ struct core_client {
|
|||||||
typedef core_client type;
|
typedef core_client type;
|
||||||
|
|
||||||
// Concurrency policy
|
// Concurrency policy
|
||||||
|
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||||
typedef websocketpp::concurrency::basic concurrency_type;
|
typedef websocketpp::concurrency::basic concurrency_type;
|
||||||
|
#else
|
||||||
|
typedef websocketpp::concurrency::none concurrency_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
// HTTP Parser Policies
|
// HTTP Parser Policies
|
||||||
typedef http::parser::request request_type;
|
typedef http::parser::request request_type;
|
||||||
@@ -216,6 +224,18 @@ struct core_client {
|
|||||||
*/
|
*/
|
||||||
static const bool silent_close = false;
|
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;
|
||||||
|
|
||||||
/// Global flag for enabling/disabling extensions
|
/// Global flag for enabling/disabling extensions
|
||||||
static const bool enable_extensions = true;
|
static const bool enable_extensions = true;
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -216,6 +216,18 @@ struct debug_core {
|
|||||||
*/
|
*/
|
||||||
static const bool silent_close = false;
|
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;
|
||||||
|
|
||||||
/// Global flag for enabling/disabling extensions
|
/// Global flag for enabling/disabling extensions
|
||||||
static const bool enable_extensions = true;
|
static const bool enable_extensions = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 <websocketpp/config/minimal_server.hpp>
|
||||||
|
|
||||||
|
namespace 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:
|
||||||
|
* <algorithm>
|
||||||
|
* <map>
|
||||||
|
* <sstream>
|
||||||
|
* <string>
|
||||||
|
* <vector>
|
||||||
|
*
|
||||||
|
* C++11 STL or Boost
|
||||||
|
* <memory>
|
||||||
|
* <functional>
|
||||||
|
* <system_error>
|
||||||
|
*
|
||||||
|
* Operating System:
|
||||||
|
* <stdint.h> or <boost/cstdint.hpp>
|
||||||
|
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
|
||||||
|
*
|
||||||
|
* @since 0.4.0-dev
|
||||||
|
*/
|
||||||
|
typedef minimal_server minimal_client;
|
||||||
|
|
||||||
|
} // namespace config
|
||||||
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
#endif // WEBSOCKETPP_CONFIG_MINIMAL_CLIENT_HPP
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* 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 <websocketpp/common/platforms.hpp>
|
||||||
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
|
#include <websocketpp/common/stdint.hpp>
|
||||||
|
|
||||||
|
// Concurrency
|
||||||
|
#include <websocketpp/concurrency/none.hpp>
|
||||||
|
|
||||||
|
// Transport
|
||||||
|
#include <websocketpp/transport/stub/endpoint.hpp>
|
||||||
|
|
||||||
|
// HTTP
|
||||||
|
#include <websocketpp/http/request.hpp>
|
||||||
|
#include <websocketpp/http/response.hpp>
|
||||||
|
|
||||||
|
// Messages
|
||||||
|
#include <websocketpp/message_buffer/message.hpp>
|
||||||
|
#include <websocketpp/message_buffer/alloc.hpp>
|
||||||
|
|
||||||
|
// Loggers
|
||||||
|
#include <websocketpp/logger/stub.hpp>
|
||||||
|
|
||||||
|
// RNG
|
||||||
|
#include <websocketpp/random/none.hpp>
|
||||||
|
|
||||||
|
// User stub base classes
|
||||||
|
#include <websocketpp/endpoint_base.hpp>
|
||||||
|
#include <websocketpp/connection_base.hpp>
|
||||||
|
|
||||||
|
// Extensions
|
||||||
|
#include <websocketpp/extensions/permessage_deflate/disabled.hpp>
|
||||||
|
|
||||||
|
namespace 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:
|
||||||
|
* <algorithm>
|
||||||
|
* <map>
|
||||||
|
* <sstream>
|
||||||
|
* <string>
|
||||||
|
* <vector>
|
||||||
|
*
|
||||||
|
* C++11 STL or Boost
|
||||||
|
* <memory>
|
||||||
|
* <functional>
|
||||||
|
* <system_error>
|
||||||
|
*
|
||||||
|
* Operating System:
|
||||||
|
* <stdint.h> or <boost/cstdint.hpp>
|
||||||
|
* <netinet/in.h> or <winsock2.h> (for ntohl.. could potentially bundle this)
|
||||||
|
*
|
||||||
|
* @since 0.4.0-dev
|
||||||
|
*/
|
||||||
|
struct minimal_server {
|
||||||
|
typedef minimal_server type;
|
||||||
|
|
||||||
|
// Concurrency policy
|
||||||
|
typedef 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_buffer::alloc::con_msg_manager>
|
||||||
|
message_type;
|
||||||
|
typedef message_buffer::alloc::con_msg_manager<message_type>
|
||||||
|
con_msg_manager_type;
|
||||||
|
typedef message_buffer::alloc::endpoint_msg_manager<con_msg_manager_type>
|
||||||
|
endpoint_msg_manager_type;
|
||||||
|
|
||||||
|
/// Logging policies
|
||||||
|
typedef websocketpp::log::stub<concurrency_type,
|
||||||
|
websocketpp::log::elevel> elog_type;
|
||||||
|
typedef websocketpp::log::stub<concurrency_type,
|
||||||
|
websocketpp::log::alevel> alog_type;
|
||||||
|
|
||||||
|
/// RNG policies
|
||||||
|
typedef websocketpp::random::none::int_generator<uint32_t> 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 websocketpp::transport::stub::endpoint<transport_config>
|
||||||
|
transport_type;
|
||||||
|
|
||||||
|
/// User overridable Endpoint base class
|
||||||
|
typedef websocketpp::endpoint_base endpoint_base;
|
||||||
|
/// User overridable Connection base class
|
||||||
|
typedef 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 websocketpp::log::level elog_level =
|
||||||
|
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 websocketpp::log::level alog_level =
|
||||||
|
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;
|
||||||
|
|
||||||
|
/// 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 websocketpp::extensions::permessage_deflate::disabled
|
||||||
|
<permessage_deflate_config> 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 websocketpp
|
||||||
|
|
||||||
|
#endif // WEBSOCKETPP_CONFIG_MINIMAL_HPP
|
||||||
+96
-12
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -279,9 +280,9 @@ private:
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit connection(bool is_server, std::string const & ua, alog_type& alog,
|
explicit connection(bool p_is_server, std::string const & ua, alog_type& alog,
|
||||||
elog_type& elog, rng_type & rng)
|
elog_type& elog, rng_type & rng)
|
||||||
: transport_con_type(is_server,alog,elog)
|
: transport_con_type(p_is_server, alog, elog)
|
||||||
, m_handle_read_frame(lib::bind(
|
, m_handle_read_frame(lib::bind(
|
||||||
&type::handle_read_frame,
|
&type::handle_read_frame,
|
||||||
this,
|
this,
|
||||||
@@ -297,12 +298,14 @@ public:
|
|||||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||||
, m_pong_timeout_dur(config::timeout_pong)
|
, m_pong_timeout_dur(config::timeout_pong)
|
||||||
|
, m_max_message_size(config::max_message_size)
|
||||||
, m_state(session::state::connecting)
|
, m_state(session::state::connecting)
|
||||||
, m_internal_state(session::internal_state::USER_INIT)
|
, m_internal_state(session::internal_state::USER_INIT)
|
||||||
, m_msg_manager(new con_msg_manager_type())
|
, m_msg_manager(new con_msg_manager_type())
|
||||||
, m_send_buffer_size(0)
|
, m_send_buffer_size(0)
|
||||||
, m_write_flag(false)
|
, m_write_flag(false)
|
||||||
, m_is_server(is_server)
|
, m_read_flag(true)
|
||||||
|
, m_is_server(p_is_server)
|
||||||
, m_alog(alog)
|
, m_alog(alog)
|
||||||
, m_elog(elog)
|
, m_elog(elog)
|
||||||
, m_rng(rng)
|
, m_rng(rng)
|
||||||
@@ -455,9 +458,9 @@ public:
|
|||||||
m_message_handler = h;
|
m_message_handler = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////
|
//////////////////////////////////////////
|
||||||
// Connection timeouts //
|
// Connection timeouts and other limits //
|
||||||
/////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
||||||
/// Set open handshake timeout
|
/// Set open handshake timeout
|
||||||
/**
|
/**
|
||||||
@@ -528,6 +531,38 @@ public:
|
|||||||
m_pong_timeout_dur = 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 a connection 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 a connection 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Uncategorized public methods //
|
// Uncategorized public methods //
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
@@ -615,9 +650,46 @@ public:
|
|||||||
* @return An error code
|
* @return An error code
|
||||||
*/
|
*/
|
||||||
lib::error_code interrupt();
|
lib::error_code interrupt();
|
||||||
|
|
||||||
/// Transport inturrupt callback
|
/// Transport inturrupt callback
|
||||||
void handle_interrupt();
|
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
|
/// Send a ping
|
||||||
/**
|
/**
|
||||||
@@ -1092,8 +1164,8 @@ public:
|
|||||||
void handle_open_handshake_timeout(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_close_handshake_timeout(lib::error_code const & ec);
|
||||||
|
|
||||||
void handle_read_frame(lib::error_code const & ec,
|
void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
|
||||||
size_t bytes_transferred);
|
void read_frame();
|
||||||
|
|
||||||
/// Get array of WebSocket protocol versions that this connection supports.
|
/// Get array of WebSocket protocol versions that this connection supports.
|
||||||
const std::vector<int>& get_supported_versions() const;
|
const std::vector<int>& get_supported_versions() const;
|
||||||
@@ -1281,6 +1353,14 @@ private:
|
|||||||
*/
|
*/
|
||||||
void log_fail_result();
|
void log_fail_result();
|
||||||
|
|
||||||
|
/// Prints information about an arbitrary error code on the specified channel
|
||||||
|
template <typename error_type>
|
||||||
|
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
|
// internal handler functions
|
||||||
read_handler m_handle_read_frame;
|
read_handler m_handle_read_frame;
|
||||||
write_frame_handler m_write_frame_handler;
|
write_frame_handler m_write_frame_handler;
|
||||||
@@ -1307,6 +1387,7 @@ private:
|
|||||||
long m_open_handshake_timeout_dur;
|
long m_open_handshake_timeout_dur;
|
||||||
long m_close_handshake_timeout_dur;
|
long m_close_handshake_timeout_dur;
|
||||||
long m_pong_timeout_dur;
|
long m_pong_timeout_dur;
|
||||||
|
size_t m_max_message_size;
|
||||||
|
|
||||||
/// External connection state
|
/// External connection state
|
||||||
/**
|
/**
|
||||||
@@ -1370,9 +1451,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::vector<transport::buffer> m_send_buffer;
|
std::vector<transport::buffer> m_send_buffer;
|
||||||
|
|
||||||
/// a pointer to hold on to the current message being written to keep it
|
/// 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.
|
/// from going out of scope before the write is complete.
|
||||||
message_ptr m_current_msg;
|
std::vector<message_ptr> m_current_msgs;
|
||||||
|
|
||||||
/// True if there is currently an outstanding transport write
|
/// True if there is currently an outstanding transport write
|
||||||
/**
|
/**
|
||||||
@@ -1380,6 +1461,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool m_write_flag;
|
bool m_write_flag;
|
||||||
|
|
||||||
|
/// True if this connection is presently reading new data
|
||||||
|
bool m_read_flag;
|
||||||
|
|
||||||
// connection data
|
// connection data
|
||||||
request_type m_request;
|
request_type m_request;
|
||||||
response_type m_response;
|
response_type m_response;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+80
-12
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
#include <websocketpp/logger/levels.hpp>
|
#include <websocketpp/logger/levels.hpp>
|
||||||
#include <websocketpp/version.hpp>
|
#include <websocketpp/version.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
@@ -87,21 +86,22 @@ public:
|
|||||||
|
|
||||||
typedef lib::shared_ptr<connection_weak_ptr> hdl_type;
|
typedef lib::shared_ptr<connection_weak_ptr> hdl_type;
|
||||||
|
|
||||||
explicit endpoint(bool is_server)
|
explicit endpoint(bool p_is_server)
|
||||||
: m_alog(config::alog_level, &std::cout)
|
: m_alog(config::alog_level, log::channel_type_hint::access)
|
||||||
, m_elog(config::elog_level, &std::cerr)
|
, m_elog(config::elog_level, log::channel_type_hint::error)
|
||||||
, m_user_agent(::websocketpp::user_agent)
|
, m_user_agent(::websocketpp::user_agent)
|
||||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||||
, m_pong_timeout_dur(config::timeout_pong)
|
, m_pong_timeout_dur(config::timeout_pong)
|
||||||
, m_is_server(is_server)
|
, m_max_message_size(config::max_message_size)
|
||||||
|
, m_is_server(p_is_server)
|
||||||
{
|
{
|
||||||
m_alog.set_channels(config::alog_level);
|
m_alog.set_channels(config::alog_level);
|
||||||
m_elog.set_channels(config::elog_level);
|
m_elog.set_channels(config::elog_level);
|
||||||
|
|
||||||
m_alog.write(log::alevel::devel,"endpoint constructor");
|
m_alog.write(log::alevel::devel, "endpoint constructor");
|
||||||
|
|
||||||
transport_type::init_logging(&m_alog,&m_elog);
|
transport_type::init_logging(&m_alog, &m_elog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the user agent string that this endpoint will use
|
/// Returns the user agent string that this endpoint will use
|
||||||
@@ -272,9 +272,9 @@ public:
|
|||||||
m_message_handler = h;
|
m_message_handler = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////
|
//////////////////////////////////////////
|
||||||
// Connection timeouts //
|
// Connection timeouts and other limits //
|
||||||
/////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
||||||
/// Set open handshake timeout
|
/// Set open handshake timeout
|
||||||
/**
|
/**
|
||||||
@@ -348,6 +348,36 @@ public:
|
|||||||
m_pong_timeout_dur = dur;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************/
|
/*************************************/
|
||||||
/* Connection pass through functions */
|
/* Connection pass through functions */
|
||||||
/*************************************/
|
/*************************************/
|
||||||
@@ -363,6 +393,43 @@ public:
|
|||||||
void interrupt(connection_hdl hdl, lib::error_code & ec);
|
void interrupt(connection_hdl hdl, lib::error_code & ec);
|
||||||
void interrupt(connection_hdl hdl);
|
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);
|
||||||
|
|
||||||
/// Create a message and add it to the outgoing send queue (exception free)
|
/// 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
|
* Convenience method to send a message given a payload string and an opcode
|
||||||
@@ -470,7 +537,7 @@ public:
|
|||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
connection_ptr con = this->get_con_from_hdl(hdl,ec);
|
connection_ptr con = this->get_con_from_hdl(hdl,ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
throw ec;
|
throw exception(ec);
|
||||||
}
|
}
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
@@ -497,6 +564,7 @@ private:
|
|||||||
long m_open_handshake_timeout_dur;
|
long m_open_handshake_timeout_dur;
|
||||||
long m_close_handshake_timeout_dur;
|
long m_close_handshake_timeout_dur;
|
||||||
long m_pong_timeout_dur;
|
long m_pong_timeout_dur;
|
||||||
|
size_t m_max_message_size;
|
||||||
|
|
||||||
rng_type m_rng;
|
rng_type m_rng;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+31
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -38,7 +38,7 @@ namespace websocketpp {
|
|||||||
/// Combination error code / string type for returning two values
|
/// Combination error code / string type for returning two values
|
||||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||||
|
|
||||||
// setup for errors that should be propogated back to the user.
|
/// Library level error codes
|
||||||
namespace error {
|
namespace error {
|
||||||
enum value {
|
enum value {
|
||||||
/// Catch-all library error
|
/// Catch-all library error
|
||||||
@@ -86,7 +86,8 @@ enum value {
|
|||||||
/// Invalid subprotocol
|
/// Invalid subprotocol
|
||||||
invalid_subprotocol,
|
invalid_subprotocol,
|
||||||
|
|
||||||
/// Bad or unknown connection
|
/// An operation was attempted on a connection that did not exist or was
|
||||||
|
/// already deleted.
|
||||||
bad_connection,
|
bad_connection,
|
||||||
|
|
||||||
/// Unit testing utility error code
|
/// Unit testing utility error code
|
||||||
@@ -114,7 +115,14 @@ enum value {
|
|||||||
close_handshake_timeout,
|
close_handshake_timeout,
|
||||||
|
|
||||||
/// Invalid port in URI
|
/// Invalid port in URI
|
||||||
invalid_port
|
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
|
||||||
}; // enum value
|
}; // enum value
|
||||||
|
|
||||||
|
|
||||||
@@ -176,6 +184,10 @@ public:
|
|||||||
return "The closing handshake timed out";
|
return "The closing handshake timed out";
|
||||||
case error::invalid_port:
|
case error::invalid_port:
|
||||||
return "Invalid URI port";
|
return "Invalid URI port";
|
||||||
|
case error::async_accept_not_listening:
|
||||||
|
return "Async Accept not listening";
|
||||||
|
case error::operation_canceled:
|
||||||
|
return "Operation canceled";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
@@ -205,21 +217,30 @@ namespace websocketpp {
|
|||||||
|
|
||||||
class exception : public std::exception {
|
class exception : public std::exception {
|
||||||
public:
|
public:
|
||||||
exception(std::string const & msg,
|
exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
|
||||||
error::value code = error::general)
|
: m_msg(msg), m_code(ec)
|
||||||
: m_msg(msg),m_code(code) {}
|
{}
|
||||||
|
|
||||||
|
explicit exception(lib::error_code ec)
|
||||||
|
: m_code(ec)
|
||||||
|
{}
|
||||||
|
|
||||||
~exception() throw() {}
|
~exception() throw() {}
|
||||||
|
|
||||||
virtual char const * what() const throw() {
|
virtual char const * what() const throw() {
|
||||||
return m_msg.c_str();
|
if (m_msg.empty()) {
|
||||||
|
return m_code.message().c_str();
|
||||||
|
} else {
|
||||||
|
return m_msg.c_str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error::value code() const throw() {
|
lib::error_code code() const throw() {
|
||||||
return m_code;
|
return m_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string m_msg;
|
std::string m_msg;
|
||||||
error::value m_code;
|
lib::error_code m_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|||||||
+24
-24
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -36,34 +36,34 @@ namespace websocketpp {
|
|||||||
*/
|
*/
|
||||||
class error_msg {
|
class error_msg {
|
||||||
public:
|
public:
|
||||||
const std::string& get_msg() const {
|
const std::string& get_msg() const {
|
||||||
return m_error_msg;
|
return m_error_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_msg(const std::string& msg) {
|
void set_msg(const std::string& msg) {
|
||||||
m_error_msg = msg;
|
m_error_msg = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_msg(const std::string& msg) {
|
void append_msg(const std::string& msg) {
|
||||||
m_error_msg.append(msg);
|
m_error_msg.append(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void set_msg(const T& thing) {
|
void set_msg(const T& thing) {
|
||||||
std::stringsteam val;
|
std::stringsteam val;
|
||||||
val << thing;
|
val << thing;
|
||||||
this->set_msg(val.str());
|
this->set_msg(val.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void append_msg(const T& thing) {
|
void append_msg(const T& thing) {
|
||||||
std::stringsteam val;
|
std::stringsteam val;
|
||||||
val << thing;
|
val << thing;
|
||||||
this->append_msg(val.str());
|
this->append_msg(val.str());
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
// error resources
|
// error resources
|
||||||
std::string m_error_msg;
|
std::string m_error_msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+25
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -53,7 +53,15 @@ class disabled {
|
|||||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
err_str_pair negotiate(http::attribute_list const & attributes) {
|
/// 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());
|
return make_pair(make_error_code(error::disabled),std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,17 +77,24 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code compress(std::string const & in, std::string & out) {
|
/// 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);
|
return make_error_code(error::disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code decompress(uint8_t const * buf, size_t len,
|
/// Decompress bytes
|
||||||
std::string & out)
|
/**
|
||||||
{
|
* @param buf Byte buffer to decompress
|
||||||
return make_error_code(error::disabled);
|
* @param len Length of buf
|
||||||
}
|
* @param out String to append decompressed bytes to
|
||||||
|
* @return Error or status code
|
||||||
lib::error_code decompress(std::string const & in, std::string & out) {
|
*/
|
||||||
|
lib::error_code decompress(uint8_t const *, size_t, std::string &) {
|
||||||
return make_error_code(error::disabled);
|
return make_error_code(error::disabled);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+9
-8
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -28,8 +28,10 @@
|
|||||||
#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||||
#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <websocketpp/common/cpp11.hpp>
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
#include <websocketpp/common/memory.hpp>
|
#include <websocketpp/common/memory.hpp>
|
||||||
|
#include <websocketpp/common/platforms.hpp>
|
||||||
#include <websocketpp/common/system_error.hpp>
|
#include <websocketpp/common/system_error.hpp>
|
||||||
#include <websocketpp/error.hpp>
|
#include <websocketpp/error.hpp>
|
||||||
|
|
||||||
@@ -48,8 +50,8 @@ namespace extensions {
|
|||||||
/**
|
/**
|
||||||
* ### permessage-deflate interface
|
* ### permessage-deflate interface
|
||||||
*
|
*
|
||||||
* **is_implimented**\n
|
* **is_implemented**\n
|
||||||
* `bool is_implimented()`\n
|
* `bool is_implemented()`\n
|
||||||
* Returns whether or not the object impliments the extension or not
|
* Returns whether or not the object impliments the extension or not
|
||||||
*
|
*
|
||||||
* **is_enabled**\n
|
* **is_enabled**\n
|
||||||
@@ -432,8 +434,8 @@ public:
|
|||||||
* @param response The server response attribute list to validate
|
* @param response The server response attribute list to validate
|
||||||
* @return Validation error or 0 on success
|
* @return Validation error or 0 on success
|
||||||
*/
|
*/
|
||||||
lib::error_code validate_offer(http::attribute_list const & response) {
|
lib::error_code validate_offer(http::attribute_list const &) {
|
||||||
|
return make_error_code(error::general);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Negotiate extension
|
/// Negotiate extension
|
||||||
@@ -487,7 +489,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t output;
|
size_t output;
|
||||||
int ret;
|
|
||||||
|
|
||||||
m_dstate.avail_out = m_compress_buffer_size;
|
m_dstate.avail_out = m_compress_buffer_size;
|
||||||
m_dstate.next_in = (unsigned char *)(const_cast<char *>(in.data()));
|
m_dstate.next_in = (unsigned char *)(const_cast<char *>(in.data()));
|
||||||
@@ -497,7 +498,7 @@ public:
|
|||||||
m_dstate.avail_out = m_compress_buffer_size;
|
m_dstate.avail_out = m_compress_buffer_size;
|
||||||
m_dstate.next_out = m_compress_buffer.get();
|
m_dstate.next_out = m_compress_buffer.get();
|
||||||
|
|
||||||
ret = deflate(&m_dstate, Z_SYNC_FLUSH);
|
deflate(&m_dstate, Z_SYNC_FLUSH);
|
||||||
|
|
||||||
output = m_compress_buffer_size - m_dstate.avail_out;
|
output = m_compress_buffer_size - m_dstate.avail_out;
|
||||||
|
|
||||||
@@ -642,7 +643,7 @@ private:
|
|||||||
m_s2c_max_window_bits = bits;
|
m_s2c_max_window_bits = bits;
|
||||||
break;
|
break;
|
||||||
case mode::largest:
|
case mode::largest:
|
||||||
m_s2c_max_window_bits = std::min(bits,m_s2c_max_window_bits);
|
m_s2c_max_window_bits = (std::min)(bits,m_s2c_max_window_bits);
|
||||||
break;
|
break;
|
||||||
case mode::smallest:
|
case mode::smallest:
|
||||||
m_s2c_max_window_bits = min_s2c_max_window_bits;
|
m_s2c_max_window_bits = min_s2c_max_window_bits;
|
||||||
|
|||||||
+3
-32
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -266,7 +266,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_converter temp64;
|
uint64_converter temp64;
|
||||||
temp64.i = lib::net::htonll(payload_size);
|
temp64.i = lib::net::_htonll(payload_size);
|
||||||
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
||||||
|
|
||||||
return 8-payload_offset;
|
return 8-payload_offset;
|
||||||
@@ -456,35 +456,6 @@ inline size_t get_header_len(basic_header const & h) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the frame's size
|
|
||||||
/**
|
|
||||||
* @param [out] h The basic header to set.
|
|
||||||
* @param [out] eh The extended header to set.
|
|
||||||
* @param [in] The size to set.
|
|
||||||
* @return What error occurred, if any.
|
|
||||||
*/
|
|
||||||
inline lib::error_code set_size(basic_header & h, extended_header & eh, uint64_t
|
|
||||||
size)
|
|
||||||
{
|
|
||||||
// make sure value isn't too big
|
|
||||||
uint8_t basic_value;
|
|
||||||
|
|
||||||
if (size <= limits::payload_size_basic) {
|
|
||||||
basic_value = static_cast<uint8_t>(size);
|
|
||||||
} else if (size <= limits::payload_size_extended) {
|
|
||||||
basic_value = payload_size_code_16bit;
|
|
||||||
} else if (size <= limits::payload_size_jumbo) {
|
|
||||||
basic_value = payload_size_code_64bit;
|
|
||||||
} else {
|
|
||||||
// error
|
|
||||||
return lib::error_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
h.b1 = (basic_value & BHB1_PAYLOAD) | (h.b1 & BHB1_MASK);
|
|
||||||
|
|
||||||
return lib::error_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate the offset location of the masking key within the extended header
|
/// Calculate the offset location of the masking key within the extended header
|
||||||
/**
|
/**
|
||||||
* Calculate the offset location of the masking key within the extended header
|
* Calculate the offset location of the masking key within the extended header
|
||||||
@@ -583,7 +554,7 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
|||||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||||
uint64_converter temp64;
|
uint64_converter temp64;
|
||||||
std::copy(e.bytes,e.bytes+8,temp64.c);
|
std::copy(e.bytes,e.bytes+8,temp64.c);
|
||||||
return lib::net::ntohll(temp64.i);
|
return lib::net::_ntohll(temp64.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the full payload size field from a WebSocket header
|
/// Extract the full payload size field from a WebSocket header
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
|
/// HTTP handling support
|
||||||
namespace http {
|
namespace http {
|
||||||
/// The type of an HTTP attribute list
|
/// The type of an HTTP attribute list
|
||||||
/**
|
/**
|
||||||
@@ -255,7 +256,7 @@ namespace http {
|
|||||||
case internal_server_error:
|
case internal_server_error:
|
||||||
return "Internal Server Error";
|
return "Internal Server Error";
|
||||||
case not_implemented:
|
case not_implemented:
|
||||||
return "Not Implimented";
|
return "Not Implemented";
|
||||||
case bad_gateway:
|
case bad_gateway:
|
||||||
return "Bad Gateway";
|
return "Bad Gateway";
|
||||||
case service_unavailable:
|
case service_unavailable:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+11
-11
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -38,15 +38,15 @@ namespace http {
|
|||||||
namespace parser {
|
namespace parser {
|
||||||
|
|
||||||
inline bool request::parse_complete(std::istream& s) {
|
inline bool request::parse_complete(std::istream& s) {
|
||||||
std::string request;
|
std::string req;
|
||||||
|
|
||||||
// get status line
|
// get status line
|
||||||
std::getline(s, request);
|
std::getline(s, req);
|
||||||
|
|
||||||
if (request[request.size()-1] == '\r') {
|
if (req[req.size()-1] == '\r') {
|
||||||
request.erase(request.end()-1);
|
req.erase(req.end()-1);
|
||||||
|
|
||||||
std::stringstream ss(request);
|
std::stringstream ss(req);
|
||||||
std::string val;
|
std::string val;
|
||||||
|
|
||||||
ss >> val;
|
ss >> val;
|
||||||
@@ -127,18 +127,18 @@ inline size_t request::consume(const char *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
begin = end+sizeof(header_delimiter)-1;
|
begin = end+(sizeof(header_delimiter)-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string request::raw() {
|
inline std::string request::raw() {
|
||||||
// TODO: validation. Make sure all required fields have been set?
|
// TODO: validation. Make sure all required fields have been set?
|
||||||
std::stringstream raw;
|
std::stringstream ret;
|
||||||
|
|
||||||
raw << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||||
raw << raw_headers() << "\r\n" << m_body;
|
ret << raw_headers() << "\r\n" << m_body;
|
||||||
|
|
||||||
return raw.str();
|
return ret.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void request::set_method(const std::string& method) {
|
inline void request::set_method(const std::string& method) {
|
||||||
|
|||||||
+11
-11
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -172,15 +172,15 @@ inline size_t response::consume(std::istream & s) {
|
|||||||
|
|
||||||
inline bool response::parse_complete(std::istream& s) {
|
inline bool response::parse_complete(std::istream& s) {
|
||||||
// parse a complete header (ie \r\n\r\n MUST be in the input stream)
|
// parse a complete header (ie \r\n\r\n MUST be in the input stream)
|
||||||
std::string response;
|
std::string line;
|
||||||
|
|
||||||
// get status line
|
// get status line
|
||||||
std::getline(s, response);
|
std::getline(s, line);
|
||||||
|
|
||||||
if (response[response.size()-1] == '\r') {
|
if (line[line.size()-1] == '\r') {
|
||||||
response.erase(response.end()-1);
|
line.erase(line.end()-1);
|
||||||
|
|
||||||
std::stringstream ss(response);
|
std::stringstream ss(line);
|
||||||
std::string str_val;
|
std::string str_val;
|
||||||
int int_val;
|
int int_val;
|
||||||
char char_val[256];
|
char char_val[256];
|
||||||
@@ -201,14 +201,14 @@ inline bool response::parse_complete(std::istream& s) {
|
|||||||
inline std::string response::raw() const {
|
inline std::string response::raw() const {
|
||||||
// TODO: validation. Make sure all required fields have been set?
|
// TODO: validation. Make sure all required fields have been set?
|
||||||
|
|
||||||
std::stringstream raw;
|
std::stringstream ret;
|
||||||
|
|
||||||
raw << get_version() << " " << m_status_code << " " << m_status_msg;
|
ret << get_version() << " " << m_status_code << " " << m_status_msg;
|
||||||
raw << "\r\n" << raw_headers() << "\r\n";
|
ret << "\r\n" << raw_headers() << "\r\n";
|
||||||
|
|
||||||
raw << m_body;
|
ret << m_body;
|
||||||
|
|
||||||
return raw.str();
|
return ret.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void response::set_status(status_code::value code) {
|
inline void response::set_status(status_code::value code) {
|
||||||
|
|||||||
+4
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -369,6 +369,9 @@ InputIterator extract_parameters(InputIterator begin, InputIterator end,
|
|||||||
|
|
||||||
inline std::string strip_lws(std::string const & input) {
|
inline std::string strip_lws(std::string const & input) {
|
||||||
std::string::const_iterator begin = extract_all_lws(input.begin(),input.end());
|
std::string::const_iterator begin = extract_all_lws(input.begin(),input.end());
|
||||||
|
if (begin == input.end()) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
std::string::const_reverse_iterator end = extract_all_lws(input.rbegin(),input.rend());
|
std::string::const_reverse_iterator end = extract_all_lws(input.rbegin(),input.rend());
|
||||||
|
|
||||||
return std::string(begin,end.base());
|
return std::string(begin,end.base());
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
typedef lib::shared_ptr<type> ptr;
|
typedef lib::shared_ptr<type> ptr;
|
||||||
|
|
||||||
request()
|
request()
|
||||||
: m_buf(new std::string())
|
: m_buf(lib::make_shared<std::string>())
|
||||||
, m_ready(false) {}
|
, m_ready(false) {}
|
||||||
|
|
||||||
/// DEPRECATED parse a complete header (\r\n\r\n MUST be in the istream)
|
/// DEPRECATED parse a complete header (\r\n\r\n MUST be in the istream)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
response()
|
response()
|
||||||
: m_read(0)
|
: m_read(0)
|
||||||
, m_buf(new std::string())
|
, m_buf(lib::make_shared<std::string>())
|
||||||
, m_status_code(status_code::uninitialized)
|
, m_status_code(status_code::uninitialized)
|
||||||
, m_state(RESPONSE_LINE) {}
|
, m_state(RESPONSE_LINE) {}
|
||||||
|
|
||||||
|
|||||||
+291
-229
File diff suppressed because it is too large
Load Diff
+60
-26
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -42,8 +42,8 @@ endpoint<connection,config>::create_connection() {
|
|||||||
|
|
||||||
//scoped_lock_type guard(m_mutex);
|
//scoped_lock_type guard(m_mutex);
|
||||||
// Create a connection on the heap and manage it using a shared pointer
|
// Create a connection on the heap and manage it using a shared pointer
|
||||||
connection_ptr con(new connection_type(m_is_server,m_user_agent,m_alog,
|
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
|
||||||
m_elog, m_rng));
|
m_user_agent, lib::ref(m_alog), lib::ref(m_elog), lib::ref(m_rng));
|
||||||
|
|
||||||
connection_weak_ptr w(con);
|
connection_weak_ptr w(con);
|
||||||
|
|
||||||
@@ -64,16 +64,19 @@ endpoint<connection,config>::create_connection() {
|
|||||||
con->set_http_handler(m_http_handler);
|
con->set_http_handler(m_http_handler);
|
||||||
con->set_validate_handler(m_validate_handler);
|
con->set_validate_handler(m_validate_handler);
|
||||||
con->set_message_handler(m_message_handler);
|
con->set_message_handler(m_message_handler);
|
||||||
|
|
||||||
if (m_open_handshake_timeout_dur == config::timeout_open_handshake) {
|
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
|
||||||
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
|
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
|
||||||
}
|
}
|
||||||
if (m_close_handshake_timeout_dur == config::timeout_close_handshake) {
|
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
|
||||||
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
|
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
|
||||||
}
|
}
|
||||||
if (m_pong_timeout_dur == config::timeout_pong) {
|
if (m_pong_timeout_dur != config::timeout_pong) {
|
||||||
con->set_pong_timeout(m_pong_timeout_dur);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
|
|
||||||
@@ -87,8 +90,7 @@ endpoint<connection,config>::create_connection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::interrupt(connection_hdl hdl,
|
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
|
||||||
lib::error_code & ec)
|
|
||||||
{
|
{
|
||||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||||
if (ec) {return;}
|
if (ec) {return;}
|
||||||
@@ -102,12 +104,46 @@ template <typename connection, typename config>
|
|||||||
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
|
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
interrupt(hdl,ec);
|
interrupt(hdl,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
|
||||||
payload, frame::opcode::value op, lib::error_code & ec)
|
{
|
||||||
|
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||||
|
if (ec) {return;}
|
||||||
|
|
||||||
|
ec = con->pause_reading();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename connection, typename config>
|
||||||
|
void endpoint<connection,config>::pause_reading(connection_hdl hdl) {
|
||||||
|
lib::error_code ec;
|
||||||
|
pause_reading(hdl,ec);
|
||||||
|
if (ec) { throw exception(ec); }
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename connection, typename config>
|
||||||
|
void endpoint<connection,config>::resume_reading(connection_hdl hdl, lib::error_code & ec)
|
||||||
|
{
|
||||||
|
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||||
|
if (ec) {return;}
|
||||||
|
|
||||||
|
ec = con->resume_reading();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename connection, typename config>
|
||||||
|
void endpoint<connection,config>::resume_reading(connection_hdl hdl) {
|
||||||
|
lib::error_code ec;
|
||||||
|
resume_reading(hdl,ec);
|
||||||
|
if (ec) { throw exception(ec); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename connection, typename config>
|
||||||
|
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
|
||||||
|
frame::opcode::value op, lib::error_code & ec)
|
||||||
{
|
{
|
||||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||||
if (ec) {return;}
|
if (ec) {return;}
|
||||||
@@ -116,12 +152,12 @@ void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
|
||||||
payload, frame::opcode::value op)
|
frame::opcode::value op)
|
||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
send(hdl,payload,op,ec);
|
send(hdl,payload,op,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
@@ -139,7 +175,7 @@ void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
|
|||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
send(hdl,payload,len,op,ec);
|
send(hdl,payload,len,op,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
@@ -155,7 +191,7 @@ template <typename connection, typename config>
|
|||||||
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
|
void endpoint<connection,config>::send(connection_hdl hdl, message_ptr msg) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
send(hdl,msg,ec);
|
send(hdl,msg,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
@@ -174,7 +210,7 @@ void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
|
|||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
close(hdl,code,reason,ec);
|
close(hdl,code,reason,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
@@ -187,17 +223,16 @@ void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
|
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
|
||||||
payload)
|
|
||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
ping(hdl,payload,ec);
|
ping(hdl,payload,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
|
||||||
payload, lib::error_code & ec)
|
lib::error_code & ec)
|
||||||
{
|
{
|
||||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||||
if (ec) {return;}
|
if (ec) {return;}
|
||||||
@@ -205,12 +240,11 @@ void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename connection, typename config>
|
template <typename connection, typename config>
|
||||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
|
||||||
payload)
|
|
||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
pong(hdl,payload,ec);
|
pong(hdl,payload,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+21
-8
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <websocketpp/common/cpp11.hpp>
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
#include <websocketpp/common/stdint.hpp>
|
#include <websocketpp/common/stdint.hpp>
|
||||||
|
#include <websocketpp/common/time.hpp>
|
||||||
#include <websocketpp/logger/levels.hpp>
|
#include <websocketpp/logger/levels.hpp>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
@@ -55,12 +56,24 @@ namespace log {
|
|||||||
template <typename concurrency, typename names>
|
template <typename concurrency, typename names>
|
||||||
class basic {
|
class basic {
|
||||||
public:
|
public:
|
||||||
basic<concurrency,names>(std::ostream * out = &std::cout)
|
basic<concurrency,names>(channel_type_hint::value h =
|
||||||
|
channel_type_hint::access)
|
||||||
|
: m_static_channels(0xffffffff)
|
||||||
|
, m_dynamic_channels(0)
|
||||||
|
, m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
|
||||||
|
|
||||||
|
basic<concurrency,names>(std::ostream * out)
|
||||||
: m_static_channels(0xffffffff)
|
: m_static_channels(0xffffffff)
|
||||||
, m_dynamic_channels(0)
|
, m_dynamic_channels(0)
|
||||||
, m_out(out) {}
|
, m_out(out) {}
|
||||||
|
|
||||||
basic<concurrency,names>(level c, std::ostream * out = &std::cout)
|
basic<concurrency,names>(level c, channel_type_hint::value h =
|
||||||
|
channel_type_hint::access)
|
||||||
|
: m_static_channels(c)
|
||||||
|
, m_dynamic_channels(0)
|
||||||
|
, m_out(h == channel_type_hint::error ? &std::cerr : &std::cout) {}
|
||||||
|
|
||||||
|
basic<concurrency,names>(level c, std::ostream * out)
|
||||||
: m_static_channels(c)
|
: m_static_channels(c)
|
||||||
, m_dynamic_channels(0)
|
, m_dynamic_channels(0)
|
||||||
, m_out(out) {}
|
, m_out(out) {}
|
||||||
@@ -120,13 +133,13 @@ private:
|
|||||||
// TODO: find a workaround for this or make this format user settable
|
// TODO: find a workaround for this or make this format user settable
|
||||||
static std::ostream & timestamp(std::ostream & os) {
|
static std::ostream & timestamp(std::ostream & os) {
|
||||||
std::time_t t = std::time(NULL);
|
std::time_t t = std::time(NULL);
|
||||||
std::tm* lt = std::localtime(&t);
|
std::tm lt = lib::localtime(t);
|
||||||
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
|
#ifdef _WEBSOCKETPP_PUTTIME_
|
||||||
return os << std::put_time(lt,"%Y-%m-%d %H:%M:%S");
|
return os << std::put_time(<,"%Y-%m-%d %H:%M:%S");
|
||||||
#else // Falls back to strftime, which requires a temporary copy of the string.
|
#else // Falls back to strftime, which requires a temporary copy of the string.
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",lt);
|
size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",<);
|
||||||
return os << buffer;
|
return os << (result == 0 ? "Unknown" : buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -36,6 +36,25 @@ namespace log {
|
|||||||
/// Type of a channel package
|
/// Type of a channel package
|
||||||
typedef uint32_t level;
|
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
|
/// Package of log levels for logging errors
|
||||||
struct elevel {
|
struct elevel {
|
||||||
/// Special aggregate value representing "no levels"
|
/// Special aggregate value representing "no levels"
|
||||||
|
|||||||
+65
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
|
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
|
||||||
#define WEBSOCKETPP_LOGGER_STUB_HPP
|
#define WEBSOCKETPP_LOGGER_STUB_HPP
|
||||||
|
|
||||||
#include <iostream>
|
#include <string>
|
||||||
|
|
||||||
#include <websocketpp/common/cpp11.hpp>
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
#include <websocketpp/logger/levels.hpp>
|
#include <websocketpp/logger/levels.hpp>
|
||||||
@@ -39,20 +39,75 @@ namespace log {
|
|||||||
/// Stub logger that ignores all input
|
/// Stub logger that ignores all input
|
||||||
class stub {
|
class stub {
|
||||||
public:
|
public:
|
||||||
explicit stub(std::ostream * out) {}
|
/// Construct the logger
|
||||||
stub(level c, std::ostream * out) {}
|
/**
|
||||||
|
* @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() {}
|
_WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {}
|
||||||
|
|
||||||
void set_channels(level channels) {}
|
/// Dynamically enable the given list of channels
|
||||||
void clear_channels(level 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) {}
|
||||||
|
|
||||||
void write(level channel, std::string const & msg) {}
|
/// Write a string message to the given channel
|
||||||
void write(level channel, char const * msg) {}
|
/**
|
||||||
|
* Writing on the stub logger is a no-op and all arguments are ignored
|
||||||
|
*
|
||||||
|
* @param channel The package of channels 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 package of channels to write to
|
||||||
|
* @param msg The message to write
|
||||||
|
*/
|
||||||
|
void write(level, char const *) {}
|
||||||
|
|
||||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ bool static_test(level channel) 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;
|
return false;
|
||||||
}
|
}
|
||||||
bool dynamic_test(level channel) {
|
|
||||||
|
/// 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;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
* @return A shared pointer to an empty new message
|
* @return A shared pointer to an empty new message
|
||||||
*/
|
*/
|
||||||
message_ptr get_message() {
|
message_ptr get_message() {
|
||||||
return message_ptr(new message(type::shared_from_this()));
|
return message_ptr(lib::make_shared<message>(type::shared_from_this()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a message buffer with specified size and opcode
|
/// Get a message buffer with specified size and opcode
|
||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
* @return A shared pointer to a new message with specified size.
|
* @return A shared pointer to a new message with specified size.
|
||||||
*/
|
*/
|
||||||
message_ptr get_message(frame::opcode::value op,size_t size) {
|
message_ptr get_message(frame::opcode::value op,size_t size) {
|
||||||
return message_ptr(new message(type::shared_from_this(),op,size));
|
return message_ptr(lib::make_shared<message>(type::shared_from_this(),op,size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recycle a message
|
/// Recycle a message
|
||||||
@@ -77,7 +77,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return true if the message was successfully recycled, false otherwse.
|
* @return true if the message was successfully recycled, false otherwse.
|
||||||
*/
|
*/
|
||||||
bool recycle(message * msg) {
|
bool recycle(message *) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -94,7 +94,7 @@ public:
|
|||||||
* @return A pointer to the requested connection message manager.
|
* @return A pointer to the requested connection message manager.
|
||||||
*/
|
*/
|
||||||
con_msg_man_ptr get_manager() const {
|
con_msg_man_ptr get_manager() const {
|
||||||
return con_msg_man_ptr(new con_msg_manager());
|
return con_msg_man_ptr(lib::make_shared<con_msg_manager>());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -171,7 +171,7 @@ public:
|
|||||||
* @return A shared pointer to a new message with specified size.
|
* @return A shared pointer to a new message with specified size.
|
||||||
*/
|
*/
|
||||||
message_ptr get_message(size_t size) const {
|
message_ptr get_message(size_t size) const {
|
||||||
return message_ptr(new message(size));
|
return lib::make_shared<message>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recycle a message
|
/// Recycle a message
|
||||||
@@ -201,7 +201,7 @@ public:
|
|||||||
* @return A pointer to the requested connection message manager.
|
* @return A pointer to the requested connection message manager.
|
||||||
*/
|
*/
|
||||||
con_msg_man_ptr get_manager() const {
|
con_msg_man_ptr get_manager() const {
|
||||||
return con_msg_man_ptr(new con_msg_manager());
|
return lib::make_shared<con_msg_manager>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+70
-19
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <websocketpp/utf8_validator.hpp>
|
#include <websocketpp/utf8_validator.hpp>
|
||||||
#include <websocketpp/common/network.hpp>
|
#include <websocketpp/common/network.hpp>
|
||||||
#include <websocketpp/common/md5.hpp>
|
#include <websocketpp/common/md5.hpp>
|
||||||
|
#include <websocketpp/common/platforms.hpp>
|
||||||
|
|
||||||
#include <websocketpp/processors/processor.hpp>
|
#include <websocketpp/processors/processor.hpp>
|
||||||
|
|
||||||
@@ -57,8 +58,8 @@ public:
|
|||||||
|
|
||||||
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
||||||
|
|
||||||
explicit hybi00(bool secure, bool server, msg_manager_ptr manager)
|
explicit hybi00(bool secure, bool p_is_server, msg_manager_ptr manager)
|
||||||
: processor<config>(secure, server)
|
: processor<config>(secure, p_is_server)
|
||||||
, msg_hdr(0x00)
|
, msg_hdr(0x00)
|
||||||
, msg_ftr(0xff)
|
, msg_ftr(0xff)
|
||||||
, m_state(HEADER)
|
, m_state(HEADER)
|
||||||
@@ -109,7 +110,7 @@ public:
|
|||||||
// of warning or exception.
|
// of warning or exception.
|
||||||
const std::string& key3 = req.get_header("Sec-WebSocket-Key3");
|
const std::string& key3 = req.get_header("Sec-WebSocket-Key3");
|
||||||
std::copy(key3.c_str(),
|
std::copy(key3.c_str(),
|
||||||
key3.c_str()+std::min(static_cast<size_t>(8), key3.size()),
|
key3.c_str()+(std::min)(static_cast<size_t>(8), key3.size()),
|
||||||
&key_final[8]);
|
&key_final[8]);
|
||||||
|
|
||||||
res.append_header(
|
res.append_header(
|
||||||
@@ -140,15 +141,32 @@ public:
|
|||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
// outgoing client connection processing is not supported for this version
|
/// Fill in a set of request headers for a client connection request
|
||||||
lib::error_code client_handshake_request(request_type& req, uri_ptr uri,
|
/**
|
||||||
std::vector<std::string> const & subprotocols) const
|
* 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<std::string> const &) const
|
||||||
{
|
{
|
||||||
return error::make_error_code(error::no_protocol_support);
|
return error::make_error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code validate_server_handshake_response(request_type const & req,
|
/// Validate the server's response to an outgoing handshake request
|
||||||
response_type & res) const
|
/**
|
||||||
|
* 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);
|
return error::make_error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
@@ -163,9 +181,16 @@ public:
|
|||||||
return r.get_header("Origin");
|
return r.get_header("Origin");
|
||||||
}
|
}
|
||||||
|
|
||||||
// hybi00 doesn't support subprotocols so there never will be any requested
|
/// Extracts requested subprotocols from a handshake request
|
||||||
lib::error_code extract_subprotocols(request_type const & req,
|
/**
|
||||||
std::vector<std::string> & subprotocol_list)
|
* hybi00 doesn't support subprotocols so there never will be any requested
|
||||||
|
*
|
||||||
|
* @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 &,
|
||||||
|
std::vector<std::string> &)
|
||||||
{
|
{
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
@@ -184,12 +209,12 @@ public:
|
|||||||
if (last_colon == std::string::npos ||
|
if (last_colon == std::string::npos ||
|
||||||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
|
(last_sbrace != std::string::npos && last_sbrace > last_colon))
|
||||||
{
|
{
|
||||||
return uri_ptr(new uri(base::m_secure, h, request.get_uri()));
|
return lib::make_shared<uri>(base::m_secure, h, request.get_uri());
|
||||||
} else {
|
} else {
|
||||||
return uri_ptr(new uri(base::m_secure,
|
return lib::make_shared<uri>(base::m_secure,
|
||||||
h.substr(0,last_colon),
|
h.substr(0,last_colon),
|
||||||
h.substr(last_colon+1),
|
h.substr(last_colon+1),
|
||||||
request.get_uri()));
|
request.get_uri());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check if get_uri is a full uri
|
// TODO: check if get_uri is a full uri
|
||||||
@@ -318,18 +343,44 @@ public:
|
|||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code prepare_ping(std::string const & in, message_ptr out) const
|
/// 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);
|
return lib::error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code prepare_pong(const std::string & in, message_ptr out) const
|
/// 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(const std::string &, message_ptr) const
|
||||||
{
|
{
|
||||||
return lib::error_code(error::no_protocol_support);
|
return lib::error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code prepare_close(close::status::value code,
|
/// Prepare a close frame
|
||||||
std::string const & reason, message_ptr out) const
|
/**
|
||||||
|
* 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) {
|
if (!out) {
|
||||||
return lib::error_code(error::invalid_arguments);
|
return lib::error_code(error::invalid_arguments);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -45,13 +45,20 @@ public:
|
|||||||
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
||||||
typedef typename config::rng_type rng_type;
|
typedef typename config::rng_type rng_type;
|
||||||
|
|
||||||
explicit hybi07(bool secure, bool server, msg_manager_ptr manager,
|
explicit hybi07(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||||
rng_type& rng)
|
: hybi08<config>(secure, p_is_server, manager, rng) {}
|
||||||
: hybi08<config>(secure, server, manager, rng) {}
|
|
||||||
|
|
||||||
// outgoing client connection processing is not supported for this version
|
/// Fill in a set of request headers for a client connection request
|
||||||
lib::error_code client_handshake_request(request_type & req, uri_ptr uri,
|
/**
|
||||||
std::vector<std::string> const & subprotocols) const
|
* 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<std::string> const &) const
|
||||||
{
|
{
|
||||||
return error::make_error_code(error::no_protocol_support);
|
return error::make_error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -46,13 +46,20 @@ public:
|
|||||||
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
||||||
typedef typename config::rng_type rng_type;
|
typedef typename config::rng_type rng_type;
|
||||||
|
|
||||||
explicit hybi08(bool secure, bool server, msg_manager_ptr manager,
|
explicit hybi08(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||||
rng_type& rng)
|
: hybi13<config>(secure, p_is_server, manager, rng) {}
|
||||||
: hybi13<config>(secure, server, manager, rng) {}
|
|
||||||
|
|
||||||
// outgoing client connection processing is not supported for this version
|
/// Fill in a set of request headers for a client connection request
|
||||||
lib::error_code client_handshake_request(request_type& req, uri_ptr uri,
|
/**
|
||||||
std::vector<std::string> const & subprotocols) const
|
* 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<std::string> const &) const
|
||||||
{
|
{
|
||||||
return error::make_error_code(error::no_protocol_support);
|
return error::make_error_code(error::no_protocol_support);
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <websocketpp/frame.hpp>
|
#include <websocketpp/frame.hpp>
|
||||||
#include <websocketpp/utf8_validator.hpp>
|
#include <websocketpp/utf8_validator.hpp>
|
||||||
#include <websocketpp/common/network.hpp>
|
#include <websocketpp/common/network.hpp>
|
||||||
|
#include <websocketpp/common/platforms.hpp>
|
||||||
#include <websocketpp/http/constants.hpp>
|
#include <websocketpp/http/constants.hpp>
|
||||||
|
|
||||||
#include <websocketpp/processors/processor.hpp>
|
#include <websocketpp/processors/processor.hpp>
|
||||||
@@ -67,9 +68,8 @@ public:
|
|||||||
|
|
||||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||||
|
|
||||||
explicit hybi13(bool secure, bool server, msg_manager_ptr manager,
|
explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||||
rng_type& rng)
|
: processor<config>(secure, p_is_server)
|
||||||
: processor<config>(secure,server)
|
|
||||||
, m_msg_manager(manager)
|
, m_msg_manager(manager)
|
||||||
, m_rng(rng)
|
, m_rng(rng)
|
||||||
{
|
{
|
||||||
@@ -121,8 +121,8 @@ public:
|
|||||||
// Figure out if this is an error that should halt all
|
// Figure out if this is an error that should halt all
|
||||||
// extension negotiations or simply cause negotiation of
|
// extension negotiations or simply cause negotiation of
|
||||||
// this specific extension to fail.
|
// this specific extension to fail.
|
||||||
std::cout << "permessage-compress negotiation failed: "
|
//std::cout << "permessage-compress negotiation failed: "
|
||||||
<< neg_ret.first.message() << std::endl;
|
// << neg_ret.first.message() << std::endl;
|
||||||
} else {
|
} else {
|
||||||
// Note: this list will need commas if WebSocket++ ever
|
// Note: this list will need commas if WebSocket++ ever
|
||||||
// supports more than one extension
|
// supports more than one extension
|
||||||
@@ -182,7 +182,13 @@ public:
|
|||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
lib::error_code client_handshake_request(request_type& req, uri_ptr
|
/// 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<std::string> const & subprotocols) const
|
uri, std::vector<std::string> const & subprotocols) const
|
||||||
{
|
{
|
||||||
req.set_method("GET");
|
req.set_method("GET");
|
||||||
@@ -219,6 +225,12 @@ public:
|
|||||||
return lib::error_code();
|
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,
|
lib::error_code validate_server_handshake_response(request_type const & req,
|
||||||
response_type& res) const
|
response_type& res) const
|
||||||
{
|
{
|
||||||
@@ -369,11 +381,25 @@ public:
|
|||||||
m_current_msg = &m_control_msg;
|
m_current_msg = &m_control_msg;
|
||||||
} else {
|
} else {
|
||||||
if (!m_data_msg.msg_ptr) {
|
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_data_msg = msg_metadata(
|
||||||
m_msg_manager->get_message(op,m_bytes_needed),
|
m_msg_manager->get_message(op,m_bytes_needed),
|
||||||
frame::get_masking_key(m_basic_header,m_extended_header)
|
frame::get_masking_key(m_basic_header,m_extended_header)
|
||||||
);
|
);
|
||||||
} else {
|
} 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
|
// Each frame starts a new masking key. All other state
|
||||||
// remains between frames.
|
// remains between frames.
|
||||||
m_data_msg.prepared_key = prepare_masking_key(
|
m_data_msg.prepared_key = prepare_masking_key(
|
||||||
@@ -382,14 +408,15 @@ public:
|
|||||||
m_extended_header
|
m_extended_header
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
// TODO: reserve space in the existing message for the new bytes
|
|
||||||
|
out.reserve(out.size() + m_bytes_needed);
|
||||||
}
|
}
|
||||||
m_current_msg = &m_data_msg;
|
m_current_msg = &m_data_msg;
|
||||||
}
|
}
|
||||||
} else if (m_state == EXTENSION) {
|
} else if (m_state == EXTENSION) {
|
||||||
m_state = APPLICATION;
|
m_state = APPLICATION;
|
||||||
} else if (m_state == APPLICATION) {
|
} else if (m_state == APPLICATION) {
|
||||||
size_t bytes_to_process = std::min(m_bytes_needed,len-p);
|
size_t bytes_to_process = (std::min)(m_bytes_needed,len-p);
|
||||||
|
|
||||||
if (bytes_to_process > 0) {
|
if (bytes_to_process > 0) {
|
||||||
p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
|
p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
|
||||||
@@ -655,7 +682,7 @@ protected:
|
|||||||
|
|
||||||
/// Reads bytes from buf into m_extended_header
|
/// Reads bytes from buf into m_extended_header
|
||||||
size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
|
size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
|
||||||
size_t bytes_to_read = std::min(m_bytes_needed,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);
|
std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
|
||||||
m_cursor += bytes_to_read;
|
m_cursor += bytes_to_read;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -140,12 +140,12 @@ uri_ptr get_uri_from_host(request_type & request, std::string scheme) {
|
|||||||
if (last_colon == std::string::npos ||
|
if (last_colon == std::string::npos ||
|
||||||
(last_sbrace != std::string::npos && last_sbrace > last_colon))
|
(last_sbrace != std::string::npos && last_sbrace > last_colon))
|
||||||
{
|
{
|
||||||
return uri_ptr(new uri(scheme, h, request.get_uri()));
|
return lib::make_shared<uri>(scheme, h, request.get_uri());
|
||||||
} else {
|
} else {
|
||||||
return uri_ptr(new uri(scheme,
|
return lib::make_shared<uri>(scheme,
|
||||||
h.substr(0,last_colon),
|
h.substr(0,last_colon),
|
||||||
h.substr(last_colon+1),
|
h.substr(last_colon+1),
|
||||||
request.get_uri()));
|
request.get_uri());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,15 +159,45 @@ public:
|
|||||||
typedef typename config::message_type::ptr message_ptr;
|
typedef typename config::message_type::ptr message_ptr;
|
||||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||||
|
|
||||||
explicit processor(bool secure, bool server)
|
explicit processor(bool secure, bool p_is_server)
|
||||||
: m_secure(secure)
|
: m_secure(secure)
|
||||||
, m_server(server) {}
|
, m_server(p_is_server)
|
||||||
|
, m_max_message_size(config::max_message_size)
|
||||||
|
{}
|
||||||
|
|
||||||
virtual ~processor() {}
|
virtual ~processor() {}
|
||||||
|
|
||||||
/// Get the protocol version of this processor
|
/// Get the protocol version of this processor
|
||||||
virtual int get_version() const = 0;
|
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
|
/// Returns whether or not the permessage_compress extension is implemented
|
||||||
/**
|
/**
|
||||||
* Compile time flag that indicates whether this processor has implemented
|
* Compile time flag that indicates whether this processor has implemented
|
||||||
@@ -182,8 +212,10 @@ public:
|
|||||||
* Reads the Sec-WebSocket-Extensions header and determines if any of the
|
* Reads the Sec-WebSocket-Extensions header and determines if any of the
|
||||||
* requested extensions are supported by this processor. If they are their
|
* requested extensions are supported by this processor. If they are their
|
||||||
* settings data is initialized.
|
* settings data is initialized.
|
||||||
|
*
|
||||||
|
* @param request The request headers to look at.
|
||||||
*/
|
*/
|
||||||
virtual err_str_pair negotiate_extensions(request_type const & request) {
|
virtual err_str_pair negotiate_extensions(request_type const &) {
|
||||||
return err_str_pair();
|
return err_str_pair();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,8 +228,7 @@ public:
|
|||||||
* @return A status code, 0 on success, non-zero for specific sorts of
|
* @return A status code, 0 on success, non-zero for specific sorts of
|
||||||
* failure
|
* failure
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code validate_handshake(request_type const & request)
|
virtual lib::error_code validate_handshake(request_type const & request) const = 0;
|
||||||
const = 0;
|
|
||||||
|
|
||||||
/// Calculate the appropriate response for this websocket request
|
/// Calculate the appropriate response for this websocket request
|
||||||
/**
|
/**
|
||||||
@@ -224,9 +255,7 @@ public:
|
|||||||
/// Validate the server's response to an outgoing handshake request
|
/// Validate the server's response to an outgoing handshake request
|
||||||
/**
|
/**
|
||||||
* @param req The original request sent
|
* @param req The original request sent
|
||||||
*
|
|
||||||
* @param res The reponse to generate
|
* @param res The reponse to generate
|
||||||
*
|
|
||||||
* @return An error code, 0 on success, non-zero for other errors
|
* @return An error code, 0 on success, non-zero for other errors
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code validate_server_handshake_response(request_type
|
virtual lib::error_code validate_server_handshake_response(request_type
|
||||||
@@ -236,18 +265,16 @@ public:
|
|||||||
virtual std::string get_raw(response_type const & request) const = 0;
|
virtual std::string get_raw(response_type const & request) const = 0;
|
||||||
|
|
||||||
/// Return the value of the header containing the CORS origin.
|
/// Return the value of the header containing the CORS origin.
|
||||||
virtual std::string const & get_origin(request_type const & request)
|
virtual std::string const & get_origin(request_type const & request) const = 0;
|
||||||
const = 0;
|
|
||||||
|
|
||||||
/// Extracts requested subprotocols from a handshake request
|
/// Extracts requested subprotocols from a handshake request
|
||||||
/**
|
/**
|
||||||
* Extracts a list of all subprotocols that the client has requested in the
|
* Extracts a list of all subprotocols that the client has requested in the
|
||||||
* given opening handshake request.
|
* given opening handshake request.
|
||||||
*
|
*
|
||||||
* @param req The request to extract from
|
* @param [in] req The request to extract from
|
||||||
*
|
* @param [out] subprotocol_list A reference to a vector of strings to store
|
||||||
* @param subprotocol_list A reference to a vector of strings to store the
|
* the results in.
|
||||||
* results in.
|
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code extract_subprotocols(const request_type & req,
|
virtual lib::error_code extract_subprotocols(const request_type & req,
|
||||||
std::vector<std::string> & subprotocol_list) = 0;
|
std::vector<std::string> & subprotocol_list) = 0;
|
||||||
@@ -261,11 +288,8 @@ public:
|
|||||||
* interpreted by a protocol processor into discrete frames.
|
* interpreted by a protocol processor into discrete frames.
|
||||||
*
|
*
|
||||||
* @param buf Buffer from which bytes should be read.
|
* @param buf Buffer from which bytes should be read.
|
||||||
*
|
|
||||||
* @param len Length of buffer
|
* @param len Length of buffer
|
||||||
*
|
|
||||||
* @param ec Reference to an error code to return any errors in
|
* @param ec Reference to an error code to return any errors in
|
||||||
*
|
|
||||||
* @return Number of bytes processed
|
* @return Number of bytes processed
|
||||||
*/
|
*/
|
||||||
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
|
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
|
||||||
@@ -310,8 +334,7 @@ public:
|
|||||||
* Performs validation, masking, compression, etc. will return an error if
|
* Performs validation, masking, compression, etc. will return an error if
|
||||||
* there was an error, otherwise msg will be ready to be written
|
* 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)
|
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0;
|
||||||
= 0;
|
|
||||||
|
|
||||||
/// Prepare a ping frame
|
/// Prepare a ping frame
|
||||||
/**
|
/**
|
||||||
@@ -319,13 +342,11 @@ public:
|
|||||||
* other than length. Payload need not be UTF-8.
|
* other than length. Payload need not be UTF-8.
|
||||||
*
|
*
|
||||||
* @param in The string to use for the ping payload
|
* @param in The string to use for the ping payload
|
||||||
*
|
|
||||||
* @param out The message buffer to prepare the ping in.
|
* @param out The message buffer to prepare the ping in.
|
||||||
*
|
|
||||||
* @return Status code, zero on success, non-zero on failure
|
* @return Status code, zero on success, non-zero on failure
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code prepare_ping(std::string const & in,
|
virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const
|
||||||
message_ptr out) const = 0;
|
= 0;
|
||||||
|
|
||||||
/// Prepare a pong frame
|
/// Prepare a pong frame
|
||||||
/**
|
/**
|
||||||
@@ -333,13 +354,11 @@ public:
|
|||||||
* other than length. Payload need not be UTF-8.
|
* other than length. Payload need not be UTF-8.
|
||||||
*
|
*
|
||||||
* @param in The string to use for the pong payload
|
* @param in The string to use for the pong payload
|
||||||
*
|
|
||||||
* @param out The message buffer to prepare the pong in.
|
* @param out The message buffer to prepare the pong in.
|
||||||
*
|
|
||||||
* @return Status code, zero on success, non-zero on failure
|
* @return Status code, zero on success, non-zero on failure
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code prepare_pong(std::string const & in,
|
virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const
|
||||||
message_ptr out) const = 0;
|
= 0;
|
||||||
|
|
||||||
/// Prepare a close frame
|
/// Prepare a close frame
|
||||||
/**
|
/**
|
||||||
@@ -349,11 +368,8 @@ public:
|
|||||||
* indicate no code. If no code is supplied a reason may not be specified.
|
* indicate no code. If no code is supplied a reason may not be specified.
|
||||||
*
|
*
|
||||||
* @param code The close code to send
|
* @param code The close code to send
|
||||||
*
|
|
||||||
* @param reason The reason string to send
|
* @param reason The reason string to send
|
||||||
*
|
|
||||||
* @param out The message buffer to prepare the fame in
|
* @param out The message buffer to prepare the fame in
|
||||||
*
|
|
||||||
* @return Status code, zero on success, non-zero on failure
|
* @return Status code, zero on success, non-zero on failure
|
||||||
*/
|
*/
|
||||||
virtual lib::error_code prepare_close(close::status::value code,
|
virtual lib::error_code prepare_close(close::status::value code,
|
||||||
@@ -361,6 +377,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool const m_secure;
|
bool const m_secure;
|
||||||
bool const m_server;
|
bool const m_server;
|
||||||
|
size_t m_max_message_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace processor
|
} // namespace processor
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
#define WEBSOCKETPP_RANDOM_NONE_HPP
|
#define WEBSOCKETPP_RANDOM_NONE_HPP
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
|
/// Random number generation policies
|
||||||
namespace random {
|
namespace random {
|
||||||
/// Stub RNG policy that always returns 0
|
/// Stub RNG policy that always returns 0
|
||||||
namespace none {
|
namespace none {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -112,7 +112,7 @@ public:
|
|||||||
* @return A connection_ptr to the new connection
|
* @return A connection_ptr to the new connection
|
||||||
*/
|
*/
|
||||||
connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
|
connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
|
||||||
uri_ptr location(new uri(u));
|
uri_ptr location = lib::make_shared<uri>(u);
|
||||||
|
|
||||||
if (!location->get_valid()) {
|
if (!location->get_valid()) {
|
||||||
ec = error::make_error_code(error::invalid_uri);
|
ec = error::make_error_code(error::invalid_uri);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -64,52 +64,101 @@ public:
|
|||||||
/// Type of the endpoint component of this server
|
/// Type of the endpoint component of this server
|
||||||
typedef endpoint<connection_type,config> endpoint_type;
|
typedef endpoint<connection_type,config> endpoint_type;
|
||||||
|
|
||||||
|
|
||||||
// TODO: clean up these types
|
|
||||||
|
|
||||||
explicit server() : endpoint_type(true)
|
explicit server() : endpoint_type(true)
|
||||||
{
|
{
|
||||||
endpoint_type::m_alog.write(log::alevel::devel,
|
endpoint_type::m_alog.write(log::alevel::devel, "server constructor");
|
||||||
"server constructor");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return an initialized connection_ptr. Call start() on this object to
|
/// Create and initialize a new connection
|
||||||
// begin the processing loop.
|
/**
|
||||||
|
* 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() {
|
connection_ptr get_connection() {
|
||||||
connection_ptr con = endpoint_type::create_connection();
|
return endpoint_type::create_connection();
|
||||||
|
|
||||||
return con;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts the server's async connection acceptance loop.
|
/// Starts the server's async connection acceptance loop (exception free)
|
||||||
void start_accept() {
|
/**
|
||||||
|
* 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();
|
connection_ptr con = get_connection();
|
||||||
|
|
||||||
transport_type::async_accept(
|
transport_type::async_accept(
|
||||||
lib::static_pointer_cast<transport_con_type>(con),
|
lib::static_pointer_cast<transport_con_type>(con),
|
||||||
lib::bind(
|
lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
|
||||||
&type::handle_accept,
|
ec
|
||||||
this,
|
|
||||||
con,
|
|
||||||
lib::placeholders::_1
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (ec && con) {
|
||||||
|
// If the connection was constructed but the accept failed,
|
||||||
|
// terminate the connection to prevent memory leaks
|
||||||
|
con->terminate(lib::error_code());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_accept(connection_ptr con, const lib::error_code& ec) {
|
/// 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) {
|
if (ec) {
|
||||||
con->terminate(ec);
|
con->terminate(ec);
|
||||||
|
|
||||||
endpoint_type::m_elog.write(log::elevel::rerror,
|
if (ec == error::operation_canceled) {
|
||||||
"handle_accept error: "+ec.message());
|
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 {
|
} else {
|
||||||
con->start();
|
con->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: are there cases where we should terminate this loop?
|
lib::error_code start_ec;
|
||||||
start_accept();
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
+189
-184
@@ -1,184 +1,189 @@
|
|||||||
/*
|
/*
|
||||||
*****
|
*****
|
||||||
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the shallsha1
|
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
|
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
|
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
|
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||||
under the same license as the original, which is listed below.
|
under the same license as the original, which is listed below.
|
||||||
*****
|
*****
|
||||||
|
|
||||||
Copyright (c) 2011, Micael Hildenborg
|
Copyright (c) 2011, Micael Hildenborg
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of Micael Hildenborg nor the
|
* Neither the name of Micael Hildenborg nor the
|
||||||
names of its contributors may be used to endorse or promote products
|
names of its contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior written permission.
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SHA1_DEFINED
|
#ifndef SHA1_DEFINED
|
||||||
#define SHA1_DEFINED
|
#define SHA1_DEFINED
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace sha1 {
|
namespace sha1 {
|
||||||
|
|
||||||
namespace // local
|
namespace { // local
|
||||||
{
|
|
||||||
// Rotate an integer value to left.
|
// Rotate an integer value to left.
|
||||||
inline const unsigned int rol(const unsigned int value,
|
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||||
const unsigned int steps)
|
return ((value << steps) | (value >> (32 - steps)));
|
||||||
{
|
}
|
||||||
return ((value << steps) | (value >> (32 - steps)));
|
|
||||||
}
|
// Sets the first 16 integers in the buffert to zero.
|
||||||
|
// Used for clearing the W buffert.
|
||||||
// Sets the first 16 integers in the buffert to zero.
|
inline void clearWBuffert(unsigned int * buffert)
|
||||||
// Used for clearing the W buffert.
|
{
|
||||||
inline void clearWBuffert(unsigned int* buffert)
|
for (int pos = 16; --pos >= 0;)
|
||||||
{
|
{
|
||||||
for (int pos = 16; --pos >= 0;)
|
buffert[pos] = 0;
|
||||||
{
|
}
|
||||||
buffert[pos] = 0;
|
}
|
||||||
}
|
|
||||||
}
|
inline void innerHash(unsigned int * result, unsigned int * w)
|
||||||
|
{
|
||||||
inline void innerHash(unsigned int* result, unsigned int* w)
|
unsigned int a = result[0];
|
||||||
{
|
unsigned int b = result[1];
|
||||||
unsigned int a = result[0];
|
unsigned int c = result[2];
|
||||||
unsigned int b = result[1];
|
unsigned int d = result[3];
|
||||||
unsigned int c = result[2];
|
unsigned int e = result[4];
|
||||||
unsigned int d = result[3];
|
|
||||||
unsigned int e = result[4];
|
int round = 0;
|
||||||
|
|
||||||
int round = 0;
|
#define sha1macro(func,val) \
|
||||||
|
{ \
|
||||||
#define sha1macro(func,val) \
|
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||||
{ \
|
e = d; \
|
||||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
d = c; \
|
||||||
e = d; \
|
c = rol(b, 30); \
|
||||||
d = c; \
|
b = a; \
|
||||||
c = rol(b, 30); \
|
a = t; \
|
||||||
b = a; \
|
}
|
||||||
a = t; \
|
|
||||||
}
|
while (round < 16)
|
||||||
|
{
|
||||||
while (round < 16)
|
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||||
{
|
++round;
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
}
|
||||||
++round;
|
while (round < 20)
|
||||||
}
|
{
|
||||||
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)
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
++round;
|
||||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
}
|
||||||
++round;
|
while (round < 40)
|
||||||
}
|
{
|
||||||
while (round < 40)
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
{
|
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
++round;
|
||||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
}
|
||||||
++round;
|
while (round < 60)
|
||||||
}
|
{
|
||||||
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)
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
++round;
|
||||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
}
|
||||||
++round;
|
while (round < 80)
|
||||||
}
|
{
|
||||||
while (round < 80)
|
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||||
{
|
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
++round;
|
||||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
}
|
||||||
++round;
|
|
||||||
}
|
#undef sha1macro
|
||||||
|
|
||||||
#undef sha1macro
|
result[0] += a;
|
||||||
|
result[1] += b;
|
||||||
result[0] += a;
|
result[2] += c;
|
||||||
result[1] += b;
|
result[3] += d;
|
||||||
result[2] += c;
|
result[4] += e;
|
||||||
result[3] += d;
|
}
|
||||||
result[4] += e;
|
|
||||||
}
|
} // namespace
|
||||||
} // namespace
|
|
||||||
|
/// Calculate a SHA1 hash
|
||||||
/**
|
/**
|
||||||
@param src points to any kind of data to be hashed.
|
* @param src points to any kind of data to be hashed.
|
||||||
@param bytelength the number of bytes to hash from the src pointer.
|
* @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.
|
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||||
*/
|
* the sha1 result in.
|
||||||
inline void calc(const void* src, const int bytelength, unsigned char* hash) {
|
*/
|
||||||
// Init the result array.
|
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
|
// Init the result array.
|
||||||
|
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
||||||
// Cast the void src pointer to be the byte array we can work with.
|
0x10325476, 0xc3d2e1f0 };
|
||||||
const unsigned char* sarray = (const unsigned char*) src;
|
|
||||||
|
// Cast the void src pointer to be the byte array we can work with.
|
||||||
// The reusable round buffer
|
unsigned char const * sarray = (unsigned char const *) src;
|
||||||
unsigned int w[80];
|
|
||||||
|
// The reusable round buffer
|
||||||
// Loop through all complete 64byte blocks.
|
unsigned int w[80];
|
||||||
const int endOfFullBlocks = bytelength - 64;
|
|
||||||
int endCurrentBlock;
|
// Loop through all complete 64byte blocks.
|
||||||
int currentBlock = 0;
|
|
||||||
|
size_t endCurrentBlock;
|
||||||
while (currentBlock <= endOfFullBlocks)
|
size_t currentBlock = 0;
|
||||||
{
|
|
||||||
endCurrentBlock = currentBlock + 64;
|
if (bytelength >= 64) {
|
||||||
|
size_t const endOfFullBlocks = bytelength - 64;
|
||||||
// Init the round buffer with the 64 byte block data.
|
|
||||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
while (currentBlock <= endOfFullBlocks) {
|
||||||
{
|
endCurrentBlock = currentBlock + 64;
|
||||||
// This line will swap endian on big endian and keep endian on little endian.
|
|
||||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
// Init the round buffer with the 64 byte block data.
|
||||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
{
|
||||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
// This line will swap endian on big endian and keep endian on
|
||||||
}
|
// little endian.
|
||||||
innerHash(result, w);
|
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||||
}
|
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||||
|
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||||
// Handle the last and not full 64 byte block if existing.
|
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||||
endCurrentBlock = bytelength - currentBlock;
|
}
|
||||||
clearWBuffert(w);
|
innerHash(result, w);
|
||||||
int lastBlockBytes = 0;
|
}
|
||||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes)
|
}
|
||||||
{
|
|
||||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
// Handle the last and not full 64 byte block if existing.
|
||||||
}
|
endCurrentBlock = bytelength - currentBlock;
|
||||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
clearWBuffert(w);
|
||||||
if (endCurrentBlock >= 56)
|
size_t lastBlockBytes = 0;
|
||||||
{
|
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||||
innerHash(result, w);
|
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
clearWBuffert(w);
|
}
|
||||||
}
|
|
||||||
w[15] = bytelength << 3;
|
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||||
innerHash(result, w);
|
if (endCurrentBlock >= 56) {
|
||||||
|
innerHash(result, w);
|
||||||
// Store hash in result pointer, and make sure we get in in the correct order on both endian models.
|
clearWBuffert(w);
|
||||||
for (int hashByte = 20; --hashByte >= 0;)
|
}
|
||||||
{
|
w[15] = bytelength << 3;
|
||||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
innerHash(result, w);
|
||||||
}
|
|
||||||
}
|
// Store hash in result pointer, and make sure we get in in the correct
|
||||||
|
// order on both endian models.
|
||||||
} // namespace sha1
|
for (int hashByte = 20; --hashByte >= 0;) {
|
||||||
} // namespace websocketpp
|
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||||
|
}
|
||||||
#endif // SHA1_DEFINED
|
}
|
||||||
|
|
||||||
|
} // namespace sha1
|
||||||
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
#endif // SHA1_DEFINED
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||||
#define WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
#define WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||||
|
|
||||||
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
#include <websocketpp/common/memory.hpp>
|
#include <websocketpp/common/memory.hpp>
|
||||||
#include <websocketpp/common/functional.hpp>
|
#include <websocketpp/common/functional.hpp>
|
||||||
#include <websocketpp/common/connection_hdl.hpp>
|
#include <websocketpp/common/connection_hdl.hpp>
|
||||||
@@ -115,7 +116,7 @@ public:
|
|||||||
* established but before any additional wrappers (proxy connects, TLS
|
* established but before any additional wrappers (proxy connects, TLS
|
||||||
* handshakes, etc) have been performed.
|
* handshakes, etc) have been performed.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*
|
*
|
||||||
* @param h The handler to call on tcp pre init.
|
* @param h The handler to call on tcp pre init.
|
||||||
*/
|
*/
|
||||||
@@ -144,7 +145,7 @@ public:
|
|||||||
* etc have been performed. This is fired before any bytes are read or any
|
* etc have been performed. This is fired before any bytes are read or any
|
||||||
* WebSocket specific handshake logic has been performed.
|
* WebSocket specific handshake logic has been performed.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*
|
*
|
||||||
* @param h The handler to call on tcp post init.
|
* @param h The handler to call on tcp post init.
|
||||||
*/
|
*/
|
||||||
@@ -164,19 +165,19 @@ public:
|
|||||||
*
|
*
|
||||||
* @param ec A status value
|
* @param ec A status value
|
||||||
*/
|
*/
|
||||||
void set_proxy(const std::string & uri, lib::error_code & ec) {
|
void set_proxy(std::string const & uri, lib::error_code & ec) {
|
||||||
// TODO: return errors for illegal URIs here?
|
// TODO: return errors for illegal URIs here?
|
||||||
// TODO: should https urls be illegal for the moment?
|
// TODO: should https urls be illegal for the moment?
|
||||||
m_proxy = uri;
|
m_proxy = uri;
|
||||||
m_proxy_data.reset(new proxy_data());
|
m_proxy_data = lib::make_shared<proxy_data>();
|
||||||
ec = lib::error_code();
|
ec = lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the proxy to connect through (exception)
|
/// Set the proxy to connect through (exception)
|
||||||
void set_proxy(const std::string & uri) {
|
void set_proxy(std::string const & uri) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
set_proxy(uri,ec);
|
set_proxy(uri,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the basic auth credentials to use (exception free)
|
/// Set the basic auth credentials to use (exception free)
|
||||||
@@ -192,8 +193,8 @@ public:
|
|||||||
*
|
*
|
||||||
* @param ec A status value
|
* @param ec A status value
|
||||||
*/
|
*/
|
||||||
void set_proxy_basic_auth(const std::string & username, const
|
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||||
std::string & password, lib::error_code & ec)
|
password, lib::error_code & ec)
|
||||||
{
|
{
|
||||||
if (!m_proxy_data) {
|
if (!m_proxy_data) {
|
||||||
ec = make_error_code(websocketpp::error::invalid_state);
|
ec = make_error_code(websocketpp::error::invalid_state);
|
||||||
@@ -207,12 +208,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the basic auth credentials to use (exception)
|
/// Set the basic auth credentials to use (exception)
|
||||||
void set_proxy_basic_auth(const std::string & username, const
|
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||||
std::string & password)
|
password)
|
||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
set_proxy_basic_auth(username,password,ec);
|
set_proxy_basic_auth(username,password,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the proxy timeout duration (exception free)
|
/// Set the proxy timeout duration (exception free)
|
||||||
@@ -239,7 +240,7 @@ public:
|
|||||||
void set_proxy_timeout(long duration) {
|
void set_proxy_timeout(long duration) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
set_proxy_timeout(duration,ec);
|
set_proxy_timeout(duration,ec);
|
||||||
if (ec) { throw ec; }
|
if (ec) { throw exception(ec); }
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & get_proxy() const {
|
const std::string & get_proxy() const {
|
||||||
@@ -289,11 +290,9 @@ public:
|
|||||||
* needed.
|
* needed.
|
||||||
*/
|
*/
|
||||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||||
timer_ptr new_timer(
|
timer_ptr new_timer = lib::make_shared<boost::asio::deadline_timer>(
|
||||||
new boost::asio::deadline_timer(
|
lib::ref(*m_io_service),
|
||||||
*m_io_service,
|
boost::posix_time::milliseconds(duration)
|
||||||
boost::posix_time::milliseconds(duration)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (config::enable_multithreading) {
|
if (config::enable_multithreading) {
|
||||||
@@ -322,11 +321,11 @@ public:
|
|||||||
*
|
*
|
||||||
* TODO: candidate for protected status
|
* TODO: candidate for protected status
|
||||||
*
|
*
|
||||||
* @param t Pointer to the timer in question
|
* @param post_timer Pointer to the timer in question
|
||||||
* @param callback The function to call back
|
* @param callback The function to call back
|
||||||
* @param ec The status code
|
* @param ec The status code
|
||||||
*/
|
*/
|
||||||
void handle_timer(timer_ptr t, timer_handler callback,
|
void handle_timer(timer_ptr, timer_handler callback,
|
||||||
boost::system::error_code const & ec)
|
boost::system::error_code const & ec)
|
||||||
{
|
{
|
||||||
if (ec) {
|
if (ec) {
|
||||||
@@ -407,7 +406,7 @@ protected:
|
|||||||
/// Finish constructing the transport
|
/// Finish constructing the transport
|
||||||
/**
|
/**
|
||||||
* init_asio is called once immediately after construction to initialize
|
* init_asio is called once immediately after construction to initialize
|
||||||
* boost::asio components to the io_service
|
* boost::asio components to the io_service.
|
||||||
*
|
*
|
||||||
* @param io_service A pointer to the io_service to register with this
|
* @param io_service A pointer to the io_service to register with this
|
||||||
* connection
|
* connection
|
||||||
@@ -415,35 +414,38 @@ protected:
|
|||||||
* @return Status code for the success or failure of the initialization
|
* @return Status code for the success or failure of the initialization
|
||||||
*/
|
*/
|
||||||
lib::error_code init_asio (io_service_ptr io_service) {
|
lib::error_code init_asio (io_service_ptr io_service) {
|
||||||
// do we need to store or use the io_service at this level?
|
|
||||||
m_io_service = io_service;
|
m_io_service = io_service;
|
||||||
|
|
||||||
if (config::enable_multithreading) {
|
if (config::enable_multithreading) {
|
||||||
m_strand.reset(new boost::asio::strand(*io_service));
|
m_strand = lib::make_shared<boost::asio::strand>(
|
||||||
|
lib::ref(*io_service));
|
||||||
|
|
||||||
m_async_read_handler = m_strand->wrap(lib::bind(
|
m_async_read_handler = m_strand->wrap(lib::bind(
|
||||||
&type::handle_async_read, get_shared(),
|
&type::handle_async_read, get_shared(),lib::placeholders::_1,
|
||||||
lib::placeholders::_1, lib::placeholders::_2
|
lib::placeholders::_2));
|
||||||
));
|
|
||||||
|
|
||||||
m_async_write_handler = m_strand->wrap(lib::bind(
|
m_async_write_handler = m_strand->wrap(lib::bind(
|
||||||
&type::handle_async_write, get_shared(),
|
&type::handle_async_write, get_shared(),lib::placeholders::_1,
|
||||||
lib::placeholders::_1, lib::placeholders::_2
|
lib::placeholders::_2));
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: goal: not have this line here
|
m_async_read_handler = lib::bind(&type::handle_async_read,
|
||||||
//m_strand.reset(new boost::asio::strand(*io_service));
|
get_shared(), lib::placeholders::_1, lib::placeholders::_2);
|
||||||
|
|
||||||
m_async_read_handler = lib::bind(
|
|
||||||
&type::handle_async_read, get_shared(),
|
|
||||||
lib::placeholders::_1, lib::placeholders::_2
|
|
||||||
);
|
|
||||||
|
|
||||||
m_async_write_handler = lib::bind(&type::handle_async_write,
|
m_async_write_handler = lib::bind(&type::handle_async_write,
|
||||||
get_shared(), lib::placeholders::_1, lib::placeholders::_2);
|
get_shared(), lib::placeholders::_1, lib::placeholders::_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return socket_con_type::init_asio(io_service, m_strand, m_is_server);
|
lib::error_code ec = socket_con_type::init_asio(io_service, m_strand,
|
||||||
|
m_is_server);
|
||||||
|
|
||||||
|
if (ec) {
|
||||||
|
// reset the handlers to break the circular reference:
|
||||||
|
// this->handler->this
|
||||||
|
lib::clear_function(m_async_read_handler);
|
||||||
|
lib::clear_function(m_async_write_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pre_init(lib::error_code const & ec) {
|
void handle_pre_init(lib::error_code const & ec) {
|
||||||
@@ -474,16 +476,19 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer_ptr post_timer;
|
timer_ptr post_timer;
|
||||||
post_timer = set_timer(
|
|
||||||
config::timeout_socket_post_init,
|
if (config::timeout_socket_post_init > 0) {
|
||||||
lib::bind(
|
post_timer = set_timer(
|
||||||
&type::handle_post_init_timeout,
|
config::timeout_socket_post_init,
|
||||||
get_shared(),
|
lib::bind(
|
||||||
post_timer,
|
&type::handle_post_init_timeout,
|
||||||
m_init_handler,
|
get_shared(),
|
||||||
lib::placeholders::_1
|
post_timer,
|
||||||
)
|
m_init_handler,
|
||||||
);
|
lib::placeholders::_1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
socket_con_type::post_init(
|
socket_con_type::post_init(
|
||||||
lib::bind(
|
lib::bind(
|
||||||
@@ -496,8 +501,17 @@ protected:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_post_init_timeout(timer_ptr post_timer, init_handler callback,
|
/// Post init timeout callback
|
||||||
const lib::error_code& ec)
|
/**
|
||||||
|
* 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;
|
lib::error_code ret_ec;
|
||||||
|
|
||||||
@@ -523,23 +537,34 @@ protected:
|
|||||||
callback(ret_ec);
|
callback(ret_ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_post_init(timer_ptr post_timer, init_handler callback, const
|
/// Post init timeout callback
|
||||||
lib::error_code& ec)
|
/**
|
||||||
|
* 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 ||
|
if (ec == transport::error::operation_aborted ||
|
||||||
post_timer->expires_from_now().is_negative())
|
(post_timer && post_timer->expires_from_now().is_negative()))
|
||||||
{
|
{
|
||||||
m_alog.write(log::alevel::devel,"post_init cancelled");
|
m_alog.write(log::alevel::devel,"post_init cancelled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
post_timer->cancel();
|
if (post_timer) {
|
||||||
|
post_timer->cancel();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_alog.static_test(log::alevel::devel)) {
|
if (m_alog.static_test(log::alevel::devel)) {
|
||||||
m_alog.write(log::alevel::devel,"asio connection handle_post_init");
|
m_alog.write(log::alevel::devel,"asio connection handle_post_init");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tcp_post_init_handler) {
|
if (m_tcp_post_init_handler) {
|
||||||
m_tcp_post_init_handler(m_connection_hdl);
|
m_tcp_post_init_handler(m_connection_hdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,8 +710,14 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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,
|
void handle_proxy_read(init_handler callback,
|
||||||
boost::system::error_code const & ec, size_t bytes_transferred)
|
boost::system::error_code const & ec, size_t)
|
||||||
{
|
{
|
||||||
if (m_alog.static_test(log::alevel::devel)) {
|
if (m_alog.static_test(log::alevel::devel)) {
|
||||||
m_alog.write(log::alevel::devel,
|
m_alog.write(log::alevel::devel,
|
||||||
@@ -779,7 +810,7 @@ protected:
|
|||||||
if (!m_async_read_handler) {
|
if (!m_async_read_handler) {
|
||||||
m_alog.write(log::alevel::devel,
|
m_alog.write(log::alevel::devel,
|
||||||
"async_read_at_least called after async_shutdown");
|
"async_read_at_least called after async_shutdown");
|
||||||
handler(make_error_code(transport::error::action_after_shutdown), 0);
|
handler(make_error_code(transport::error::action_after_shutdown),0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,36 +826,54 @@ protected:
|
|||||||
|
|
||||||
m_read_handler = handler;
|
m_read_handler = handler;
|
||||||
|
|
||||||
|
if (!m_read_handler) {
|
||||||
|
m_alog.write(log::alevel::devel,
|
||||||
|
"asio con async_read_at_least called with bad handler");
|
||||||
|
}
|
||||||
|
|
||||||
boost::asio::async_read(
|
boost::asio::async_read(
|
||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
boost::asio::buffer(buf,len),
|
boost::asio::buffer(buf,len),
|
||||||
boost::asio::transfer_at_least(num_bytes),
|
boost::asio::transfer_at_least(num_bytes),
|
||||||
make_custom_alloc_handler(
|
make_custom_alloc_handler(
|
||||||
m_read_handler_allocator,
|
m_read_handler_allocator,
|
||||||
m_async_read_handler
|
m_async_read_handler
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_async_read(const boost::system::error_code& ec,
|
void handle_async_read(boost::system::error_code const & ec,
|
||||||
size_t bytes_transferred)
|
size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
if (!ec) {
|
m_alog.write(log::alevel::devel, "asio con handle_async_read");
|
||||||
m_read_handler(lib::error_code(), bytes_transferred);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// translate boost error codes into more lib::error_codes
|
// translate boost error codes into more lib::error_codes
|
||||||
|
lib::error_code tec;
|
||||||
if (ec == boost::asio::error::eof) {
|
if (ec == boost::asio::error::eof) {
|
||||||
m_read_handler(make_error_code(transport::error::eof),
|
tec = make_error_code(transport::error::eof);
|
||||||
bytes_transferred);
|
} else if (ec) {
|
||||||
} else if (ec.value() == 335544539) {
|
// We don't know much more about the error at this point. As our
|
||||||
m_read_handler(make_error_code(transport::error::tls_short_read),
|
// socket/security policy if it knows more:
|
||||||
bytes_transferred);
|
tec = socket_con_type::translate_ec(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 (m_read_handler) {
|
||||||
|
m_read_handler(tec,bytes_transferred);
|
||||||
|
// TODO: why does this line break things?
|
||||||
|
//m_read_handler = _WEBSOCKETPP_NULL_FUNCTION_;
|
||||||
} else {
|
} else {
|
||||||
log_err(log::elevel::info,"asio async_read_at_least",ec);
|
// This can happen in cases where the connection is terminated while
|
||||||
m_read_handler(make_error_code(transport::error::pass_through),
|
// the transport is waiting on a read.
|
||||||
bytes_transferred);
|
m_alog.write(log::alevel::devel,
|
||||||
|
"handle_async_read called with null read handler");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,7 +885,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bufs.push_back(boost::asio::buffer(buf,len));
|
m_bufs.push_back(boost::asio::buffer(buf,len));
|
||||||
|
|
||||||
m_write_handler = handler;
|
m_write_handler = handler;
|
||||||
|
|
||||||
@@ -844,8 +893,8 @@ protected:
|
|||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
m_bufs,
|
m_bufs,
|
||||||
make_custom_alloc_handler(
|
make_custom_alloc_handler(
|
||||||
m_write_handler_allocator,
|
m_write_handler_allocator,
|
||||||
m_async_write_handler
|
m_async_write_handler
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -869,21 +918,33 @@ protected:
|
|||||||
socket_con_type::get_socket(),
|
socket_con_type::get_socket(),
|
||||||
m_bufs,
|
m_bufs,
|
||||||
make_custom_alloc_handler(
|
make_custom_alloc_handler(
|
||||||
m_write_handler_allocator,
|
m_write_handler_allocator,
|
||||||
m_async_write_handler
|
m_async_write_handler
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_async_write(boost::system::error_code const & ec,
|
/// Async write callback
|
||||||
size_t bytes_transferred)
|
/**
|
||||||
{
|
* @param ec The status code
|
||||||
|
* @param bytes_transferred The number of bytes read
|
||||||
|
*/
|
||||||
|
void handle_async_write(boost::system::error_code const & ec, size_t) {
|
||||||
m_bufs.clear();
|
m_bufs.clear();
|
||||||
|
lib::error_code tec;
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_write",ec);
|
log_err(log::elevel::info,"asio async_write",ec);
|
||||||
m_write_handler(make_error_code(transport::error::pass_through));
|
tec = make_error_code(transport::error::pass_through);
|
||||||
|
}
|
||||||
|
if (m_write_handler) {
|
||||||
|
m_write_handler(tec);
|
||||||
|
// TODO: why does this line break things?
|
||||||
|
//m_write_handler = _WEBSOCKETPP_NULL_FUNCTION_;
|
||||||
} else {
|
} else {
|
||||||
m_write_handler(lib::error_code());
|
// 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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,12 +992,15 @@ protected:
|
|||||||
m_alog.write(log::alevel::devel,"asio connection async_shutdown");
|
m_alog.write(log::alevel::devel,"asio connection async_shutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset cached handlers now that we won't be reading or writing anymore
|
// Reset cached handlers now that we won't be reading or writing anymore
|
||||||
// These cached handlers store shared pointers to this connection and will leak
|
// These cached handlers store shared pointers to this connection and
|
||||||
// the connection if not destroyed.
|
// will leak the connection if not destroyed.
|
||||||
m_async_read_handler = 0;
|
lib::clear_function(m_async_read_handler);
|
||||||
m_async_write_handler = 0;
|
lib::clear_function(m_async_write_handler);
|
||||||
m_init_handler = 0;
|
lib::clear_function(m_init_handler);
|
||||||
|
|
||||||
|
lib::clear_function(m_read_handler);
|
||||||
|
lib::clear_function(m_write_handler);
|
||||||
|
|
||||||
timer_ptr shutdown_timer;
|
timer_ptr shutdown_timer;
|
||||||
shutdown_timer = set_timer(
|
shutdown_timer = set_timer(
|
||||||
@@ -961,8 +1025,14 @@ protected:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_async_shutdown_timeout(timer_ptr shutdown_timer, init_handler
|
/// Async shutdown timeout handler
|
||||||
callback, const lib::error_code& ec)
|
/**
|
||||||
|
* @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;
|
lib::error_code ret_ec;
|
||||||
|
|
||||||
@@ -973,7 +1043,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_err(log::elevel::devel,"asio handle_async_socket_shutdown",ec);
|
log_err(log::elevel::devel,"asio handle_async_shutdown_timeout",ec);
|
||||||
ret_ec = ec;
|
ret_ec = ec;
|
||||||
} else {
|
} else {
|
||||||
ret_ec = make_error_code(transport::error::timeout);
|
ret_ec = make_error_code(transport::error::timeout);
|
||||||
@@ -986,7 +1056,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_async_shutdown(timer_ptr shutdown_timer, shutdown_handler
|
void handle_async_shutdown(timer_ptr shutdown_timer, shutdown_handler
|
||||||
callback, const boost::system::error_code & ec)
|
callback, boost::system::error_code const & ec)
|
||||||
{
|
{
|
||||||
if (ec == boost::asio::error::operation_aborted ||
|
if (ec == boost::asio::error::operation_aborted ||
|
||||||
shutdown_timer->expires_from_now().is_negative())
|
shutdown_timer->expires_from_now().is_negative())
|
||||||
@@ -997,25 +1067,37 @@ protected:
|
|||||||
|
|
||||||
shutdown_timer->cancel();
|
shutdown_timer->cancel();
|
||||||
|
|
||||||
|
lib::error_code tec;
|
||||||
if (ec) {
|
if (ec) {
|
||||||
log_err(log::elevel::info,"asio async_shutdown",ec);
|
|
||||||
if (ec == boost::asio::error::not_connected) {
|
if (ec == boost::asio::error::not_connected) {
|
||||||
// The socket was already closed when we tried to close it. This
|
// The socket was already closed when we tried to close it. This
|
||||||
// happens periodically (usually if a read or write fails
|
// happens periodically (usually if a read or write fails
|
||||||
// earlier and if it is a real error will be caught at another
|
// earlier and if it is a real error will be caught at another
|
||||||
// level of the stack.
|
// level of the stack.
|
||||||
callback(lib::error_code());
|
|
||||||
} else {
|
} else {
|
||||||
callback(make_error_code(transport::error::pass_through));
|
// 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);
|
||||||
|
|
||||||
|
if (tec == transport::error::tls_short_read) {
|
||||||
|
// TLS short read at this point is somewhat expected if both
|
||||||
|
// sides try and end the connection at the same time or if
|
||||||
|
// SSLv2 is being used. In general there is nothing that can
|
||||||
|
// be done here other than a low level development log.
|
||||||
|
} else {
|
||||||
|
// all other errors are effectively pass through errors of
|
||||||
|
// some sort so print some detail on the info channel for
|
||||||
|
// library users to look up if needed.
|
||||||
|
log_err(log::elevel::info,"asio async_shutdown",ec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_alog.static_test(log::alevel::devel)) {
|
if (m_alog.static_test(log::alevel::devel)) {
|
||||||
m_alog.write(log::alevel::devel,
|
m_alog.write(log::alevel::devel,
|
||||||
"asio con handle_async_shutdown");
|
"asio con handle_async_shutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(lib::error_code());
|
|
||||||
}
|
}
|
||||||
|
callback(tec);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
/// Convenience method for logging the code and message for an error_code
|
/// Convenience method for logging the code and message for an error_code
|
||||||
|
|||||||
+106
-58
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -38,8 +38,6 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace transport {
|
namespace transport {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
@@ -89,8 +87,10 @@ public:
|
|||||||
|
|
||||||
// generate and manage our own io_service
|
// generate and manage our own io_service
|
||||||
explicit endpoint()
|
explicit endpoint()
|
||||||
: m_external_io_service(false)
|
: m_io_service(NULL)
|
||||||
|
, m_external_io_service(false)
|
||||||
, m_listen_backlog(0)
|
, m_listen_backlog(0)
|
||||||
|
, m_reuse_addr(false)
|
||||||
, m_state(UNINITIALIZED)
|
, m_state(UNINITIALIZED)
|
||||||
{
|
{
|
||||||
//std::cout << "transport::asio::endpoint constructor" << std::endl;
|
//std::cout << "transport::asio::endpoint constructor" << std::endl;
|
||||||
@@ -122,7 +122,8 @@ public:
|
|||||||
: m_io_service(src.m_io_service)
|
: m_io_service(src.m_io_service)
|
||||||
, m_external_io_service(src.m_external_io_service)
|
, m_external_io_service(src.m_external_io_service)
|
||||||
, m_acceptor(src.m_acceptor)
|
, m_acceptor(src.m_acceptor)
|
||||||
, m_listen_backlog(0)
|
, m_listen_backlog(boost::asio::socket_base::max_connections)
|
||||||
|
, m_reuse_addr(src.m_reuse_addr)
|
||||||
, m_state(src.m_state)
|
, m_state(src.m_state)
|
||||||
{
|
{
|
||||||
src.m_io_service = NULL;
|
src.m_io_service = NULL;
|
||||||
@@ -136,13 +137,14 @@ public:
|
|||||||
m_io_service = rhs.m_io_service;
|
m_io_service = rhs.m_io_service;
|
||||||
m_external_io_service = rhs.m_external_io_service;
|
m_external_io_service = rhs.m_external_io_service;
|
||||||
m_acceptor = rhs.m_acceptor;
|
m_acceptor = rhs.m_acceptor;
|
||||||
m_listen_backlog = rhs.m_listen_backlog
|
m_listen_backlog = rhs.m_listen_backlog;
|
||||||
|
m_reuse_addr = rhs.m_reuse_addr;
|
||||||
m_state = rhs.m_state;
|
m_state = rhs.m_state;
|
||||||
|
|
||||||
rhs.m_io_service = NULL;
|
rhs.m_io_service = NULL;
|
||||||
rhs.m_external_io_service = false;
|
rhs.m_external_io_service = false;
|
||||||
rhs.m_acceptor = NULL;
|
rhs.m_acceptor = NULL;
|
||||||
rhs.m_listen_backlog = 0;
|
rhs.m_listen_backlog = boost::asio::socket_base::max_connections;
|
||||||
rhs.m_state = UNINITIALIZED;
|
rhs.m_state = UNINITIALIZED;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@@ -175,7 +177,9 @@ public:
|
|||||||
|
|
||||||
m_io_service = ptr;
|
m_io_service = ptr;
|
||||||
m_external_io_service = true;
|
m_external_io_service = true;
|
||||||
m_acceptor.reset(new boost::asio::ip::tcp::acceptor(*m_io_service));
|
m_acceptor = lib::make_shared<boost::asio::ip::tcp::acceptor>(
|
||||||
|
lib::ref(*m_io_service));
|
||||||
|
|
||||||
m_state = READY;
|
m_state = READY;
|
||||||
ec = lib::error_code();
|
ec = lib::error_code();
|
||||||
}
|
}
|
||||||
@@ -191,9 +195,7 @@ public:
|
|||||||
void init_asio(io_service_ptr ptr) {
|
void init_asio(io_service_ptr ptr) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
init_asio(ptr,ec);
|
init_asio(ptr,ec);
|
||||||
if (ec) {
|
if (ec) { throw exception(ec); }
|
||||||
throw ec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize asio transport with internal io_service (exception free)
|
/// Initialize asio transport with internal io_service (exception free)
|
||||||
@@ -206,7 +208,7 @@ public:
|
|||||||
* @param ec Set to indicate what error occurred, if any.
|
* @param ec Set to indicate what error occurred, if any.
|
||||||
*/
|
*/
|
||||||
void init_asio(lib::error_code & ec) {
|
void init_asio(lib::error_code & ec) {
|
||||||
init_asio(new boost::asio::io_service(),ec);
|
init_asio(new boost::asio::io_service(), ec);
|
||||||
m_external_io_service = false;
|
m_external_io_service = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +230,7 @@ public:
|
|||||||
* established but before any additional wrappers (proxy connects, TLS
|
* established but before any additional wrappers (proxy connects, TLS
|
||||||
* handshakes, etc) have been performed.
|
* handshakes, etc) have been performed.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*
|
*
|
||||||
* @param h The handler to call on tcp pre init.
|
* @param h The handler to call on tcp pre init.
|
||||||
*/
|
*/
|
||||||
@@ -257,7 +259,7 @@ public:
|
|||||||
* etc have been performed. This is fired before any bytes are read or any
|
* etc have been performed. This is fired before any bytes are read or any
|
||||||
* WebSocket specific handshake logic has been performed.
|
* WebSocket specific handshake logic has been performed.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*
|
*
|
||||||
* @param h The handler to call on tcp post init.
|
* @param h The handler to call on tcp post init.
|
||||||
*/
|
*/
|
||||||
@@ -280,13 +282,31 @@ public:
|
|||||||
* A value of zero will use the operating system default. This is the
|
* A value of zero will use the operating system default. This is the
|
||||||
* default value.
|
* default value.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*
|
*
|
||||||
* @param backlog The maximum length of the queue of pending connections
|
* @param backlog The maximum length of the queue of pending connections
|
||||||
*/
|
*/
|
||||||
void set_listen_backlog(int backlog) {
|
void set_listen_backlog(int backlog) {
|
||||||
m_listen_backlog = 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.
|
||||||
|
*
|
||||||
|
* New values affect future calls to listen only.
|
||||||
|
*
|
||||||
|
* 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
|
/// Retrieve a reference to the endpoint's io_service
|
||||||
/**
|
/**
|
||||||
@@ -323,16 +343,25 @@ public:
|
|||||||
|
|
||||||
m_alog->write(log::alevel::devel,"asio::listen");
|
m_alog->write(log::alevel::devel,"asio::listen");
|
||||||
|
|
||||||
m_acceptor->open(ep.protocol());
|
boost::system::error_code bec;
|
||||||
m_acceptor->set_option(boost::asio::socket_base::reuse_address(true));
|
|
||||||
m_acceptor->bind(ep);
|
m_acceptor->open(ep.protocol(),bec);
|
||||||
if (m_listen_backlog == 0) {
|
if (!bec) {
|
||||||
m_acceptor->listen();
|
m_acceptor->set_option(boost::asio::socket_base::reuse_address(m_reuse_addr),bec);
|
||||||
|
}
|
||||||
|
if (!bec) {
|
||||||
|
m_acceptor->bind(ep,bec);
|
||||||
|
}
|
||||||
|
if (!bec) {
|
||||||
|
m_acceptor->listen(m_listen_backlog,bec);
|
||||||
|
}
|
||||||
|
if (bec) {
|
||||||
|
log_err(log::elevel::info,"asio listen",bec);
|
||||||
|
ec = make_error_code(error::pass_through);
|
||||||
} else {
|
} else {
|
||||||
m_acceptor->listen(m_listen_backlog);
|
m_state = LISTENING;
|
||||||
|
ec = lib::error_code();
|
||||||
}
|
}
|
||||||
m_state = LISTENING;
|
|
||||||
ec = lib::error_code();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up endpoint for listening manually
|
/// Set up endpoint for listening manually
|
||||||
@@ -344,9 +373,7 @@ public:
|
|||||||
void listen(boost::asio::ip::tcp::endpoint const & ep) {
|
void listen(boost::asio::ip::tcp::endpoint const & ep) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
listen(ep,ec);
|
listen(ep,ec);
|
||||||
if (ec) {
|
if (ec) { throw exception(ec); }
|
||||||
throw ec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up endpoint for listening with protocol and port (exception free)
|
/// Set up endpoint for listening with protocol and port (exception free)
|
||||||
@@ -476,9 +503,7 @@ public:
|
|||||||
{
|
{
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
listen(host,service,ec);
|
listen(host,service,ec);
|
||||||
if (ec) {
|
if (ec) { throw exception(ec); }
|
||||||
throw ec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop listening (exception free)
|
/// Stop listening (exception free)
|
||||||
@@ -513,9 +538,15 @@ public:
|
|||||||
void stop_listening() {
|
void stop_listening() {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
stop_listening(ec);
|
stop_listening(ec);
|
||||||
if (ec) {
|
if (ec) { throw exception(ec); }
|
||||||
throw 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
|
/// wraps the run method of the internal io_service object
|
||||||
@@ -566,10 +597,12 @@ public:
|
|||||||
* called either before the endpoint has run out of work or before it was
|
* called either before the endpoint has run out of work or before it was
|
||||||
* started
|
* started
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
void start_perpetual() {
|
void start_perpetual() {
|
||||||
m_work.reset(new boost::asio::io_service::work(*m_io_service));
|
m_work = lib::make_shared<boost::asio::io_service::work>(
|
||||||
|
lib::ref(*m_io_service)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the endpoint's perpetual flag, allowing it to exit when empty
|
/// Clears the endpoint's perpetual flag, allowing it to exit when empty
|
||||||
@@ -578,7 +611,7 @@ public:
|
|||||||
* method to exit normally when it runs out of connections. If there are
|
* method to exit normally when it runs out of connections. If there are
|
||||||
* currently active connections it will not end until they are complete.
|
* currently active connections it will not end until they are complete.
|
||||||
*
|
*
|
||||||
* @since 0.4.0-alpha1
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
void stop_perpetual() {
|
void stop_perpetual() {
|
||||||
m_work.reset();
|
m_work.reset();
|
||||||
@@ -597,11 +630,9 @@ public:
|
|||||||
* needed.
|
* needed.
|
||||||
*/
|
*/
|
||||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||||
timer_ptr new_timer(
|
timer_ptr new_timer = lib::make_shared<boost::asio::deadline_timer>(
|
||||||
new boost::asio::deadline_timer(
|
*m_io_service,
|
||||||
*m_io_service,
|
boost::posix_time::milliseconds(duration)
|
||||||
boost::posix_time::milliseconds(duration)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
new_timer->async_wait(
|
new_timer->async_wait(
|
||||||
@@ -617,7 +648,7 @@ public:
|
|||||||
return new_timer;
|
return new_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Timer callback
|
/// Timer handler
|
||||||
/**
|
/**
|
||||||
* The timer pointer is included to ensure the timer isn't destroyed until
|
* The timer pointer is included to ensure the timer isn't destroyed until
|
||||||
* after it has expired.
|
* after it has expired.
|
||||||
@@ -626,7 +657,7 @@ public:
|
|||||||
* @param callback The function to call back
|
* @param callback The function to call back
|
||||||
* @param ec A status code indicating an error, if any.
|
* @param ec A status code indicating an error, if any.
|
||||||
*/
|
*/
|
||||||
void handle_timer(timer_ptr t, timer_handler callback,
|
void handle_timer(timer_ptr, timer_handler callback,
|
||||||
boost::system::error_code const & ec)
|
boost::system::error_code const & ec)
|
||||||
{
|
{
|
||||||
if (ec) {
|
if (ec) {
|
||||||
@@ -653,10 +684,8 @@ public:
|
|||||||
lib::error_code & ec)
|
lib::error_code & ec)
|
||||||
{
|
{
|
||||||
if (m_state != LISTENING) {
|
if (m_state != LISTENING) {
|
||||||
m_elog->write(log::elevel::library,
|
|
||||||
"asio::async_accept called from the wrong state");
|
|
||||||
using websocketpp::error::make_error_code;
|
using websocketpp::error::make_error_code;
|
||||||
ec = make_error_code(websocketpp::error::invalid_state);
|
ec = make_error_code(websocketpp::error::async_accept_not_listening);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,9 +722,7 @@ public:
|
|||||||
void async_accept(transport_con_ptr tcon, accept_handler callback) {
|
void async_accept(transport_con_ptr tcon, accept_handler callback) {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
async_accept(tcon,callback,ec);
|
async_accept(tcon,callback,ec);
|
||||||
if (ec) {
|
if (ec) { throw exception(ec); }
|
||||||
throw ec;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
/// Initialize logging
|
/// Initialize logging
|
||||||
@@ -721,8 +748,12 @@ protected:
|
|||||||
m_alog->write(log::alevel::devel, "asio::handle_accept");
|
m_alog->write(log::alevel::devel, "asio::handle_accept");
|
||||||
|
|
||||||
if (boost_ec) {
|
if (boost_ec) {
|
||||||
log_err(log::elevel::devel,"asio handle_accept",boost_ec);
|
if (boost_ec == boost::system::errc::operation_canceled) {
|
||||||
ret_ec = make_error_code(error::pass_through);
|
ret_ec = make_error_code(websocketpp::error::operation_canceled);
|
||||||
|
} else {
|
||||||
|
log_err(log::elevel::info,"asio handle_accept",boost_ec);
|
||||||
|
ret_ec = make_error_code(error::pass_through);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(ret_ec);
|
callback(ret_ec);
|
||||||
@@ -735,7 +766,8 @@ protected:
|
|||||||
|
|
||||||
// Create a resolver
|
// Create a resolver
|
||||||
if (!m_resolver) {
|
if (!m_resolver) {
|
||||||
m_resolver.reset(new boost::asio::ip::tcp::resolver(*m_io_service));
|
m_resolver = lib::make_shared<boost::asio::ip::tcp::resolver>(
|
||||||
|
lib::ref(*m_io_service));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string proxy = tcon->get_proxy();
|
std::string proxy = tcon->get_proxy();
|
||||||
@@ -748,7 +780,7 @@ protected:
|
|||||||
} else {
|
} else {
|
||||||
lib::error_code ec;
|
lib::error_code ec;
|
||||||
|
|
||||||
uri_ptr pu(new uri(proxy));
|
uri_ptr pu = lib::make_shared<uri>(proxy);
|
||||||
|
|
||||||
if (!pu->get_valid()) {
|
if (!pu->get_valid()) {
|
||||||
cb(make_error_code(error::proxy_invalid));
|
cb(make_error_code(error::proxy_invalid));
|
||||||
@@ -814,7 +846,16 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_resolve_timeout(timer_ptr dns_timer, connect_handler callback,
|
/// 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 const & ec)
|
||||||
{
|
{
|
||||||
lib::error_code ret_ec;
|
lib::error_code ret_ec;
|
||||||
@@ -913,7 +954,17 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_connect_timeout(transport_con_ptr tcon, timer_ptr con_timer,
|
/// 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)
|
connect_handler callback, lib::error_code const & ec)
|
||||||
{
|
{
|
||||||
lib::error_code ret_ec;
|
lib::error_code ret_ec;
|
||||||
@@ -962,10 +1013,6 @@ protected:
|
|||||||
callback(lib::error_code());
|
callback(lib::error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_listening() const {
|
|
||||||
return (m_state == LISTENING);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize a connection
|
/// Initialize a connection
|
||||||
/**
|
/**
|
||||||
* init is called by an endpoint once for each newly created connection.
|
* init is called by an endpoint once for each newly created connection.
|
||||||
@@ -1022,6 +1069,7 @@ private:
|
|||||||
|
|
||||||
// Network constants
|
// Network constants
|
||||||
int m_listen_backlog;
|
int m_listen_backlog;
|
||||||
|
bool m_reuse_addr;
|
||||||
|
|
||||||
elog_type* m_elog;
|
elog_type* m_elog;
|
||||||
alog_type* m_alog;
|
alog_type* m_alog;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -36,7 +36,6 @@
|
|||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Interface that sockets/security policies must implement
|
// Interface that sockets/security policies must implement
|
||||||
@@ -95,7 +94,10 @@ namespace error {
|
|||||||
pass_through,
|
pass_through,
|
||||||
|
|
||||||
/// Required tls_init handler not present
|
/// Required tls_init handler not present
|
||||||
missing_tls_init_handler
|
missing_tls_init_handler,
|
||||||
|
|
||||||
|
/// TLS Handshake Failed
|
||||||
|
tls_handshake_failed,
|
||||||
};
|
};
|
||||||
} // namespace error
|
} // namespace error
|
||||||
|
|
||||||
@@ -119,9 +121,11 @@ public:
|
|||||||
case error::tls_handshake_timeout:
|
case error::tls_handshake_timeout:
|
||||||
return "TLS handshake timed out";
|
return "TLS handshake timed out";
|
||||||
case error::pass_through:
|
case error::pass_through:
|
||||||
return "Pass through from underlying library";
|
return "Pass through from socket policy";
|
||||||
case error::missing_tls_init_handler:
|
case error::missing_tls_init_handler:
|
||||||
return "Required tls_init handler not present.";
|
return "Required tls_init handler not present.";
|
||||||
|
case error::tls_handshake_failed:
|
||||||
|
return "TLS handshake failed";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -33,14 +33,16 @@
|
|||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace transport {
|
namespace transport {
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
/// A socket policy for the asio transport that implements a plain, unencrypted
|
||||||
|
/// socket
|
||||||
namespace basic_socket {
|
namespace basic_socket {
|
||||||
|
|
||||||
|
/// The signature of the socket init handler for this socket policy
|
||||||
typedef lib::function<void(connection_hdl,boost::asio::ip::tcp::socket&)>
|
typedef lib::function<void(connection_hdl,boost::asio::ip::tcp::socket&)>
|
||||||
socket_init_handler;
|
socket_init_handler;
|
||||||
|
|
||||||
@@ -60,8 +62,10 @@ public:
|
|||||||
typedef boost::asio::io_service* io_service_ptr;
|
typedef boost::asio::io_service* io_service_ptr;
|
||||||
/// Type of a pointer to the ASIO io_service strand being used
|
/// Type of a pointer to the ASIO io_service strand being used
|
||||||
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
||||||
|
/// Type of the ASIO socket being used
|
||||||
|
typedef boost::asio::ip::tcp::socket socket_type;
|
||||||
/// Type of a shared pointer to the socket being used.
|
/// Type of a shared pointer to the socket being used.
|
||||||
typedef lib::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
|
typedef lib::shared_ptr<socket_type> socket_ptr;
|
||||||
|
|
||||||
explicit connection() : m_state(UNINITIALIZED) {
|
explicit connection() : m_state(UNINITIALIZED) {
|
||||||
//std::cout << "transport::asio::basic_socket::connection constructor"
|
//std::cout << "transport::asio::basic_socket::connection constructor"
|
||||||
@@ -154,14 +158,14 @@ protected:
|
|||||||
* @param strand A shared pointer to the connection's asio strand
|
* @param strand A shared pointer to the connection's asio strand
|
||||||
* @param is_server Whether or not the endpoint is a server or not.
|
* @param is_server Whether or not the endpoint is a server or not.
|
||||||
*/
|
*/
|
||||||
lib::error_code init_asio (io_service_ptr service, strand_ptr strand,
|
lib::error_code init_asio (io_service_ptr service, strand_ptr, bool)
|
||||||
bool is_server)
|
|
||||||
{
|
{
|
||||||
if (m_state != UNINITIALIZED) {
|
if (m_state != UNINITIALIZED) {
|
||||||
return socket::make_error_code(socket::error::invalid_state);
|
return socket::make_error_code(socket::error::invalid_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_socket.reset(new boost::asio::ip::tcp::socket(*service));
|
m_socket = lib::make_shared<boost::asio::ip::tcp::socket>(
|
||||||
|
lib::ref(*service));
|
||||||
|
|
||||||
m_state = READY;
|
m_state = READY;
|
||||||
|
|
||||||
@@ -229,6 +233,23 @@ protected:
|
|||||||
lib::error_code get_ec() const {
|
lib::error_code get_ec() const {
|
||||||
return lib::error_code();
|
return lib::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Translate any security policy specific information about an error code
|
||||||
|
/**
|
||||||
|
* Translate_ec takes a boost error code and attempts to convert its value
|
||||||
|
* to an appropriate websocketpp error code. The plain socket policy does
|
||||||
|
* not presently provide any additional information so all 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
|
||||||
|
*/
|
||||||
|
lib::error_code translate_ec(boost::system::error_code) {
|
||||||
|
// We don't know any more information about this error so pass through
|
||||||
|
return make_error_code(transport::error::pass_through);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
enum state {
|
enum state {
|
||||||
UNINITIALIZED = 0,
|
UNINITIALIZED = 0,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -37,16 +37,19 @@
|
|||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace websocketpp {
|
namespace websocketpp {
|
||||||
namespace transport {
|
namespace transport {
|
||||||
namespace asio {
|
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 {
|
namespace tls_socket {
|
||||||
|
|
||||||
|
/// The signature of the socket_init_handler for this socket policy
|
||||||
typedef lib::function<void(connection_hdl,boost::asio::ssl::stream<
|
typedef lib::function<void(connection_hdl,boost::asio::ssl::stream<
|
||||||
boost::asio::ip::tcp::socket>&)> socket_init_handler;
|
boost::asio::ip::tcp::socket>&)> socket_init_handler;
|
||||||
|
/// The signature of the tls_init_handler for this socket policy
|
||||||
typedef lib::function<lib::shared_ptr<boost::asio::ssl::context>(connection_hdl)>
|
typedef lib::function<lib::shared_ptr<boost::asio::ssl::context>(connection_hdl)>
|
||||||
tls_init_handler;
|
tls_init_handler;
|
||||||
|
|
||||||
@@ -190,7 +193,8 @@ protected:
|
|||||||
if (!m_context) {
|
if (!m_context) {
|
||||||
return socket::make_error_code(socket::error::invalid_tls_context);
|
return socket::make_error_code(socket::error::invalid_tls_context);
|
||||||
}
|
}
|
||||||
m_socket.reset(new socket_type(*service,*m_context));
|
m_socket = lib::make_shared<socket_type>(
|
||||||
|
_WEBSOCKETPP_REF(*service),lib::ref(*m_context));
|
||||||
|
|
||||||
m_io_service = service;
|
m_io_service = service;
|
||||||
m_strand = strand;
|
m_strand = strand;
|
||||||
@@ -260,11 +264,10 @@ protected:
|
|||||||
m_hdl = hdl;
|
m_hdl = hdl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_init(init_handler callback, const
|
void handle_init(init_handler callback,boost::system::error_code const & ec)
|
||||||
boost::system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
if (ec) {
|
if (ec) {
|
||||||
m_ec = socket::make_error_code(socket::error::pass_through);
|
m_ec = socket::make_error_code(socket::error::tls_handshake_failed);
|
||||||
} else {
|
} else {
|
||||||
m_ec = lib::error_code();
|
m_ec = lib::error_code();
|
||||||
}
|
}
|
||||||
@@ -284,6 +287,37 @@ protected:
|
|||||||
void async_shutdown(socket_shutdown_handler callback) {
|
void async_shutdown(socket_shutdown_handler callback) {
|
||||||
m_socket->async_shutdown(callback);
|
m_socket->async_shutdown(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Translate any security policy specific information about an error code
|
||||||
|
/**
|
||||||
|
* Translate_ec takes a boost error code and attempts to convert its value
|
||||||
|
* to an appropriate websocketpp error code. 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 pass_through
|
||||||
|
* error.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*
|
||||||
|
* @param ec The error code to translate_ec
|
||||||
|
* @return The translated error code
|
||||||
|
*/
|
||||||
|
lib::error_code translate_ec(boost::system::error_code ec) {
|
||||||
|
if (ec.category() == boost::asio::error::get_ssl_category()) {
|
||||||
|
if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) {
|
||||||
|
return make_error_code(transport::error::tls_short_read);
|
||||||
|
} else {
|
||||||
|
// We know it is a TLS related error, but otherwise don't know
|
||||||
|
// more. Pass through as TLS generic.
|
||||||
|
return make_error_code(transport::error::tls_error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We don't know any more information about this error so pass
|
||||||
|
// through
|
||||||
|
return make_error_code(transport::error::pass_through);
|
||||||
|
}
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
socket_type::handshake_type get_handshake_type() {
|
socket_type::handshake_type get_handshake_type() {
|
||||||
if (m_is_server) {
|
if (m_is_server) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -141,6 +141,7 @@ struct buffer {
|
|||||||
size_t len;
|
size_t len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Generic transport related errors
|
||||||
namespace error {
|
namespace error {
|
||||||
enum value {
|
enum value {
|
||||||
/// Catch-all error for transport policy errors that don't fit in other
|
/// Catch-all error for transport policy errors that don't fit in other
|
||||||
@@ -170,9 +171,12 @@ enum value {
|
|||||||
|
|
||||||
/// Timer expired
|
/// Timer expired
|
||||||
timeout,
|
timeout,
|
||||||
|
|
||||||
/// read or write after shutdown
|
/// read or write after shutdown
|
||||||
action_after_shutdown
|
action_after_shutdown,
|
||||||
|
|
||||||
|
/// Other TLS error
|
||||||
|
tls_error,
|
||||||
};
|
};
|
||||||
|
|
||||||
class category : public lib::error_category {
|
class category : public lib::error_category {
|
||||||
@@ -197,12 +201,14 @@ class category : public lib::error_category {
|
|||||||
return "The operation is not supported by this transport";
|
return "The operation is not supported by this transport";
|
||||||
case eof:
|
case eof:
|
||||||
return "End of File";
|
return "End of File";
|
||||||
case tls_short_read:
|
case tls_short_read:
|
||||||
return "TLS Short Read";
|
return "TLS Short Read";
|
||||||
case timeout:
|
case timeout:
|
||||||
return "Timer Expired";
|
return "Timer Expired";
|
||||||
case action_after_shutdown:
|
case action_after_shutdown:
|
||||||
return "A transport action was requested after shutdown";
|
return "A transport action was requested after shutdown";
|
||||||
|
case tls_error:
|
||||||
|
return "Generic TLS related error";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -28,8 +28,9 @@
|
|||||||
#ifndef WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP
|
#ifndef WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP
|
||||||
#define WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP
|
#define WEBSOCKETPP_TRANSPORT_IOSTREAM_CON_HPP
|
||||||
|
|
||||||
#include <websocketpp/common/memory.hpp>
|
|
||||||
#include <websocketpp/common/connection_hdl.hpp>
|
#include <websocketpp/common/connection_hdl.hpp>
|
||||||
|
#include <websocketpp/common/memory.hpp>
|
||||||
|
#include <websocketpp/common/platforms.hpp>
|
||||||
#include <websocketpp/logger/levels.hpp>
|
#include <websocketpp/logger/levels.hpp>
|
||||||
|
|
||||||
#include <websocketpp/transport/base/connection.hpp>
|
#include <websocketpp/transport/base/connection.hpp>
|
||||||
@@ -127,14 +128,13 @@ public:
|
|||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Manual input supply
|
/// Manual input supply (read some)
|
||||||
/**
|
/**
|
||||||
* Copies bytes from buf into WebSocket++'s input buffers. Bytes will be
|
* Copies bytes from buf into WebSocket++'s input buffers. Bytes will be
|
||||||
* copied from the supplied buffer to fulfill any pending library reads. It
|
* copied from the supplied buffer to fulfill any pending library reads. It
|
||||||
* will return the number of bytes successfully processed. If there are no
|
* 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
|
* pending reads read_some will return immediately. Not all of the bytes may
|
||||||
* be able to be read in one call
|
* be able to be read in one call.
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @since 0.3.0-alpha4
|
* @since 0.3.0-alpha4
|
||||||
*
|
*
|
||||||
@@ -148,6 +148,37 @@ public:
|
|||||||
|
|
||||||
return this->read_some_impl(buf,len);
|
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)
|
/// Manual input supply (DEPRECATED)
|
||||||
/**
|
/**
|
||||||
@@ -273,7 +304,7 @@ public:
|
|||||||
* @return A handle that can be used to cancel the timer if it is no longer
|
* @return A handle that can be used to cancel the timer if it is no longer
|
||||||
* needed.
|
* needed.
|
||||||
*/
|
*/
|
||||||
timer_ptr set_timer(long duration, timer_handler handler) {
|
timer_ptr set_timer(long, timer_handler) {
|
||||||
return timer_ptr();
|
return timer_ptr();
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
@@ -479,7 +510,7 @@ private:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bytes_to_copy = std::min(len,m_len-m_cursor);
|
size_t bytes_to_copy = (std::min)(len,m_len-m_cursor);
|
||||||
|
|
||||||
std::copy(buf,buf+bytes_to_copy,m_buf+m_cursor);
|
std::copy(buf,buf+bytes_to_copy,m_buf+m_cursor);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -140,7 +140,7 @@ protected:
|
|||||||
* @param u A URI pointer to the URI to connect to.
|
* @param u A URI pointer to the URI to connect to.
|
||||||
* @param cb The function to call back with the results when complete.
|
* @param cb The function to call back with the results when complete.
|
||||||
*/
|
*/
|
||||||
void async_connect(transport_con_ptr tcon, uri_ptr u, connect_handler cb) {
|
void async_connect(transport_con_ptr, uri_ptr, connect_handler cb) {
|
||||||
cb(lib::error_code());
|
cb(lib::error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* 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 <websocketpp/common/system_error.hpp>
|
||||||
|
#include <websocketpp/common/cpp11.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace 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 implimented
|
||||||
|
not_implimented
|
||||||
|
};
|
||||||
|
|
||||||
|
/// iostream 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_implimented:
|
||||||
|
return "feature not implimented";
|
||||||
|
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<int>(e), get_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace error
|
||||||
|
} // namespace stub
|
||||||
|
} // namespace transport
|
||||||
|
} // namespace websocketpp
|
||||||
|
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
|
||||||
|
template<> struct is_error_code_enum<websocketpp::transport::stub::error::value>
|
||||||
|
{
|
||||||
|
static bool const value = true;
|
||||||
|
};
|
||||||
|
_WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
|
||||||
|
|
||||||
|
#endif // WEBSOCKETPP_TRANSPORT_STUB_BASE_HPP
|
||||||
@@ -0,0 +1,264 @@
|
|||||||
|
/*
|
||||||
|
* 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 <websocketpp/common/connection_hdl.hpp>
|
||||||
|
#include <websocketpp/common/memory.hpp>
|
||||||
|
#include <websocketpp/common/platforms.hpp>
|
||||||
|
#include <websocketpp/logger/levels.hpp>
|
||||||
|
|
||||||
|
#include <websocketpp/transport/base/connection.hpp>
|
||||||
|
#include <websocketpp/transport/stub/base.hpp>
|
||||||
|
|
||||||
|
namespace 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 <typename config>
|
||||||
|
class connection : public lib::enable_shared_from_this< connection<config> > {
|
||||||
|
public:
|
||||||
|
/// Type of this connection transport component
|
||||||
|
typedef connection<config> type;
|
||||||
|
/// Type of a shared pointer to this connection transport component
|
||||||
|
typedef lib::shared_ptr<type> 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> timer_ptr;
|
||||||
|
|
||||||
|
explicit connection(bool is_server, alog_type & alog, elog_type & 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 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_implimented));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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_implimented));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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_implimented));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<buffer> const & bufs, write_handler handler) {
|
||||||
|
m_alog.write(log::alevel::devel,"stub_con async_write buffer list");
|
||||||
|
handler(make_error_code(error::not_implimented));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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!
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace stub
|
||||||
|
} // namespace transport
|
||||||
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
#endif // WEBSOCKETPP_TRANSPORT_STUB_CON_HPP
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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 <websocketpp/common/memory.hpp>
|
||||||
|
#include <websocketpp/logger/levels.hpp>
|
||||||
|
|
||||||
|
#include <websocketpp/transport/base/endpoint.hpp>
|
||||||
|
#include <websocketpp/transport/stub/connection.hpp>
|
||||||
|
|
||||||
|
namespace websocketpp {
|
||||||
|
namespace transport {
|
||||||
|
namespace stub {
|
||||||
|
|
||||||
|
template <typename config>
|
||||||
|
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<type> 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<config> 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_implimented));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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) {
|
||||||
|
cb(make_error_code(error::not_implimented));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace stub
|
||||||
|
} // namespace transport
|
||||||
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
#endif // WEBSOCKETPP_TRANSPORT_STUB_HPP
|
||||||
+13
-13
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -47,13 +47,13 @@ static uint16_t const uri_default_secure_port = 443;
|
|||||||
|
|
||||||
class uri {
|
class uri {
|
||||||
public:
|
public:
|
||||||
explicit uri(std::string const & uri) : m_valid(false) {
|
explicit uri(std::string const & uri_string) : m_valid(false) {
|
||||||
std::string::const_iterator it;
|
std::string::const_iterator it;
|
||||||
std::string::const_iterator temp;
|
std::string::const_iterator temp;
|
||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
it = uri.begin();
|
it = uri_string.begin();
|
||||||
|
|
||||||
if (std::equal(it,it+6,"wss://")) {
|
if (std::equal(it,it+6,"wss://")) {
|
||||||
m_secure = true;
|
m_secure = true;
|
||||||
@@ -88,14 +88,14 @@ public:
|
|||||||
//temp = std::find(it,it2,']');
|
//temp = std::find(it,it2,']');
|
||||||
|
|
||||||
temp = it;
|
temp = it;
|
||||||
while (temp != uri.end()) {
|
while (temp != uri_string.end()) {
|
||||||
if (*temp == ']') {
|
if (*temp == ']') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++temp;
|
++temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp == uri.end()) {
|
if (temp == uri_string.end()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// validate IPv6 literal parts
|
// validate IPv6 literal parts
|
||||||
@@ -103,7 +103,7 @@ public:
|
|||||||
m_host.append(it,temp);
|
m_host.append(it,temp);
|
||||||
}
|
}
|
||||||
it = temp+1;
|
it = temp+1;
|
||||||
if (it == uri.end()) {
|
if (it == uri_string.end()) {
|
||||||
state = 2;
|
state = 2;
|
||||||
} else if (*it == '/') {
|
} else if (*it == '/') {
|
||||||
state = 2;
|
state = 2;
|
||||||
@@ -119,7 +119,7 @@ public:
|
|||||||
// IPv4 or hostname
|
// IPv4 or hostname
|
||||||
// extract until : or /
|
// extract until : or /
|
||||||
while (state == 0) {
|
while (state == 0) {
|
||||||
if (it == uri.end()) {
|
if (it == uri_string.end()) {
|
||||||
state = 2;
|
state = 2;
|
||||||
break;
|
break;
|
||||||
} else if (*it == '/') {
|
} else if (*it == '/') {
|
||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
// parse port
|
// parse port
|
||||||
std::string port = "";
|
std::string port = "";
|
||||||
while (state == 1) {
|
while (state == 1) {
|
||||||
if (it == uri.end()) {
|
if (it == uri_string.end()) {
|
||||||
// state is not used after this point presently.
|
// state is not used after this point presently.
|
||||||
// this should be re-enabled if it ever is needed in a future
|
// this should be re-enabled if it ever is needed in a future
|
||||||
// refactoring
|
// refactoring
|
||||||
@@ -159,7 +159,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_resource = "/";
|
m_resource = "/";
|
||||||
m_resource.append(it,uri.end());
|
m_resource.append(it,uri_string.end());
|
||||||
|
|
||||||
|
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
@@ -290,10 +290,10 @@ public:
|
|||||||
* @return query portion of the URI.
|
* @return query portion of the URI.
|
||||||
*/
|
*/
|
||||||
std::string get_query() const {
|
std::string get_query() const {
|
||||||
std::size_t found = m_resource.find('?');
|
std::size_t found = m_resource.find('?');
|
||||||
if (found != std::string::npos) {
|
if (found != std::string::npos) {
|
||||||
return m_resource.substr(found + 1);
|
return m_resource.substr(found + 1);
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -78,7 +78,7 @@ struct ci_less : std::binary_function<std::string, std::string, bool> {
|
|||||||
: public std::binary_function<unsigned char,unsigned char,bool>
|
: public std::binary_function<unsigned char,unsigned char,bool>
|
||||||
{
|
{
|
||||||
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
|
bool operator() (unsigned char const & c1, unsigned char const & c2) const {
|
||||||
return std::tolower (c1) < std::tolower (c2);
|
return tolower (c1) < tolower (c2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
bool operator() (std::string const & s1, std::string const & s2) const {
|
bool operator() (std::string const & s1, std::string const & s2) const {
|
||||||
|
|||||||
+4
-4
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Peter Thorson. All rights reserved.
|
* Copyright (c) 2014, Peter Thorson. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
@@ -42,7 +42,7 @@ namespace websocketpp {
|
|||||||
/// Library major version number
|
/// Library major version number
|
||||||
static int const major_version = 0;
|
static int const major_version = 0;
|
||||||
/// Library minor version number
|
/// Library minor version number
|
||||||
static int const minor_version = 3;
|
static int const minor_version = 4;
|
||||||
/// Library patch version number
|
/// Library patch version number
|
||||||
static int const patch_version = 0;
|
static int const patch_version = 0;
|
||||||
/// Library pre-release flag
|
/// Library pre-release flag
|
||||||
@@ -50,10 +50,10 @@ static int const patch_version = 0;
|
|||||||
* This is a textual flag indicating the type and number for pre-release
|
* This is a textual flag indicating the type and number for pre-release
|
||||||
* versions (dev, alpha, beta, rc). This will be blank for release versions.
|
* versions (dev, alpha, beta, rc). This will be blank for release versions.
|
||||||
*/
|
*/
|
||||||
static char const prerelease_flag[] = "alpha4";
|
static char const prerelease_flag[] = "";
|
||||||
|
|
||||||
/// Default user agent string
|
/// Default user agent string
|
||||||
static char const user_agent[] = "WebSocket++/0.3.0-alpha4";
|
static char const user_agent[] = "WebSocket++/0.4.0";
|
||||||
|
|
||||||
} // namespace websocketpp
|
} // namespace websocketpp
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user