Updating websocketpp to latest git.
This commit is contained in:
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
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
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
+35
-13
@@ -45,6 +45,11 @@ static std::string const base64_chars =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
/// Test whether a character is a valid base64 character
|
||||
/**
|
||||
* @param c The character to test
|
||||
* @return true if c is a valid base64 character
|
||||
*/
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (c == 43 || // +
|
||||
(c >= 47 && c <= 57) || // /-9
|
||||
@@ -52,17 +57,21 @@ static inline bool is_base64(unsigned char c) {
|
||||
(c >= 97 && c <= 122)); // a-z
|
||||
}
|
||||
|
||||
inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
||||
int in_len)
|
||||
{
|
||||
/// Encode a char buffer into a base64 string
|
||||
/**
|
||||
* @param input The input data
|
||||
* @param len The length of input in bytes
|
||||
* @return A base64 encoded string representing input
|
||||
*/
|
||||
inline std::string base64_encode(unsigned char const * input, size_t len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
while (len--) {
|
||||
char_array_3[i++] = *(input++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
|
||||
@@ -97,25 +106,38 @@ inline std::string base64_encode(unsigned char const * bytes_to_encode, unsigned
|
||||
while((i++ < 3)) {
|
||||
ret += '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline std::string base64_encode(std::string const & data) {
|
||||
return base64_encode(reinterpret_cast<const unsigned char *>(data.data()),data.size());
|
||||
/// Encode a string into a base64 string
|
||||
/**
|
||||
* @param input The input data
|
||||
* @return A base64 encoded string representing input
|
||||
*/
|
||||
inline std::string base64_encode(std::string const & input) {
|
||||
return base64_encode(
|
||||
reinterpret_cast<const unsigned char *>(input.data()),
|
||||
input.size()
|
||||
);
|
||||
}
|
||||
|
||||
inline std::string base64_decode(std::string const & encoded_string) {
|
||||
size_t in_len = encoded_string.size();
|
||||
/// Decode a base64 encoded string into a string of raw bytes
|
||||
/**
|
||||
* @param input The base64 encoded input data
|
||||
* @return A string representing the decoded raw bytes
|
||||
*/
|
||||
inline std::string base64_decode(std::string const & input) {
|
||||
size_t in_len = input.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
|
||||
char_array_4[i++] = input[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++) {
|
||||
char_array_4[i] = static_cast<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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -199,6 +199,46 @@ namespace status {
|
||||
code == policy_violation || code == message_too_big ||
|
||||
code == internal_endpoint_error);
|
||||
}
|
||||
|
||||
/// Return a human readable interpretation of a WebSocket close code
|
||||
/**
|
||||
* See https://tools.ietf.org/html/rfc6455#section-7.4 for more details.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param [in] code The code to look up.
|
||||
* @return A human readable interpretation of the code.
|
||||
*/
|
||||
inline std::string get_string(value code) {
|
||||
switch (code) {
|
||||
case normal:
|
||||
return "Normal close";
|
||||
case going_away:
|
||||
return "Going away";
|
||||
case protocol_error:
|
||||
return "Protocol error";
|
||||
case unsupported_data:
|
||||
return "Unsupported data";
|
||||
case no_status:
|
||||
return "No status set";
|
||||
case abnormal_close:
|
||||
return "Abnormal close";
|
||||
case invalid_payload:
|
||||
return "Invalid payload";
|
||||
case policy_violation:
|
||||
return "Policy violoation";
|
||||
case message_too_big:
|
||||
return "Message too big";
|
||||
case extension_required:
|
||||
return "Extension required";
|
||||
case internal_endpoint_error:
|
||||
return "Internal endpoint error";
|
||||
case tls_handshake:
|
||||
return "TLS handshake failure";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
} // namespace status
|
||||
|
||||
/// 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -34,7 +34,7 @@ namespace websocketpp {
|
||||
|
||||
/// 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
|
||||
* 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
|
||||
* 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.
|
||||
#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_
|
||||
// This flag indicates that all of the C++11 language features are available
|
||||
// to us.
|
||||
#if defined(_WEBSOCKETPP_CPP11_STL_) || __cplusplus >= 201103L || defined(_WEBSOCKETPP_CPP11_STRICT_)
|
||||
// This check tests for blanket c++11 coverage. It can be activated in one
|
||||
// of three ways. Either the compiler itself reports that it is a full
|
||||
// C++11 compiler via the __cplusplus macro or the user/build system
|
||||
// supplies one of the two preprocessor defines below:
|
||||
|
||||
// _WEBSOCKETPP_CPP11_STRICT_
|
||||
//
|
||||
// This define reports to WebSocket++ that 100% of the language and library
|
||||
// features of C++11 are available. Using this define on a non-C++11
|
||||
// compiler will result in problems.
|
||||
|
||||
// _WEBSOCKETPP_CPP11_STL_
|
||||
//
|
||||
// This define enables *most* C++11 options that were implemented early on
|
||||
// by compilers. It is typically used for compilers that have many, but not
|
||||
// all C++11 features. It should be safe to use on GCC 4.7-4.8 and perhaps
|
||||
// earlier.
|
||||
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ noexcept
|
||||
#endif
|
||||
@@ -53,7 +72,19 @@
|
||||
#ifndef _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#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
|
||||
// In the absence of a blanket define, try to use compiler versions or
|
||||
// feature testing macros to selectively enable what we can.
|
||||
|
||||
// Test for noexcept
|
||||
#ifndef _WEBSOCKETPP_NOEXCEPT_TOKEN_
|
||||
#ifdef _WEBSOCKETPP_NOEXCEPT_
|
||||
@@ -90,6 +121,25 @@
|
||||
#if __has_feature(cxx_generalized_initializers) && !defined(_WEBSOCKETPP_INITIALIZER_LISTS_)
|
||||
#define _WEBSOCKETPP_INITIALIZER_LISTS_
|
||||
#endif
|
||||
|
||||
// Test for nullptr
|
||||
#ifndef _WEBSOCKETPP_NULLPTR_TOKEN_
|
||||
#ifdef _WEBSOCKETPP_NULLPTR_
|
||||
// build system says we have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#else
|
||||
#if __has_feature(cxx_nullptr)
|
||||
// clang feature detect says we have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#elif _MSC_VER >= 1600
|
||||
// Visual Studio version that has nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ nullptr
|
||||
#else
|
||||
// assume we don't have nullptr
|
||||
#define _WEBSOCKETPP_NULLPTR_TOKEN_ 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_CPP11_HPP
|
||||
|
||||
@@ -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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -39,8 +39,11 @@
|
||||
#else
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace websocketpp {
|
||||
namespace lib {
|
||||
|
||||
@@ -49,6 +52,18 @@ namespace lib {
|
||||
using std::bind;
|
||||
using std::ref;
|
||||
namespace placeholders = std::placeholders;
|
||||
|
||||
// There are some cases where a C++11 compiler balks at using std::ref
|
||||
// but a C++03 compiler using boost function requires boost::ref. As such
|
||||
// lib::ref is not useful in these cases. Instead this macro allows the use
|
||||
// of boost::ref in the case of a boost compile or no reference wrapper at
|
||||
// all in the case of a C++11 compile
|
||||
#define _WEBSOCKETPP_REF(x) x
|
||||
|
||||
template <typename T>
|
||||
void clear_function(T & x) {
|
||||
x = nullptr;
|
||||
}
|
||||
#else
|
||||
using boost::function;
|
||||
using boost::bind;
|
||||
@@ -58,6 +73,14 @@ namespace lib {
|
||||
using ::_1;
|
||||
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
|
||||
|
||||
} // namespace lib
|
||||
|
||||
+70
-70
@@ -34,7 +34,7 @@
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
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
|
||||
(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
|
||||
@@ -45,12 +45,12 @@
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
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. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
@@ -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. */
|
||||
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
|
||||
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#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]*/) {
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if ZSW_MD5_BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
@@ -183,51 +183,51 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
|
||||
{
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static int const w = 1;
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static int const w = 1;
|
||||
|
||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (md5_word_t const *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
std::memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (md5_word_t const *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
std::memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if ZSW_MD5_BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#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);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
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);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
std::memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
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]) {
|
||||
static md5_byte_t const pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
|
||||
// some convenience c++ functions
|
||||
inline std::string md5_hash_string(std::string const & s) {
|
||||
char digest[16];
|
||||
char digest[16];
|
||||
|
||||
md5_state_t state;
|
||||
md5_state_t state;
|
||||
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
|
||||
std::string ret;
|
||||
ret.resize(16);
|
||||
std::copy(digest,digest+16,ret.begin());
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <memory>
|
||||
#else
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/pointer_cast.hpp>
|
||||
@@ -51,6 +52,7 @@ namespace lib {
|
||||
using std::weak_ptr;
|
||||
using std::enable_shared_from_this;
|
||||
using std::static_pointer_cast;
|
||||
using std::make_shared;
|
||||
|
||||
typedef std::unique_ptr<unsigned char[]> unique_ptr_uchar_array;
|
||||
#else
|
||||
@@ -58,6 +60,7 @@ namespace lib {
|
||||
using boost::weak_ptr;
|
||||
using boost::enable_shared_from_this;
|
||||
using boost::static_pointer_cast;
|
||||
using boost::make_shared;
|
||||
|
||||
typedef boost::scoped_array<unsigned char> unique_ptr_uchar_array;
|
||||
#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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,7 +29,7 @@
|
||||
#define WEBSOCKETPP_COMMON_NETWORK_HPP
|
||||
|
||||
// For ntohs and htons
|
||||
#if defined(WIN32)
|
||||
#if defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
//#include <arpa/inet.h>
|
||||
@@ -50,7 +50,18 @@ inline bool is_little_endian() {
|
||||
#define TYP_SMLE 1
|
||||
#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;
|
||||
unsigned char c;
|
||||
union {
|
||||
@@ -71,8 +82,19 @@ inline uint64_t htonll(uint64_t src) {
|
||||
return x.ull;
|
||||
}
|
||||
|
||||
inline uint64_t ntohll(uint64_t src) {
|
||||
return htonll(src);
|
||||
/// Convert 64 bit value to host byte order
|
||||
/**
|
||||
* This method is prefixed to avoid conflicts with operating system level
|
||||
* macros for this functionality.
|
||||
*
|
||||
* TODO: figure out if it would be beneficial to use operating system level
|
||||
* macros for this.
|
||||
*
|
||||
* @param src The integer in network byte order
|
||||
* @return src converted to host byte order
|
||||
*/
|
||||
inline uint64_t _ntohll(uint64_t src) {
|
||||
return _htonll(src);
|
||||
}
|
||||
|
||||
} // net
|
||||
|
||||
@@ -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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -33,7 +33,7 @@
|
||||
* 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
|
||||
#define NOMINMAX
|
||||
#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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -32,7 +32,7 @@
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#if WIN32 && (_MSC_VER < 1600)
|
||||
#if defined (_WIN32) && defined (_MSC_VER) && (_MSC_VER < 1600)
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,26 +29,48 @@
|
||||
#define WEBSOCKETPP_CONCURRENCY_NONE_HPP
|
||||
|
||||
namespace websocketpp {
|
||||
|
||||
/// Concurrency handling support
|
||||
namespace concurrency {
|
||||
|
||||
/// Implementation for no-op locking primitives
|
||||
namespace none_impl {
|
||||
/// A fake mutex implementation that does nothing
|
||||
class fake_mutex {
|
||||
public:
|
||||
fake_mutex() {}
|
||||
~fake_mutex() {}
|
||||
};
|
||||
|
||||
/// A fake lock guard implementation that does nothing
|
||||
class fake_lock_guard {
|
||||
public:
|
||||
explicit fake_lock_guard(fake_mutex foo) {}
|
||||
explicit fake_lock_guard(fake_mutex) {}
|
||||
~fake_lock_guard() {}
|
||||
};
|
||||
} // 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 {
|
||||
public:
|
||||
/// The type of a mutex primitive
|
||||
/**
|
||||
* std::mutex is an example.
|
||||
*/
|
||||
typedef none_impl::fake_mutex mutex_type;
|
||||
|
||||
/// The type of a scoped/RAII lock primitive.
|
||||
/**
|
||||
* The scoped lock constructor should take a mutex_type as a parameter,
|
||||
* acquire that lock, and release it in its destructor. std::lock_guard is
|
||||
* an example.
|
||||
*/
|
||||
typedef none_impl::fake_lock_guard scoped_lock_type;
|
||||
};
|
||||
|
||||
|
||||
+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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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 will correctly configure most target platforms simply by including this header before
|
||||
// any other WebSocket++ header.
|
||||
// This header defines WebSocket++ macros for C++11 compatibility based on the
|
||||
// Boost.Config library. This will correctly configure most target platforms
|
||||
// simply by including this header before any other WebSocket++ header.
|
||||
|
||||
#ifndef WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||
#define WEBSOCKETPP_CONFIG_BOOST_CONFIG_HPP
|
||||
@@ -41,7 +41,7 @@
|
||||
#define _WEBSOCKETPP_CPP11_FUNCTIONAL_
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ASIO_HAS_STD_CHRONO
|
||||
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
||||
#define _WEBSOCKETPP_CPP11_CHRONO_
|
||||
#endif
|
||||
|
||||
@@ -67,5 +67,6 @@
|
||||
|
||||
#define _WEBSOCKETPP_NOEXCEPT_TOKEN_ BOOST_NOEXCEPT
|
||||
#define _WEBSOCKETPP_CONSTEXPR_TOKEN_ BOOST_CONSTEXPR
|
||||
// TODO: nullptr support
|
||||
|
||||
#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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -215,6 +215,18 @@ struct core {
|
||||
*/
|
||||
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
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -34,7 +34,11 @@
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
|
||||
// Concurrency
|
||||
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||
#include <websocketpp/concurrency/basic.hpp>
|
||||
#else
|
||||
#include <websocketpp/concurrency/none.hpp>
|
||||
#endif
|
||||
|
||||
// Transport
|
||||
#include <websocketpp/transport/iostream/endpoint.hpp>
|
||||
@@ -68,7 +72,11 @@ struct core_client {
|
||||
typedef core_client type;
|
||||
|
||||
// Concurrency policy
|
||||
#ifndef _WEBSOCKETPP_NO_THREADING_
|
||||
typedef websocketpp::concurrency::basic concurrency_type;
|
||||
#else
|
||||
typedef websocketpp::concurrency::none concurrency_type;
|
||||
#endif
|
||||
|
||||
// HTTP Parser Policies
|
||||
typedef http::parser::request request_type;
|
||||
@@ -216,6 +224,18 @@ struct core_client {
|
||||
*/
|
||||
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
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -216,6 +216,18 @@ struct debug_core {
|
||||
*/
|
||||
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
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -279,9 +280,9 @@ private:
|
||||
};
|
||||
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)
|
||||
: transport_con_type(is_server,alog,elog)
|
||||
: transport_con_type(p_is_server, alog, elog)
|
||||
, m_handle_read_frame(lib::bind(
|
||||
&type::handle_read_frame,
|
||||
this,
|
||||
@@ -297,12 +298,14 @@ public:
|
||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||
, m_pong_timeout_dur(config::timeout_pong)
|
||||
, m_max_message_size(config::max_message_size)
|
||||
, m_state(session::state::connecting)
|
||||
, m_internal_state(session::internal_state::USER_INIT)
|
||||
, m_msg_manager(new con_msg_manager_type())
|
||||
, m_send_buffer_size(0)
|
||||
, m_write_flag(false)
|
||||
, m_is_server(is_server)
|
||||
, m_read_flag(true)
|
||||
, m_is_server(p_is_server)
|
||||
, m_alog(alog)
|
||||
, m_elog(elog)
|
||||
, m_rng(rng)
|
||||
@@ -455,9 +458,9 @@ public:
|
||||
m_message_handler = h;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Connection timeouts //
|
||||
/////////////////////////
|
||||
//////////////////////////////////////////
|
||||
// Connection timeouts and other limits //
|
||||
//////////////////////////////////////////
|
||||
|
||||
/// Set open handshake timeout
|
||||
/**
|
||||
@@ -528,6 +531,38 @@ public:
|
||||
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 //
|
||||
//////////////////////////////////
|
||||
@@ -615,9 +650,46 @@ public:
|
||||
* @return An error code
|
||||
*/
|
||||
lib::error_code interrupt();
|
||||
|
||||
|
||||
/// Transport inturrupt callback
|
||||
void handle_interrupt();
|
||||
|
||||
/// Pause reading of new data
|
||||
/**
|
||||
* Signals to the connection to halt reading of new data. While reading is paused,
|
||||
* the connection will stop reading from its associated socket. In turn this will
|
||||
* result in TCP based flow control kicking in and slowing data flow from the remote
|
||||
* endpoint.
|
||||
*
|
||||
* This is useful for applications that push new requests to a queue to be processed
|
||||
* by another thread and need a way to signal when their request queue is full without
|
||||
* blocking the network processing thread.
|
||||
*
|
||||
* Use `resume_reading()` to resume.
|
||||
*
|
||||
* If supported by the transport this is done asynchronously. As such reading may not
|
||||
* stop until the current read operation completes. Typically you can expect to
|
||||
* receive no more bytes after initiating a read pause than the size of the read
|
||||
* buffer.
|
||||
*
|
||||
* If reading is paused for this connection already nothing is changed.
|
||||
*/
|
||||
lib::error_code pause_reading();
|
||||
|
||||
/// Pause reading callback
|
||||
void handle_pause_reading();
|
||||
|
||||
/// Resume reading of new data
|
||||
/**
|
||||
* Signals to the connection to resume reading of new data after it was paused by
|
||||
* `pause_reading()`.
|
||||
*
|
||||
* If reading is not paused for this connection already nothing is changed.
|
||||
*/
|
||||
lib::error_code resume_reading();
|
||||
|
||||
/// Resume reading callback
|
||||
void handle_resume_reading();
|
||||
|
||||
/// Send a ping
|
||||
/**
|
||||
@@ -1092,8 +1164,8 @@ public:
|
||||
void handle_open_handshake_timeout(lib::error_code const & ec);
|
||||
void handle_close_handshake_timeout(lib::error_code const & ec);
|
||||
|
||||
void handle_read_frame(lib::error_code const & ec,
|
||||
size_t bytes_transferred);
|
||||
void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
|
||||
void read_frame();
|
||||
|
||||
/// Get array of WebSocket protocol versions that this connection supports.
|
||||
const std::vector<int>& get_supported_versions() const;
|
||||
@@ -1281,6 +1353,14 @@ private:
|
||||
*/
|
||||
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
|
||||
read_handler m_handle_read_frame;
|
||||
write_frame_handler m_write_frame_handler;
|
||||
@@ -1307,6 +1387,7 @@ private:
|
||||
long m_open_handshake_timeout_dur;
|
||||
long m_close_handshake_timeout_dur;
|
||||
long m_pong_timeout_dur;
|
||||
size_t m_max_message_size;
|
||||
|
||||
/// External connection state
|
||||
/**
|
||||
@@ -1370,9 +1451,9 @@ private:
|
||||
*/
|
||||
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.
|
||||
message_ptr m_current_msg;
|
||||
std::vector<message_ptr> m_current_msgs;
|
||||
|
||||
/// True if there is currently an outstanding transport write
|
||||
/**
|
||||
@@ -1380,6 +1461,9 @@ private:
|
||||
*/
|
||||
bool m_write_flag;
|
||||
|
||||
/// True if this connection is presently reading new data
|
||||
bool m_read_flag;
|
||||
|
||||
// connection data
|
||||
request_type m_request;
|
||||
response_type m_response;
|
||||
|
||||
@@ -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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
#include <websocketpp/version.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
namespace websocketpp {
|
||||
@@ -87,21 +86,22 @@ public:
|
||||
|
||||
typedef lib::shared_ptr<connection_weak_ptr> hdl_type;
|
||||
|
||||
explicit endpoint(bool is_server)
|
||||
: m_alog(config::alog_level, &std::cout)
|
||||
, m_elog(config::elog_level, &std::cerr)
|
||||
explicit endpoint(bool p_is_server)
|
||||
: m_alog(config::alog_level, log::channel_type_hint::access)
|
||||
, m_elog(config::elog_level, log::channel_type_hint::error)
|
||||
, m_user_agent(::websocketpp::user_agent)
|
||||
, m_open_handshake_timeout_dur(config::timeout_open_handshake)
|
||||
, m_close_handshake_timeout_dur(config::timeout_close_handshake)
|
||||
, m_pong_timeout_dur(config::timeout_pong)
|
||||
, m_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_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
|
||||
@@ -272,9 +272,9 @@ public:
|
||||
m_message_handler = h;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Connection timeouts //
|
||||
/////////////////////////
|
||||
//////////////////////////////////////////
|
||||
// Connection timeouts and other limits //
|
||||
//////////////////////////////////////////
|
||||
|
||||
/// Set open handshake timeout
|
||||
/**
|
||||
@@ -348,6 +348,36 @@ public:
|
||||
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 */
|
||||
/*************************************/
|
||||
@@ -363,6 +393,43 @@ public:
|
||||
void interrupt(connection_hdl hdl, lib::error_code & ec);
|
||||
void interrupt(connection_hdl hdl);
|
||||
|
||||
/// Pause reading of new data (exception free)
|
||||
/**
|
||||
* Signals to the connection to halt reading of new data. While reading is paused,
|
||||
* the connection will stop reading from its associated socket. In turn this will
|
||||
* result in TCP based flow control kicking in and slowing data flow from the remote
|
||||
* endpoint.
|
||||
*
|
||||
* This is useful for applications that push new requests to a queue to be processed
|
||||
* by another thread and need a way to signal when their request queue is full without
|
||||
* blocking the network processing thread.
|
||||
*
|
||||
* Use `resume_reading()` to resume.
|
||||
*
|
||||
* If supported by the transport this is done asynchronously. As such reading may not
|
||||
* stop until the current read operation completes. Typically you can expect to
|
||||
* receive no more bytes after initiating a read pause than the size of the read
|
||||
* buffer.
|
||||
*
|
||||
* If reading is paused for this connection already nothing is changed.
|
||||
*/
|
||||
void pause_reading(connection_hdl hdl, lib::error_code & ec);
|
||||
|
||||
/// Pause reading of new data
|
||||
void pause_reading(connection_hdl hdl);
|
||||
|
||||
/// Resume reading of new data (exception free)
|
||||
/**
|
||||
* Signals to the connection to resume reading of new data after it was paused by
|
||||
* `pause_reading()`.
|
||||
*
|
||||
* If reading is not paused for this connection already nothing is changed.
|
||||
*/
|
||||
void resume_reading(connection_hdl hdl, lib::error_code & ec);
|
||||
|
||||
/// Resume reading of new data
|
||||
void resume_reading(connection_hdl hdl);
|
||||
|
||||
/// 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
|
||||
@@ -470,7 +537,7 @@ public:
|
||||
lib::error_code ec;
|
||||
connection_ptr con = this->get_con_from_hdl(hdl,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
throw exception(ec);
|
||||
}
|
||||
return con;
|
||||
}
|
||||
@@ -497,6 +564,7 @@ private:
|
||||
long m_open_handshake_timeout_dur;
|
||||
long m_close_handshake_timeout_dur;
|
||||
long m_pong_timeout_dur;
|
||||
size_t m_max_message_size;
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
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 {
|
||||
enum value {
|
||||
/// Catch-all library error
|
||||
@@ -86,7 +86,8 @@ enum value {
|
||||
/// 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,
|
||||
|
||||
/// Unit testing utility error code
|
||||
@@ -114,7 +115,14 @@ enum value {
|
||||
close_handshake_timeout,
|
||||
|
||||
/// 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
|
||||
|
||||
|
||||
@@ -176,6 +184,10 @@ public:
|
||||
return "The closing handshake timed out";
|
||||
case error::invalid_port:
|
||||
return "Invalid URI port";
|
||||
case error::async_accept_not_listening:
|
||||
return "Async Accept not listening";
|
||||
case error::operation_canceled:
|
||||
return "Operation canceled";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -205,21 +217,30 @@ namespace websocketpp {
|
||||
|
||||
class exception : public std::exception {
|
||||
public:
|
||||
exception(std::string const & msg,
|
||||
error::value code = error::general)
|
||||
: m_msg(msg),m_code(code) {}
|
||||
exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
|
||||
: m_msg(msg), m_code(ec)
|
||||
{}
|
||||
|
||||
explicit exception(lib::error_code ec)
|
||||
: m_code(ec)
|
||||
{}
|
||||
|
||||
~exception() 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;
|
||||
}
|
||||
|
||||
std::string m_msg;
|
||||
error::value m_code;
|
||||
lib::error_code m_code;
|
||||
};
|
||||
|
||||
} // 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -36,34 +36,34 @@ namespace websocketpp {
|
||||
*/
|
||||
class error_msg {
|
||||
public:
|
||||
const std::string& get_msg() const {
|
||||
return m_error_msg;
|
||||
}
|
||||
const std::string& get_msg() const {
|
||||
return m_error_msg;
|
||||
}
|
||||
|
||||
void set_msg(const std::string& msg) {
|
||||
m_error_msg = msg;
|
||||
}
|
||||
void set_msg(const std::string& msg) {
|
||||
m_error_msg = msg;
|
||||
}
|
||||
|
||||
void append_msg(const std::string& msg) {
|
||||
m_error_msg.append(msg);
|
||||
}
|
||||
void append_msg(const std::string& msg) {
|
||||
m_error_msg.append(msg);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->set_msg(val.str());
|
||||
}
|
||||
template <typename T>
|
||||
void set_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->set_msg(val.str());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void append_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->append_msg(val.str());
|
||||
}
|
||||
template <typename T>
|
||||
void append_msg(const T& thing) {
|
||||
std::stringsteam val;
|
||||
val << thing;
|
||||
this->append_msg(val.str());
|
||||
}
|
||||
private:
|
||||
// error resources
|
||||
std::string m_error_msg;
|
||||
// error resources
|
||||
std::string m_error_msg;
|
||||
};
|
||||
|
||||
} // 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
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -69,17 +77,24 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
lib::error_code decompress(uint8_t const * buf, size_t len,
|
||||
std::string & out)
|
||||
{
|
||||
return make_error_code(error::disabled);
|
||||
}
|
||||
|
||||
lib::error_code decompress(std::string const & in, std::string & out) {
|
||||
/// Decompress bytes
|
||||
/**
|
||||
* @param buf Byte buffer to decompress
|
||||
* @param len Length of buf
|
||||
* @param out String to append decompressed bytes to
|
||||
* @return Error or status code
|
||||
*/
|
||||
lib::error_code decompress(uint8_t const *, size_t, std::string &) {
|
||||
return make_error_code(error::disabled);
|
||||
}
|
||||
};
|
||||
|
||||
+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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -28,8 +28,10 @@
|
||||
#ifndef WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||
#define WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
@@ -48,8 +50,8 @@ namespace extensions {
|
||||
/**
|
||||
* ### permessage-deflate interface
|
||||
*
|
||||
* **is_implimented**\n
|
||||
* `bool is_implimented()`\n
|
||||
* **is_implemented**\n
|
||||
* `bool is_implemented()`\n
|
||||
* Returns whether or not the object impliments the extension or not
|
||||
*
|
||||
* **is_enabled**\n
|
||||
@@ -432,8 +434,8 @@ public:
|
||||
* @param response The server response attribute list to validate
|
||||
* @return Validation error or 0 on success
|
||||
*/
|
||||
lib::error_code validate_offer(http::attribute_list const & response) {
|
||||
|
||||
lib::error_code validate_offer(http::attribute_list const &) {
|
||||
return make_error_code(error::general);
|
||||
}
|
||||
|
||||
/// Negotiate extension
|
||||
@@ -487,7 +489,6 @@ public:
|
||||
}
|
||||
|
||||
size_t output;
|
||||
int ret;
|
||||
|
||||
m_dstate.avail_out = m_compress_buffer_size;
|
||||
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.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;
|
||||
|
||||
@@ -642,7 +643,7 @@ private:
|
||||
m_s2c_max_window_bits = bits;
|
||||
break;
|
||||
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;
|
||||
case mode::smallest:
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -266,7 +266,7 @@ private:
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return 8-payload_offset;
|
||||
@@ -456,35 +456,6 @@ inline size_t get_header_len(basic_header const & h) {
|
||||
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
|
||||
@@ -583,7 +554,7 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
uint64_converter temp64;
|
||||
std::copy(e.bytes,e.bytes+8,temp64.c);
|
||||
return lib::net::ntohll(temp64.i);
|
||||
return lib::net::_ntohll(temp64.i);
|
||||
}
|
||||
|
||||
/// 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace websocketpp {
|
||||
/// HTTP handling support
|
||||
namespace http {
|
||||
/// The type of an HTTP attribute list
|
||||
/**
|
||||
@@ -255,7 +256,7 @@ namespace http {
|
||||
case internal_server_error:
|
||||
return "Internal Server Error";
|
||||
case not_implemented:
|
||||
return "Not Implimented";
|
||||
return "Not Implemented";
|
||||
case bad_gateway:
|
||||
return "Bad Gateway";
|
||||
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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -38,15 +38,15 @@ namespace http {
|
||||
namespace parser {
|
||||
|
||||
inline bool request::parse_complete(std::istream& s) {
|
||||
std::string request;
|
||||
std::string req;
|
||||
|
||||
// get status line
|
||||
std::getline(s, request);
|
||||
std::getline(s, req);
|
||||
|
||||
if (request[request.size()-1] == '\r') {
|
||||
request.erase(request.end()-1);
|
||||
if (req[req.size()-1] == '\r') {
|
||||
req.erase(req.end()-1);
|
||||
|
||||
std::stringstream ss(request);
|
||||
std::stringstream ss(req);
|
||||
std::string 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() {
|
||||
// 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";
|
||||
raw << raw_headers() << "\r\n" << m_body;
|
||||
ret << m_method << " " << m_uri << " " << get_version() << "\r\n";
|
||||
ret << raw_headers() << "\r\n" << m_body;
|
||||
|
||||
return raw.str();
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
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
|
||||
* 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) {
|
||||
// parse a complete header (ie \r\n\r\n MUST be in the input stream)
|
||||
std::string response;
|
||||
std::string line;
|
||||
|
||||
// get status line
|
||||
std::getline(s, response);
|
||||
std::getline(s, line);
|
||||
|
||||
if (response[response.size()-1] == '\r') {
|
||||
response.erase(response.end()-1);
|
||||
if (line[line.size()-1] == '\r') {
|
||||
line.erase(line.end()-1);
|
||||
|
||||
std::stringstream ss(response);
|
||||
std::stringstream ss(line);
|
||||
std::string str_val;
|
||||
int int_val;
|
||||
char char_val[256];
|
||||
@@ -201,14 +201,14 @@ inline bool response::parse_complete(std::istream& s) {
|
||||
inline std::string response::raw() const {
|
||||
// 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;
|
||||
raw << "\r\n" << raw_headers() << "\r\n";
|
||||
ret << get_version() << " " << m_status_code << " " << m_status_msg;
|
||||
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) {
|
||||
|
||||
+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
|
||||
* 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) {
|
||||
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());
|
||||
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
typedef lib::shared_ptr<type> ptr;
|
||||
|
||||
request()
|
||||
: m_buf(new std::string())
|
||||
: m_buf(lib::make_shared<std::string>())
|
||||
, m_ready(false) {}
|
||||
|
||||
/// 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
response()
|
||||
: m_read(0)
|
||||
, m_buf(new std::string())
|
||||
, m_buf(lib::make_shared<std::string>())
|
||||
, m_status_code(status_code::uninitialized)
|
||||
, 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
|
||||
* 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);
|
||||
// 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,
|
||||
m_elog, m_rng));
|
||||
connection_ptr con = lib::make_shared<connection_type>(m_is_server,
|
||||
m_user_agent, lib::ref(m_alog), lib::ref(m_elog), lib::ref(m_rng));
|
||||
|
||||
connection_weak_ptr w(con);
|
||||
|
||||
@@ -64,16 +64,19 @@ endpoint<connection,config>::create_connection() {
|
||||
con->set_http_handler(m_http_handler);
|
||||
con->set_validate_handler(m_validate_handler);
|
||||
con->set_message_handler(m_message_handler);
|
||||
|
||||
if (m_open_handshake_timeout_dur == config::timeout_open_handshake) {
|
||||
|
||||
if (m_open_handshake_timeout_dur != config::timeout_open_handshake) {
|
||||
con->set_open_handshake_timeout(m_open_handshake_timeout_dur);
|
||||
}
|
||||
if (m_close_handshake_timeout_dur == config::timeout_close_handshake) {
|
||||
if (m_close_handshake_timeout_dur != config::timeout_close_handshake) {
|
||||
con->set_close_handshake_timeout(m_close_handshake_timeout_dur);
|
||||
}
|
||||
if (m_pong_timeout_dur == config::timeout_pong) {
|
||||
if (m_pong_timeout_dur != config::timeout_pong) {
|
||||
con->set_pong_timeout(m_pong_timeout_dur);
|
||||
}
|
||||
if (m_max_message_size != config::max_message_size) {
|
||||
con->set_max_message_size(m_max_message_size);
|
||||
}
|
||||
|
||||
lib::error_code ec;
|
||||
|
||||
@@ -87,8 +90,7 @@ endpoint<connection,config>::create_connection() {
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl,
|
||||
lib::error_code & ec)
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
@@ -102,12 +104,46 @@ template <typename connection, typename config>
|
||||
void endpoint<connection,config>::interrupt(connection_hdl hdl) {
|
||||
lib::error_code ec;
|
||||
interrupt(hdl,ec);
|
||||
if (ec) { throw 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)
|
||||
void endpoint<connection,config>::pause_reading(connection_hdl hdl, lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
|
||||
ec = con->pause_reading();
|
||||
}
|
||||
|
||||
template <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);
|
||||
if (ec) {return;}
|
||||
@@ -116,12 +152,12 @@ void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const &
|
||||
payload, frame::opcode::value op)
|
||||
void endpoint<connection,config>::send(connection_hdl hdl, std::string const & payload,
|
||||
frame::opcode::value op)
|
||||
{
|
||||
lib::error_code ec;
|
||||
send(hdl,payload,op,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -139,7 +175,7 @@ void endpoint<connection,config>::send(connection_hdl hdl, void const * payload,
|
||||
{
|
||||
lib::error_code ec;
|
||||
send(hdl,payload,len,op,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
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) {
|
||||
lib::error_code ec;
|
||||
send(hdl,msg,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
@@ -174,7 +210,7 @@ void endpoint<connection,config>::close(connection_hdl hdl, close::status::value
|
||||
{
|
||||
lib::error_code ec;
|
||||
close(hdl,code,reason,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
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>
|
||||
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const &
|
||||
payload)
|
||||
void endpoint<connection,config>::ping(connection_hdl hdl, std::string const & payload)
|
||||
{
|
||||
lib::error_code ec;
|
||||
ping(hdl,payload,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
payload, lib::error_code & ec)
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload,
|
||||
lib::error_code & ec)
|
||||
{
|
||||
connection_ptr con = get_con_from_hdl(hdl,ec);
|
||||
if (ec) {return;}
|
||||
@@ -205,12 +240,11 @@ void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
}
|
||||
|
||||
template <typename connection, typename config>
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const &
|
||||
payload)
|
||||
void endpoint<connection,config>::pong(connection_hdl hdl, std::string const & payload)
|
||||
{
|
||||
lib::error_code ec;
|
||||
pong(hdl,payload,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
} // 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
#include <websocketpp/common/time.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
@@ -55,12 +56,24 @@ namespace log {
|
||||
template <typename concurrency, typename names>
|
||||
class basic {
|
||||
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_dynamic_channels(0)
|
||||
, 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_dynamic_channels(0)
|
||||
, m_out(out) {}
|
||||
@@ -120,13 +133,13 @@ private:
|
||||
// TODO: find a workaround for this or make this format user settable
|
||||
static std::ostream & timestamp(std::ostream & os) {
|
||||
std::time_t t = std::time(NULL);
|
||||
std::tm* lt = std::localtime(&t);
|
||||
#ifdef _WEBSOCKETPP_CPP11_CHRONO_
|
||||
return os << std::put_time(lt,"%Y-%m-%d %H:%M:%S");
|
||||
std::tm lt = lib::localtime(t);
|
||||
#ifdef _WEBSOCKETPP_PUTTIME_
|
||||
return os << std::put_time(<,"%Y-%m-%d %H:%M:%S");
|
||||
#else // Falls back to strftime, which requires a temporary copy of the string.
|
||||
char buffer[20];
|
||||
std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",lt);
|
||||
return os << buffer;
|
||||
size_t result = std::strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",<);
|
||||
return os << (result == 0 ? "Unknown" : buffer);
|
||||
#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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -36,6 +36,25 @@ namespace log {
|
||||
/// Type of a channel package
|
||||
typedef uint32_t level;
|
||||
|
||||
/// Package of values for hinting at the nature of a given logger.
|
||||
/**
|
||||
* Used by the library to signal to the logging class a hint that it can use to
|
||||
* set itself up. For example, the `access` hint indicates that it is an access
|
||||
* log that might be suitable for being printed to an access log file or to cout
|
||||
* whereas `error` might be suitable for an error log file or cerr.
|
||||
*/
|
||||
struct channel_type_hint {
|
||||
/// Type of a channel type hint value
|
||||
typedef uint32_t value;
|
||||
|
||||
/// No information
|
||||
static value const none = 0;
|
||||
/// Access log
|
||||
static value const access = 1;
|
||||
/// Error log
|
||||
static value const error = 2;
|
||||
};
|
||||
|
||||
/// Package of log levels for logging errors
|
||||
struct elevel {
|
||||
/// Special aggregate value representing "no levels"
|
||||
|
||||
+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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -28,7 +28,7 @@
|
||||
#ifndef WEBSOCKETPP_LOGGER_STUB_HPP
|
||||
#define WEBSOCKETPP_LOGGER_STUB_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
@@ -39,20 +39,75 @@ namespace log {
|
||||
/// Stub logger that ignores all input
|
||||
class stub {
|
||||
public:
|
||||
explicit stub(std::ostream * out) {}
|
||||
stub(level c, std::ostream * out) {}
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
explicit stub(channel_type_hint::value) {}
|
||||
|
||||
/// Construct the logger
|
||||
/**
|
||||
* @param default_channels A set of channels to statically enable
|
||||
* @param hint A channel type specific hint for how to construct the logger
|
||||
*/
|
||||
stub(level, channel_type_hint::value) {}
|
||||
_WEBSOCKETPP_CONSTEXPR_TOKEN_ stub() {}
|
||||
|
||||
void set_channels(level channels) {}
|
||||
void clear_channels(level channels) {}
|
||||
/// Dynamically enable the given list of channels
|
||||
/**
|
||||
* All operations on the stub logger are no-ops and all arguments are
|
||||
* ignored
|
||||
*
|
||||
* @param channels The package of channels to enable
|
||||
*/
|
||||
void set_channels(level) {}
|
||||
|
||||
/// Dynamically disable the given list of channels
|
||||
/**
|
||||
* All operations on the stub logger are no-ops and all arguments are
|
||||
* ignored
|
||||
*
|
||||
* @param channels The package of channels to disable
|
||||
*/
|
||||
void clear_channels(level) {}
|
||||
|
||||
void write(level channel, std::string const & msg) {}
|
||||
void write(level channel, char const * msg) {}
|
||||
/// Write a string message to the given channel
|
||||
/**
|
||||
* Writing on the stub logger is a no-op and all arguments are ignored
|
||||
*
|
||||
* @param channel The 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
* @return A shared pointer to an empty new 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
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
* @return A shared pointer to a new message with specified size.
|
||||
*/
|
||||
message_ptr get_message(frame::opcode::value op,size_t size) {
|
||||
return message_ptr(new message(type::shared_from_this(),op,size));
|
||||
return message_ptr(lib::make_shared<message>(type::shared_from_this(),op,size));
|
||||
}
|
||||
|
||||
/// Recycle a message
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
*
|
||||
* @return true if the message was successfully recycled, false otherwse.
|
||||
*/
|
||||
bool recycle(message * msg) {
|
||||
bool recycle(message *) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
* @return A pointer to the requested connection message manager.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
message_ptr get_message(size_t size) const {
|
||||
return message_ptr(new message(size));
|
||||
return lib::make_shared<message>(size);
|
||||
}
|
||||
|
||||
/// Recycle a message
|
||||
@@ -201,7 +201,7 @@ public:
|
||||
* @return A pointer to the requested connection message manager.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <websocketpp/utf8_validator.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
#include <websocketpp/common/md5.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
|
||||
@@ -57,8 +58,8 @@ public:
|
||||
|
||||
typedef typename config::con_msg_manager_type::ptr msg_manager_ptr;
|
||||
|
||||
explicit hybi00(bool secure, bool server, msg_manager_ptr manager)
|
||||
: processor<config>(secure, server)
|
||||
explicit hybi00(bool secure, bool p_is_server, msg_manager_ptr manager)
|
||||
: processor<config>(secure, p_is_server)
|
||||
, msg_hdr(0x00)
|
||||
, msg_ftr(0xff)
|
||||
, m_state(HEADER)
|
||||
@@ -109,7 +110,7 @@ public:
|
||||
// of warning or exception.
|
||||
const std::string& key3 = req.get_header("Sec-WebSocket-Key3");
|
||||
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]);
|
||||
|
||||
res.append_header(
|
||||
@@ -140,15 +141,32 @@ public:
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
// outgoing client connection processing is not supported for this version
|
||||
lib::error_code client_handshake_request(request_type& req, uri_ptr uri,
|
||||
std::vector<std::string> const & subprotocols) const
|
||||
/// Fill in a set of request headers for a client connection request
|
||||
/**
|
||||
* The Hybi 00 processor only implements incoming connections so this will
|
||||
* always return an error.
|
||||
*
|
||||
* @param [out] req Set of headers to fill in
|
||||
* @param [in] uri The uri being connected to
|
||||
* @param [in] subprotocols The list of subprotocols to request
|
||||
*/
|
||||
lib::error_code client_handshake_request(request_type &, uri_ptr,
|
||||
std::vector<std::string> const &) const
|
||||
{
|
||||
return error::make_error_code(error::no_protocol_support);
|
||||
}
|
||||
|
||||
lib::error_code validate_server_handshake_response(request_type const & req,
|
||||
response_type & res) const
|
||||
/// Validate the server's response to an outgoing handshake request
|
||||
/**
|
||||
* The Hybi 00 processor only implements incoming connections so this will
|
||||
* always return an error.
|
||||
*
|
||||
* @param req The original request sent
|
||||
* @param res The reponse to generate
|
||||
* @return An error code, 0 on success, non-zero for other errors
|
||||
*/
|
||||
lib::error_code validate_server_handshake_response(request_type const &,
|
||||
response_type &) const
|
||||
{
|
||||
return error::make_error_code(error::no_protocol_support);
|
||||
}
|
||||
@@ -163,9 +181,16 @@ public:
|
||||
return r.get_header("Origin");
|
||||
}
|
||||
|
||||
// hybi00 doesn't support subprotocols so there never will be any requested
|
||||
lib::error_code extract_subprotocols(request_type const & req,
|
||||
std::vector<std::string> & subprotocol_list)
|
||||
/// Extracts requested subprotocols from a handshake request
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
@@ -184,12 +209,12 @@ public:
|
||||
if (last_colon == std::string::npos ||
|
||||
(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 {
|
||||
return uri_ptr(new uri(base::m_secure,
|
||||
return lib::make_shared<uri>(base::m_secure,
|
||||
h.substr(0,last_colon),
|
||||
h.substr(last_colon+1),
|
||||
request.get_uri()));
|
||||
request.get_uri());
|
||||
}
|
||||
|
||||
// TODO: check if get_uri is a full uri
|
||||
@@ -318,18 +343,44 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
lib::error_code prepare_close(close::status::value code,
|
||||
std::string const & reason, message_ptr out) const
|
||||
/// Prepare a close frame
|
||||
/**
|
||||
* Hybi 00 doesn't support the close code or reason so these parameters are
|
||||
* ignored.
|
||||
*
|
||||
* @param code The close code to send
|
||||
* @param reason The reason string to send
|
||||
* @param out The message buffer to prepare the fame in
|
||||
* @return Status code, zero on success, non-zero on failure
|
||||
*/
|
||||
lib::error_code prepare_close(close::status::value, std::string const &,
|
||||
message_ptr out) const
|
||||
{
|
||||
if (!out) {
|
||||
return lib::error_code(error::invalid_arguments);
|
||||
|
||||
@@ -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
|
||||
* 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::rng_type rng_type;
|
||||
|
||||
explicit hybi07(bool secure, bool server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
: hybi08<config>(secure, server, manager, rng) {}
|
||||
explicit hybi07(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||
: hybi08<config>(secure, p_is_server, manager, rng) {}
|
||||
|
||||
// outgoing client connection processing is not supported for this version
|
||||
lib::error_code client_handshake_request(request_type & req, uri_ptr uri,
|
||||
std::vector<std::string> const & subprotocols) const
|
||||
/// Fill in a set of request headers for a client connection request
|
||||
/**
|
||||
* The Hybi 07 processor only implements incoming connections so this will
|
||||
* always return an error.
|
||||
*
|
||||
* @param [out] req Set of headers to fill in
|
||||
* @param [in] uri The uri being connected to
|
||||
* @param [in] subprotocols The list of subprotocols to request
|
||||
*/
|
||||
lib::error_code client_handshake_request(request_type &, uri_ptr,
|
||||
std::vector<std::string> const &) const
|
||||
{
|
||||
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
|
||||
* 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::rng_type rng_type;
|
||||
|
||||
explicit hybi08(bool secure, bool server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
: hybi13<config>(secure, server, manager, rng) {}
|
||||
explicit hybi08(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||
: hybi13<config>(secure, p_is_server, manager, rng) {}
|
||||
|
||||
// outgoing client connection processing is not supported for this version
|
||||
lib::error_code client_handshake_request(request_type& req, uri_ptr uri,
|
||||
std::vector<std::string> const & subprotocols) const
|
||||
/// Fill in a set of request headers for a client connection request
|
||||
/**
|
||||
* The Hybi 08 processor only implements incoming connections so this will
|
||||
* always return an error.
|
||||
*
|
||||
* @param [out] req Set of headers to fill in
|
||||
* @param [in] uri The uri being connected to
|
||||
* @param [in] subprotocols The list of subprotocols to request
|
||||
*/
|
||||
lib::error_code client_handshake_request(request_type &, uri_ptr,
|
||||
std::vector<std::string> const &) const
|
||||
{
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <websocketpp/frame.hpp>
|
||||
#include <websocketpp/utf8_validator.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/http/constants.hpp>
|
||||
|
||||
#include <websocketpp/processors/processor.hpp>
|
||||
@@ -67,9 +68,8 @@ public:
|
||||
|
||||
typedef std::pair<lib::error_code,std::string> err_str_pair;
|
||||
|
||||
explicit hybi13(bool secure, bool server, msg_manager_ptr manager,
|
||||
rng_type& rng)
|
||||
: processor<config>(secure,server)
|
||||
explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
|
||||
: processor<config>(secure, p_is_server)
|
||||
, m_msg_manager(manager)
|
||||
, m_rng(rng)
|
||||
{
|
||||
@@ -121,8 +121,8 @@ public:
|
||||
// Figure out if this is an error that should halt all
|
||||
// extension negotiations or simply cause negotiation of
|
||||
// this specific extension to fail.
|
||||
std::cout << "permessage-compress negotiation failed: "
|
||||
<< neg_ret.first.message() << std::endl;
|
||||
//std::cout << "permessage-compress negotiation failed: "
|
||||
// << neg_ret.first.message() << std::endl;
|
||||
} else {
|
||||
// Note: this list will need commas if WebSocket++ ever
|
||||
// supports more than one extension
|
||||
@@ -182,7 +182,13 @@ public:
|
||||
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
|
||||
{
|
||||
req.set_method("GET");
|
||||
@@ -219,6 +225,12 @@ public:
|
||||
return lib::error_code();
|
||||
}
|
||||
|
||||
/// Validate the server's response to an outgoing handshake request
|
||||
/**
|
||||
* @param req The original request sent
|
||||
* @param res The reponse to generate
|
||||
* @return An error code, 0 on success, non-zero for other errors
|
||||
*/
|
||||
lib::error_code validate_server_handshake_response(request_type const & req,
|
||||
response_type& res) const
|
||||
{
|
||||
@@ -369,11 +381,25 @@ public:
|
||||
m_current_msg = &m_control_msg;
|
||||
} else {
|
||||
if (!m_data_msg.msg_ptr) {
|
||||
if (m_bytes_needed > base::m_max_message_size) {
|
||||
ec = make_error_code(error::message_too_big);
|
||||
break;
|
||||
}
|
||||
|
||||
m_data_msg = msg_metadata(
|
||||
m_msg_manager->get_message(op,m_bytes_needed),
|
||||
frame::get_masking_key(m_basic_header,m_extended_header)
|
||||
);
|
||||
} else {
|
||||
// Fetch the underlying payload buffer from the data message we
|
||||
// are writing into.
|
||||
std::string & out = m_data_msg.msg_ptr->get_raw_payload();
|
||||
|
||||
if (out.size() + m_bytes_needed > base::m_max_message_size) {
|
||||
ec = make_error_code(error::message_too_big);
|
||||
break;
|
||||
}
|
||||
|
||||
// Each frame starts a new masking key. All other state
|
||||
// remains between frames.
|
||||
m_data_msg.prepared_key = prepare_masking_key(
|
||||
@@ -382,14 +408,15 @@ public:
|
||||
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;
|
||||
}
|
||||
} else if (m_state == EXTENSION) {
|
||||
m_state = APPLICATION;
|
||||
} else if (m_state == APPLICATION) {
|
||||
size_t bytes_to_process = std::min(m_bytes_needed,len-p);
|
||||
size_t bytes_to_process = (std::min)(m_bytes_needed,len-p);
|
||||
|
||||
if (bytes_to_process > 0) {
|
||||
p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
|
||||
@@ -655,7 +682,7 @@ protected:
|
||||
|
||||
/// Reads bytes from buf into m_extended_header
|
||||
size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
|
||||
size_t bytes_to_read = std::min(m_bytes_needed,len);
|
||||
size_t bytes_to_read = (std::min)(m_bytes_needed,len);
|
||||
|
||||
std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
|
||||
m_cursor += bytes_to_read;
|
||||
|
||||
@@ -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
|
||||
* 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 ||
|
||||
(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 {
|
||||
return uri_ptr(new uri(scheme,
|
||||
return lib::make_shared<uri>(scheme,
|
||||
h.substr(0,last_colon),
|
||||
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 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_server(server) {}
|
||||
, m_server(p_is_server)
|
||||
, m_max_message_size(config::max_message_size)
|
||||
{}
|
||||
|
||||
virtual ~processor() {}
|
||||
|
||||
/// Get the protocol version of this processor
|
||||
virtual int get_version() const = 0;
|
||||
|
||||
/// Get maximum message size
|
||||
/**
|
||||
* Get maximum message size. Maximum message size determines the point at which the
|
||||
* processor will fail a connection with the message_too_big protocol error.
|
||||
*
|
||||
* The default is retrieved from the max_message_size value from the template config
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
size_t get_max_message_size() const {
|
||||
return m_max_message_size;
|
||||
}
|
||||
|
||||
/// Set maximum message size
|
||||
/**
|
||||
* Set maximum message size. Maximum message size determines the point at which the
|
||||
* processor will fail a connection with the message_too_big protocol error.
|
||||
*
|
||||
* The default is retrieved from the max_message_size value from the template config
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param new_value The value to set as the maximum message size.
|
||||
*/
|
||||
void set_max_message_size(size_t new_value) {
|
||||
m_max_message_size = new_value;
|
||||
}
|
||||
|
||||
/// Returns whether or not the permessage_compress extension is implemented
|
||||
/**
|
||||
* Compile time flag that indicates whether this processor has implemented
|
||||
@@ -182,8 +212,10 @@ public:
|
||||
* Reads the Sec-WebSocket-Extensions header and determines if any of the
|
||||
* requested extensions are supported by this processor. If they are their
|
||||
* settings data is initialized.
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
@@ -196,8 +228,7 @@ public:
|
||||
* @return A status code, 0 on success, non-zero for specific sorts of
|
||||
* failure
|
||||
*/
|
||||
virtual lib::error_code validate_handshake(request_type const & request)
|
||||
const = 0;
|
||||
virtual lib::error_code validate_handshake(request_type const & request) const = 0;
|
||||
|
||||
/// Calculate the appropriate response for this websocket request
|
||||
/**
|
||||
@@ -224,9 +255,7 @@ public:
|
||||
/// Validate the server's response to an outgoing handshake request
|
||||
/**
|
||||
* @param req The original request sent
|
||||
*
|
||||
* @param res The reponse to generate
|
||||
*
|
||||
* @return An error code, 0 on success, non-zero for other errors
|
||||
*/
|
||||
virtual lib::error_code validate_server_handshake_response(request_type
|
||||
@@ -236,18 +265,16 @@ public:
|
||||
virtual std::string get_raw(response_type const & request) const = 0;
|
||||
|
||||
/// Return the value of the header containing the CORS origin.
|
||||
virtual std::string const & get_origin(request_type const & request)
|
||||
const = 0;
|
||||
virtual std::string const & get_origin(request_type const & request) const = 0;
|
||||
|
||||
/// Extracts requested subprotocols from a handshake request
|
||||
/**
|
||||
* Extracts a list of all subprotocols that the client has requested in the
|
||||
* given opening handshake request.
|
||||
*
|
||||
* @param req The request to extract from
|
||||
*
|
||||
* @param subprotocol_list A reference to a vector of strings to store the
|
||||
* results in.
|
||||
* @param [in] req The request to extract from
|
||||
* @param [out] subprotocol_list A reference to a vector of strings to store
|
||||
* the results in.
|
||||
*/
|
||||
virtual lib::error_code extract_subprotocols(const request_type & req,
|
||||
std::vector<std::string> & subprotocol_list) = 0;
|
||||
@@ -261,11 +288,8 @@ public:
|
||||
* interpreted by a protocol processor into discrete frames.
|
||||
*
|
||||
* @param buf Buffer from which bytes should be read.
|
||||
*
|
||||
* @param len Length of buffer
|
||||
*
|
||||
* @param ec Reference to an error code to return any errors in
|
||||
*
|
||||
* @return Number of bytes processed
|
||||
*/
|
||||
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
|
||||
@@ -310,8 +334,7 @@ public:
|
||||
* Performs validation, masking, compression, etc. will return an error if
|
||||
* there was an error, otherwise msg will be ready to be written
|
||||
*/
|
||||
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
|
||||
= 0;
|
||||
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0;
|
||||
|
||||
/// Prepare a ping frame
|
||||
/**
|
||||
@@ -319,13 +342,11 @@ public:
|
||||
* other than length. Payload need not be UTF-8.
|
||||
*
|
||||
* @param in The string to use for the ping payload
|
||||
*
|
||||
* @param out The message buffer to prepare the ping in.
|
||||
*
|
||||
* @return Status code, zero on success, non-zero on failure
|
||||
*/
|
||||
virtual lib::error_code prepare_ping(std::string const & in,
|
||||
message_ptr out) const = 0;
|
||||
virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const
|
||||
= 0;
|
||||
|
||||
/// Prepare a pong frame
|
||||
/**
|
||||
@@ -333,13 +354,11 @@ public:
|
||||
* other than length. Payload need not be UTF-8.
|
||||
*
|
||||
* @param in The string to use for the pong payload
|
||||
*
|
||||
* @param out The message buffer to prepare the pong in.
|
||||
*
|
||||
* @return Status code, zero on success, non-zero on failure
|
||||
*/
|
||||
virtual lib::error_code prepare_pong(std::string const & in,
|
||||
message_ptr out) const = 0;
|
||||
virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const
|
||||
= 0;
|
||||
|
||||
/// Prepare a close frame
|
||||
/**
|
||||
@@ -349,11 +368,8 @@ public:
|
||||
* indicate no code. If no code is supplied a reason may not be specified.
|
||||
*
|
||||
* @param code The close code to send
|
||||
*
|
||||
* @param reason The reason string to send
|
||||
*
|
||||
* @param out The message buffer to prepare the fame in
|
||||
*
|
||||
* @return Status code, zero on success, non-zero on failure
|
||||
*/
|
||||
virtual lib::error_code prepare_close(close::status::value code,
|
||||
@@ -361,6 +377,7 @@ public:
|
||||
protected:
|
||||
bool const m_secure;
|
||||
bool const m_server;
|
||||
size_t m_max_message_size;
|
||||
};
|
||||
|
||||
} // 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -29,6 +29,7 @@
|
||||
#define WEBSOCKETPP_RANDOM_NONE_HPP
|
||||
|
||||
namespace websocketpp {
|
||||
/// Random number generation policies
|
||||
namespace random {
|
||||
/// Stub RNG policy that always returns 0
|
||||
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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
* @return A connection_ptr to the new connection
|
||||
*/
|
||||
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()) {
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -64,52 +64,101 @@ public:
|
||||
/// Type of the endpoint component of this server
|
||||
typedef endpoint<connection_type,config> endpoint_type;
|
||||
|
||||
|
||||
// TODO: clean up these types
|
||||
|
||||
explicit server() : endpoint_type(true)
|
||||
{
|
||||
endpoint_type::m_alog.write(log::alevel::devel,
|
||||
"server constructor");
|
||||
endpoint_type::m_alog.write(log::alevel::devel, "server constructor");
|
||||
}
|
||||
|
||||
// return an initialized connection_ptr. Call start() on this object to
|
||||
// begin the processing loop.
|
||||
/// Create and initialize a new connection
|
||||
/**
|
||||
* The connection will be initialized and ready to begin. Call its start()
|
||||
* method to begin the processing loop.
|
||||
*
|
||||
* Note: The connection must either be started or terminated using
|
||||
* connection::terminate in order to avoid memory leaks.
|
||||
*
|
||||
* @return A pointer to the new connection.
|
||||
*/
|
||||
connection_ptr get_connection() {
|
||||
connection_ptr con = endpoint_type::create_connection();
|
||||
|
||||
return con;
|
||||
return endpoint_type::create_connection();
|
||||
}
|
||||
|
||||
// Starts the server's async connection acceptance loop.
|
||||
void start_accept() {
|
||||
/// Starts the server's async connection acceptance loop (exception free)
|
||||
/**
|
||||
* Initiates the server connection acceptance loop. Must be called after
|
||||
* listen. This method will have no effect until the underlying io_service
|
||||
* starts running. It may be called after the io_service is already running.
|
||||
*
|
||||
* Refer to documentation for the transport policy you are using for
|
||||
* instructions on how to stop this acceptance loop.
|
||||
*
|
||||
* @param [out] ec A status code indicating an error, if any.
|
||||
*/
|
||||
void start_accept(lib::error_code & ec) {
|
||||
if (!transport_type::is_listening()) {
|
||||
ec = error::make_error_code(error::async_accept_not_listening);
|
||||
return;
|
||||
}
|
||||
|
||||
ec = lib::error_code();
|
||||
connection_ptr con = get_connection();
|
||||
|
||||
|
||||
transport_type::async_accept(
|
||||
lib::static_pointer_cast<transport_con_type>(con),
|
||||
lib::bind(
|
||||
&type::handle_accept,
|
||||
this,
|
||||
con,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
|
||||
ec
|
||||
);
|
||||
|
||||
if (ec && con) {
|
||||
// If the connection was constructed but the accept failed,
|
||||
// terminate the connection to prevent memory leaks
|
||||
con->terminate(lib::error_code());
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
con->terminate(ec);
|
||||
|
||||
endpoint_type::m_elog.write(log::elevel::rerror,
|
||||
"handle_accept error: "+ec.message());
|
||||
if (ec == error::operation_canceled) {
|
||||
endpoint_type::m_elog.write(log::elevel::info,
|
||||
"handle_accept error: "+ec.message());
|
||||
} else {
|
||||
endpoint_type::m_elog.write(log::elevel::rerror,
|
||||
"handle_accept error: "+ec.message());
|
||||
}
|
||||
} else {
|
||||
con->start();
|
||||
}
|
||||
|
||||
// TODO: are there cases where we should terminate this loop?
|
||||
start_accept();
|
||||
lib::error_code start_ec;
|
||||
start_accept(start_ec);
|
||||
if (start_ec == error::async_accept_not_listening) {
|
||||
endpoint_type::m_elog.write(log::elevel::info,
|
||||
"Stopping acceptance of new connections because the underlying transport is no longer listening.");
|
||||
} else if (start_ec) {
|
||||
endpoint_type::m_elog.write(log::elevel::rerror,
|
||||
"Restarting async_accept loop failed: "+ec.message());
|
||||
}
|
||||
}
|
||||
private:
|
||||
};
|
||||
|
||||
} // 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
|
||||
* 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
|
||||
library (http://code.google.com/p/smallsha1/) into a single header suitable for
|
||||
use as a header only library. This conversion was done by Peter Thorson
|
||||
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||
under the same license as the original, which is listed below.
|
||||
*****
|
||||
|
||||
Copyright (c) 2011, Micael Hildenborg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Micael Hildenborg nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SHA1_DEFINED
|
||||
#define SHA1_DEFINED
|
||||
|
||||
namespace websocketpp {
|
||||
namespace sha1 {
|
||||
|
||||
namespace // local
|
||||
{
|
||||
// Rotate an integer value to left.
|
||||
inline const unsigned int rol(const unsigned int value,
|
||||
const unsigned int steps)
|
||||
{
|
||||
return ((value << steps) | (value >> (32 - steps)));
|
||||
}
|
||||
|
||||
// Sets the first 16 integers in the buffert to zero.
|
||||
// Used for clearing the W buffert.
|
||||
inline void clearWBuffert(unsigned int* buffert)
|
||||
{
|
||||
for (int pos = 16; --pos >= 0;)
|
||||
{
|
||||
buffert[pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void innerHash(unsigned int* result, unsigned int* w)
|
||||
{
|
||||
unsigned int a = result[0];
|
||||
unsigned int b = result[1];
|
||||
unsigned int c = result[2];
|
||||
unsigned int d = result[3];
|
||||
unsigned int e = result[4];
|
||||
|
||||
int round = 0;
|
||||
|
||||
#define sha1macro(func,val) \
|
||||
{ \
|
||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = rol(b, 30); \
|
||||
b = a; \
|
||||
a = t; \
|
||||
}
|
||||
|
||||
while (round < 16)
|
||||
{
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 20)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 40)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||
++round;
|
||||
}
|
||||
while (round < 60)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||
++round;
|
||||
}
|
||||
while (round < 80)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||
++round;
|
||||
}
|
||||
|
||||
#undef sha1macro
|
||||
|
||||
result[0] += a;
|
||||
result[1] += b;
|
||||
result[2] += c;
|
||||
result[3] += d;
|
||||
result[4] += e;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
@param src points to any kind of data to be hashed.
|
||||
@param bytelength the number of bytes to hash from the src pointer.
|
||||
@param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
|
||||
*/
|
||||
inline void calc(const void* src, const int bytelength, unsigned char* hash) {
|
||||
// Init the result array.
|
||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
|
||||
|
||||
// Cast the void src pointer to be the byte array we can work with.
|
||||
const unsigned char* sarray = (const unsigned char*) src;
|
||||
|
||||
// The reusable round buffer
|
||||
unsigned int w[80];
|
||||
|
||||
// Loop through all complete 64byte blocks.
|
||||
const int endOfFullBlocks = bytelength - 64;
|
||||
int endCurrentBlock;
|
||||
int currentBlock = 0;
|
||||
|
||||
while (currentBlock <= endOfFullBlocks)
|
||||
{
|
||||
endCurrentBlock = currentBlock + 64;
|
||||
|
||||
// Init the round buffer with the 64 byte block data.
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||
{
|
||||
// This line will swap endian on big endian and keep endian on little endian.
|
||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||
}
|
||||
innerHash(result, w);
|
||||
}
|
||||
|
||||
// Handle the last and not full 64 byte block if existing.
|
||||
endCurrentBlock = bytelength - currentBlock;
|
||||
clearWBuffert(w);
|
||||
int lastBlockBytes = 0;
|
||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes)
|
||||
{
|
||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
}
|
||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
if (endCurrentBlock >= 56)
|
||||
{
|
||||
innerHash(result, w);
|
||||
clearWBuffert(w);
|
||||
}
|
||||
w[15] = bytelength << 3;
|
||||
innerHash(result, w);
|
||||
|
||||
// Store hash in result pointer, and make sure we get in in the correct order on both endian models.
|
||||
for (int hashByte = 20; --hashByte >= 0;)
|
||||
{
|
||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sha1
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // SHA1_DEFINED
|
||||
/*
|
||||
*****
|
||||
sha1.hpp is a repackaging of the sha1.cpp and sha1.h files from the smallsha1
|
||||
library (http://code.google.com/p/smallsha1/) into a single header suitable for
|
||||
use as a header only library. This conversion was done by Peter Thorson
|
||||
(webmaster@zaphoyd.com) in 2013. All modifications to the code are redistributed
|
||||
under the same license as the original, which is listed below.
|
||||
*****
|
||||
|
||||
Copyright (c) 2011, Micael Hildenborg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Micael Hildenborg nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SHA1_DEFINED
|
||||
#define SHA1_DEFINED
|
||||
|
||||
namespace websocketpp {
|
||||
namespace sha1 {
|
||||
|
||||
namespace { // local
|
||||
|
||||
// Rotate an integer value to left.
|
||||
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||
return ((value << steps) | (value >> (32 - steps)));
|
||||
}
|
||||
|
||||
// Sets the first 16 integers in the buffert to zero.
|
||||
// Used for clearing the W buffert.
|
||||
inline void clearWBuffert(unsigned int * buffert)
|
||||
{
|
||||
for (int pos = 16; --pos >= 0;)
|
||||
{
|
||||
buffert[pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
{
|
||||
unsigned int a = result[0];
|
||||
unsigned int b = result[1];
|
||||
unsigned int c = result[2];
|
||||
unsigned int d = result[3];
|
||||
unsigned int e = result[4];
|
||||
|
||||
int round = 0;
|
||||
|
||||
#define sha1macro(func,val) \
|
||||
{ \
|
||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = rol(b, 30); \
|
||||
b = a; \
|
||||
a = t; \
|
||||
}
|
||||
|
||||
while (round < 16)
|
||||
{
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 20)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 40)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||
++round;
|
||||
}
|
||||
while (round < 60)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||
++round;
|
||||
}
|
||||
while (round < 80)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||
++round;
|
||||
}
|
||||
|
||||
#undef sha1macro
|
||||
|
||||
result[0] += a;
|
||||
result[1] += b;
|
||||
result[2] += c;
|
||||
result[3] += d;
|
||||
result[4] += e;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Calculate a SHA1 hash
|
||||
/**
|
||||
* @param src points to any kind of data to be hashed.
|
||||
* @param bytelength the number of bytes to hash from the src pointer.
|
||||
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||
* the sha1 result in.
|
||||
*/
|
||||
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
// Init the result array.
|
||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
||||
0x10325476, 0xc3d2e1f0 };
|
||||
|
||||
// Cast the void src pointer to be the byte array we can work with.
|
||||
unsigned char const * sarray = (unsigned char const *) src;
|
||||
|
||||
// The reusable round buffer
|
||||
unsigned int w[80];
|
||||
|
||||
// Loop through all complete 64byte blocks.
|
||||
|
||||
size_t endCurrentBlock;
|
||||
size_t currentBlock = 0;
|
||||
|
||||
if (bytelength >= 64) {
|
||||
size_t const endOfFullBlocks = bytelength - 64;
|
||||
|
||||
while (currentBlock <= endOfFullBlocks) {
|
||||
endCurrentBlock = currentBlock + 64;
|
||||
|
||||
// Init the round buffer with the 64 byte block data.
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||
{
|
||||
// This line will swap endian on big endian and keep endian on
|
||||
// little endian.
|
||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||
}
|
||||
innerHash(result, w);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the last and not full 64 byte block if existing.
|
||||
endCurrentBlock = bytelength - currentBlock;
|
||||
clearWBuffert(w);
|
||||
size_t lastBlockBytes = 0;
|
||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
}
|
||||
|
||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
if (endCurrentBlock >= 56) {
|
||||
innerHash(result, w);
|
||||
clearWBuffert(w);
|
||||
}
|
||||
w[15] = bytelength << 3;
|
||||
innerHash(result, w);
|
||||
|
||||
// Store hash in result pointer, and make sure we get in in the correct
|
||||
// order on both endian models.
|
||||
for (int hashByte = 20; --hashByte >= 0;) {
|
||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sha1
|
||||
} // namespace 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -28,6 +28,7 @@
|
||||
#ifndef WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||
#define WEBSOCKETPP_TRANSPORT_ASIO_CON_HPP
|
||||
|
||||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
#include <websocketpp/common/connection_hdl.hpp>
|
||||
@@ -115,7 +116,7 @@ public:
|
||||
* established but before any additional wrappers (proxy connects, TLS
|
||||
* handshakes, etc) have been performed.
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @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
|
||||
* 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.
|
||||
*/
|
||||
@@ -164,19 +165,19 @@ public:
|
||||
*
|
||||
* @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: should https urls be illegal for the moment?
|
||||
m_proxy = uri;
|
||||
m_proxy_data.reset(new proxy_data());
|
||||
m_proxy_data = lib::make_shared<proxy_data>();
|
||||
ec = lib::error_code();
|
||||
}
|
||||
|
||||
/// 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;
|
||||
set_proxy(uri,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Set the basic auth credentials to use (exception free)
|
||||
@@ -192,8 +193,8 @@ public:
|
||||
*
|
||||
* @param ec A status value
|
||||
*/
|
||||
void set_proxy_basic_auth(const std::string & username, const
|
||||
std::string & password, lib::error_code & ec)
|
||||
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||
password, lib::error_code & ec)
|
||||
{
|
||||
if (!m_proxy_data) {
|
||||
ec = make_error_code(websocketpp::error::invalid_state);
|
||||
@@ -207,12 +208,12 @@ public:
|
||||
}
|
||||
|
||||
/// Set the basic auth credentials to use (exception)
|
||||
void set_proxy_basic_auth(const std::string & username, const
|
||||
std::string & password)
|
||||
void set_proxy_basic_auth(std::string const & username, std::string const &
|
||||
password)
|
||||
{
|
||||
lib::error_code ec;
|
||||
set_proxy_basic_auth(username,password,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Set the proxy timeout duration (exception free)
|
||||
@@ -239,7 +240,7 @@ public:
|
||||
void set_proxy_timeout(long duration) {
|
||||
lib::error_code ec;
|
||||
set_proxy_timeout(duration,ec);
|
||||
if (ec) { throw ec; }
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
const std::string & get_proxy() const {
|
||||
@@ -289,11 +290,9 @@ public:
|
||||
* needed.
|
||||
*/
|
||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||
timer_ptr new_timer(
|
||||
new boost::asio::deadline_timer(
|
||||
*m_io_service,
|
||||
boost::posix_time::milliseconds(duration)
|
||||
)
|
||||
timer_ptr new_timer = lib::make_shared<boost::asio::deadline_timer>(
|
||||
lib::ref(*m_io_service),
|
||||
boost::posix_time::milliseconds(duration)
|
||||
);
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
@@ -322,11 +321,11 @@ public:
|
||||
*
|
||||
* 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 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)
|
||||
{
|
||||
if (ec) {
|
||||
@@ -407,7 +406,7 @@ protected:
|
||||
/// Finish constructing the transport
|
||||
/**
|
||||
* 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
|
||||
* connection
|
||||
@@ -415,35 +414,38 @@ protected:
|
||||
* @return Status code for the success or failure of the initialization
|
||||
*/
|
||||
lib::error_code init_asio (io_service_ptr io_service) {
|
||||
// do we need to store or use the io_service at this level?
|
||||
m_io_service = io_service;
|
||||
|
||||
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(
|
||||
&type::handle_async_read, get_shared(),
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
));
|
||||
&type::handle_async_read, get_shared(),lib::placeholders::_1,
|
||||
lib::placeholders::_2));
|
||||
|
||||
m_async_write_handler = m_strand->wrap(lib::bind(
|
||||
&type::handle_async_write, get_shared(),
|
||||
lib::placeholders::_1, lib::placeholders::_2
|
||||
));
|
||||
&type::handle_async_write, get_shared(),lib::placeholders::_1,
|
||||
lib::placeholders::_2));
|
||||
} else {
|
||||
// TODO: goal: not have this line here
|
||||
//m_strand.reset(new boost::asio::strand(*io_service));
|
||||
|
||||
m_async_read_handler = lib::bind(
|
||||
&type::handle_async_read, 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,
|
||||
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) {
|
||||
@@ -474,16 +476,19 @@ protected:
|
||||
}
|
||||
|
||||
timer_ptr post_timer;
|
||||
post_timer = set_timer(
|
||||
config::timeout_socket_post_init,
|
||||
lib::bind(
|
||||
&type::handle_post_init_timeout,
|
||||
get_shared(),
|
||||
post_timer,
|
||||
m_init_handler,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
|
||||
if (config::timeout_socket_post_init > 0) {
|
||||
post_timer = set_timer(
|
||||
config::timeout_socket_post_init,
|
||||
lib::bind(
|
||||
&type::handle_post_init_timeout,
|
||||
get_shared(),
|
||||
post_timer,
|
||||
m_init_handler,
|
||||
lib::placeholders::_1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
socket_con_type::post_init(
|
||||
lib::bind(
|
||||
@@ -496,8 +501,17 @@ protected:
|
||||
);
|
||||
}
|
||||
|
||||
void handle_post_init_timeout(timer_ptr post_timer, init_handler callback,
|
||||
const lib::error_code& ec)
|
||||
/// Post init timeout callback
|
||||
/**
|
||||
* The timer pointer is included to ensure the timer isn't destroyed until
|
||||
* after it has expired.
|
||||
*
|
||||
* @param post_timer Pointer to the timer in question
|
||||
* @param callback The function to call back
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_post_init_timeout(timer_ptr, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
lib::error_code ret_ec;
|
||||
|
||||
@@ -523,23 +537,34 @@ protected:
|
||||
callback(ret_ec);
|
||||
}
|
||||
|
||||
void handle_post_init(timer_ptr post_timer, init_handler callback, const
|
||||
lib::error_code& ec)
|
||||
/// Post init timeout callback
|
||||
/**
|
||||
* The timer pointer is included to ensure the timer isn't destroyed until
|
||||
* after it has expired.
|
||||
*
|
||||
* @param post_timer Pointer to the timer in question
|
||||
* @param callback The function to call back
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_post_init(timer_ptr post_timer, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
if (ec == transport::error::operation_aborted ||
|
||||
post_timer->expires_from_now().is_negative())
|
||||
(post_timer && post_timer->expires_from_now().is_negative()))
|
||||
{
|
||||
m_alog.write(log::alevel::devel,"post_init cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
post_timer->cancel();
|
||||
if (post_timer) {
|
||||
post_timer->cancel();
|
||||
}
|
||||
|
||||
if (m_alog.static_test(log::alevel::devel)) {
|
||||
m_alog.write(log::alevel::devel,"asio connection handle_post_init");
|
||||
}
|
||||
|
||||
if (m_tcp_post_init_handler) {
|
||||
if (m_tcp_post_init_handler) {
|
||||
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,
|
||||
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)) {
|
||||
m_alog.write(log::alevel::devel,
|
||||
@@ -779,7 +810,7 @@ protected:
|
||||
if (!m_async_read_handler) {
|
||||
m_alog.write(log::alevel::devel,
|
||||
"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;
|
||||
}
|
||||
|
||||
@@ -795,36 +826,54 @@ protected:
|
||||
|
||||
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(
|
||||
socket_con_type::get_socket(),
|
||||
boost::asio::buffer(buf,len),
|
||||
boost::asio::transfer_at_least(num_bytes),
|
||||
make_custom_alloc_handler(
|
||||
m_read_handler_allocator,
|
||||
m_async_read_handler
|
||||
m_read_handler_allocator,
|
||||
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)
|
||||
{
|
||||
if (!ec) {
|
||||
m_read_handler(lib::error_code(), bytes_transferred);
|
||||
return;
|
||||
}
|
||||
m_alog.write(log::alevel::devel, "asio con handle_async_read");
|
||||
|
||||
// translate boost error codes into more lib::error_codes
|
||||
lib::error_code tec;
|
||||
if (ec == boost::asio::error::eof) {
|
||||
m_read_handler(make_error_code(transport::error::eof),
|
||||
bytes_transferred);
|
||||
} else if (ec.value() == 335544539) {
|
||||
m_read_handler(make_error_code(transport::error::tls_short_read),
|
||||
bytes_transferred);
|
||||
tec = make_error_code(transport::error::eof);
|
||||
} else if (ec) {
|
||||
// We don't know much more about the error at this point. As our
|
||||
// socket/security policy if it knows more:
|
||||
tec = socket_con_type::translate_ec(ec);
|
||||
|
||||
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 {
|
||||
log_err(log::elevel::info,"asio async_read_at_least",ec);
|
||||
m_read_handler(make_error_code(transport::error::pass_through),
|
||||
bytes_transferred);
|
||||
// This can happen in cases where the connection is terminated while
|
||||
// the transport is waiting on a read.
|
||||
m_alog.write(log::alevel::devel,
|
||||
"handle_async_read called with null read handler");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,7 +885,7 @@ protected:
|
||||
return;
|
||||
}
|
||||
|
||||
m_bufs.push_back(boost::asio::buffer(buf,len));
|
||||
m_bufs.push_back(boost::asio::buffer(buf,len));
|
||||
|
||||
m_write_handler = handler;
|
||||
|
||||
@@ -844,8 +893,8 @@ protected:
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
m_async_write_handler
|
||||
m_write_handler_allocator,
|
||||
m_async_write_handler
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -869,21 +918,33 @@ protected:
|
||||
socket_con_type::get_socket(),
|
||||
m_bufs,
|
||||
make_custom_alloc_handler(
|
||||
m_write_handler_allocator,
|
||||
m_async_write_handler
|
||||
m_write_handler_allocator,
|
||||
m_async_write_handler
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_async_write(boost::system::error_code const & ec,
|
||||
size_t bytes_transferred)
|
||||
{
|
||||
/// Async write callback
|
||||
/**
|
||||
* @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();
|
||||
lib::error_code tec;
|
||||
if (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 {
|
||||
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");
|
||||
}
|
||||
|
||||
// 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
|
||||
// the connection if not destroyed.
|
||||
m_async_read_handler = 0;
|
||||
m_async_write_handler = 0;
|
||||
m_init_handler = 0;
|
||||
// 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 the connection if not destroyed.
|
||||
lib::clear_function(m_async_read_handler);
|
||||
lib::clear_function(m_async_write_handler);
|
||||
lib::clear_function(m_init_handler);
|
||||
|
||||
lib::clear_function(m_read_handler);
|
||||
lib::clear_function(m_write_handler);
|
||||
|
||||
timer_ptr shutdown_timer;
|
||||
shutdown_timer = set_timer(
|
||||
@@ -961,8 +1025,14 @@ protected:
|
||||
);
|
||||
}
|
||||
|
||||
void handle_async_shutdown_timeout(timer_ptr shutdown_timer, init_handler
|
||||
callback, const lib::error_code& ec)
|
||||
/// Async shutdown timeout handler
|
||||
/**
|
||||
* @param shutdown_timer A pointer to the timer to keep it in scope
|
||||
* @param callback The function to call back
|
||||
* @param ec The status code
|
||||
*/
|
||||
void handle_async_shutdown_timeout(timer_ptr, init_handler callback,
|
||||
lib::error_code const & ec)
|
||||
{
|
||||
lib::error_code ret_ec;
|
||||
|
||||
@@ -973,7 +1043,7 @@ protected:
|
||||
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;
|
||||
} else {
|
||||
ret_ec = make_error_code(transport::error::timeout);
|
||||
@@ -986,7 +1056,7 @@ protected:
|
||||
}
|
||||
|
||||
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 ||
|
||||
shutdown_timer->expires_from_now().is_negative())
|
||||
@@ -997,25 +1067,37 @@ protected:
|
||||
|
||||
shutdown_timer->cancel();
|
||||
|
||||
lib::error_code tec;
|
||||
if (ec) {
|
||||
log_err(log::elevel::info,"asio async_shutdown",ec);
|
||||
if (ec == boost::asio::error::not_connected) {
|
||||
// The socket was already closed when we tried to close it. This
|
||||
// happens periodically (usually if a read or write fails
|
||||
// earlier and if it is a real error will be caught at another
|
||||
// level of the stack.
|
||||
callback(lib::error_code());
|
||||
} 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 {
|
||||
if (m_alog.static_test(log::alevel::devel)) {
|
||||
m_alog.write(log::alevel::devel,
|
||||
"asio con handle_async_shutdown");
|
||||
}
|
||||
|
||||
callback(lib::error_code());
|
||||
}
|
||||
callback(tec);
|
||||
}
|
||||
private:
|
||||
/// 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -38,8 +38,6 @@
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace asio {
|
||||
@@ -89,8 +87,10 @@ public:
|
||||
|
||||
// generate and manage our own io_service
|
||||
explicit endpoint()
|
||||
: m_external_io_service(false)
|
||||
: m_io_service(NULL)
|
||||
, m_external_io_service(false)
|
||||
, m_listen_backlog(0)
|
||||
, m_reuse_addr(false)
|
||||
, m_state(UNINITIALIZED)
|
||||
{
|
||||
//std::cout << "transport::asio::endpoint constructor" << std::endl;
|
||||
@@ -122,7 +122,8 @@ public:
|
||||
: m_io_service(src.m_io_service)
|
||||
, m_external_io_service(src.m_external_io_service)
|
||||
, 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)
|
||||
{
|
||||
src.m_io_service = NULL;
|
||||
@@ -136,13 +137,14 @@ public:
|
||||
m_io_service = rhs.m_io_service;
|
||||
m_external_io_service = rhs.m_external_io_service;
|
||||
m_acceptor = rhs.m_acceptor;
|
||||
m_listen_backlog = rhs.m_listen_backlog
|
||||
m_listen_backlog = rhs.m_listen_backlog;
|
||||
m_reuse_addr = rhs.m_reuse_addr;
|
||||
m_state = rhs.m_state;
|
||||
|
||||
rhs.m_io_service = NULL;
|
||||
rhs.m_external_io_service = false;
|
||||
rhs.m_acceptor = NULL;
|
||||
rhs.m_listen_backlog = 0;
|
||||
rhs.m_listen_backlog = boost::asio::socket_base::max_connections;
|
||||
rhs.m_state = UNINITIALIZED;
|
||||
}
|
||||
return *this;
|
||||
@@ -175,7 +177,9 @@ public:
|
||||
|
||||
m_io_service = ptr;
|
||||
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;
|
||||
ec = lib::error_code();
|
||||
}
|
||||
@@ -191,9 +195,7 @@ public:
|
||||
void init_asio(io_service_ptr ptr) {
|
||||
lib::error_code ec;
|
||||
init_asio(ptr,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Initialize asio transport with internal io_service (exception free)
|
||||
@@ -206,7 +208,7 @@ public:
|
||||
* @param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -228,7 +230,7 @@ public:
|
||||
* established but before any additional wrappers (proxy connects, TLS
|
||||
* handshakes, etc) have been performed.
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @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
|
||||
* 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.
|
||||
*/
|
||||
@@ -280,13 +282,31 @@ public:
|
||||
* A value of zero will use the operating system default. This is the
|
||||
* default value.
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
* @since 0.3.0
|
||||
*
|
||||
* @param backlog The maximum length of the queue of pending connections
|
||||
*/
|
||||
void set_listen_backlog(int backlog) {
|
||||
m_listen_backlog = backlog;
|
||||
}
|
||||
|
||||
/// Sets whether to use the SO_REUSEADDR flag when opening listening sockets
|
||||
/**
|
||||
* Specifies whether or not to use the SO_REUSEADDR TCP socket option. What
|
||||
* this flag does depends on your operating system. Please consult operating
|
||||
* system documentation for more details.
|
||||
*
|
||||
* 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
|
||||
/**
|
||||
@@ -323,16 +343,25 @@ public:
|
||||
|
||||
m_alog->write(log::alevel::devel,"asio::listen");
|
||||
|
||||
m_acceptor->open(ep.protocol());
|
||||
m_acceptor->set_option(boost::asio::socket_base::reuse_address(true));
|
||||
m_acceptor->bind(ep);
|
||||
if (m_listen_backlog == 0) {
|
||||
m_acceptor->listen();
|
||||
boost::system::error_code bec;
|
||||
|
||||
m_acceptor->open(ep.protocol(),bec);
|
||||
if (!bec) {
|
||||
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 {
|
||||
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
|
||||
@@ -344,9 +373,7 @@ public:
|
||||
void listen(boost::asio::ip::tcp::endpoint const & ep) {
|
||||
lib::error_code ec;
|
||||
listen(ep,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Set up endpoint for listening with protocol and port (exception free)
|
||||
@@ -476,9 +503,7 @@ public:
|
||||
{
|
||||
lib::error_code ec;
|
||||
listen(host,service,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Stop listening (exception free)
|
||||
@@ -513,9 +538,15 @@ public:
|
||||
void stop_listening() {
|
||||
lib::error_code ec;
|
||||
stop_listening(ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
|
||||
/// Check if the endpoint is listening
|
||||
/**
|
||||
* @return Whether or not the endpoint is listening.
|
||||
*/
|
||||
bool is_listening() const {
|
||||
return (m_state == LISTENING);
|
||||
}
|
||||
|
||||
/// wraps the run method of the internal io_service object
|
||||
@@ -566,10 +597,12 @@ public:
|
||||
* called either before the endpoint has run out of work or before it was
|
||||
* started
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
* @since 0.3.0
|
||||
*/
|
||||
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
|
||||
@@ -578,7 +611,7 @@ public:
|
||||
* method to exit normally when it runs out of connections. If there are
|
||||
* currently active connections it will not end until they are complete.
|
||||
*
|
||||
* @since 0.4.0-alpha1
|
||||
* @since 0.3.0
|
||||
*/
|
||||
void stop_perpetual() {
|
||||
m_work.reset();
|
||||
@@ -597,11 +630,9 @@ public:
|
||||
* needed.
|
||||
*/
|
||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||
timer_ptr new_timer(
|
||||
new boost::asio::deadline_timer(
|
||||
*m_io_service,
|
||||
boost::posix_time::milliseconds(duration)
|
||||
)
|
||||
timer_ptr new_timer = lib::make_shared<boost::asio::deadline_timer>(
|
||||
*m_io_service,
|
||||
boost::posix_time::milliseconds(duration)
|
||||
);
|
||||
|
||||
new_timer->async_wait(
|
||||
@@ -617,7 +648,7 @@ public:
|
||||
return new_timer;
|
||||
}
|
||||
|
||||
/// Timer callback
|
||||
/// Timer handler
|
||||
/**
|
||||
* The timer pointer is included to ensure the timer isn't destroyed until
|
||||
* after it has expired.
|
||||
@@ -626,7 +657,7 @@ public:
|
||||
* @param callback The function to call back
|
||||
* @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)
|
||||
{
|
||||
if (ec) {
|
||||
@@ -653,10 +684,8 @@ public:
|
||||
lib::error_code & ec)
|
||||
{
|
||||
if (m_state != LISTENING) {
|
||||
m_elog->write(log::elevel::library,
|
||||
"asio::async_accept called from the wrong state");
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -693,9 +722,7 @@ public:
|
||||
void async_accept(transport_con_ptr tcon, accept_handler callback) {
|
||||
lib::error_code ec;
|
||||
async_accept(tcon,callback,ec);
|
||||
if (ec) {
|
||||
throw ec;
|
||||
}
|
||||
if (ec) { throw exception(ec); }
|
||||
}
|
||||
protected:
|
||||
/// Initialize logging
|
||||
@@ -721,8 +748,12 @@ protected:
|
||||
m_alog->write(log::alevel::devel, "asio::handle_accept");
|
||||
|
||||
if (boost_ec) {
|
||||
log_err(log::elevel::devel,"asio handle_accept",boost_ec);
|
||||
ret_ec = make_error_code(error::pass_through);
|
||||
if (boost_ec == boost::system::errc::operation_canceled) {
|
||||
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);
|
||||
@@ -735,7 +766,8 @@ protected:
|
||||
|
||||
// Create a 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();
|
||||
@@ -748,7 +780,7 @@ protected:
|
||||
} else {
|
||||
lib::error_code ec;
|
||||
|
||||
uri_ptr pu(new uri(proxy));
|
||||
uri_ptr pu = lib::make_shared<uri>(proxy);
|
||||
|
||||
if (!pu->get_valid()) {
|
||||
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 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)
|
||||
{
|
||||
lib::error_code ret_ec;
|
||||
@@ -962,10 +1013,6 @@ protected:
|
||||
callback(lib::error_code());
|
||||
}
|
||||
|
||||
bool is_listening() const {
|
||||
return (m_state == LISTENING);
|
||||
}
|
||||
|
||||
/// Initialize a connection
|
||||
/**
|
||||
* init is called by an endpoint once for each newly created connection.
|
||||
@@ -1022,6 +1069,7 @@ private:
|
||||
|
||||
// Network constants
|
||||
int m_listen_backlog;
|
||||
bool m_reuse_addr;
|
||||
|
||||
elog_type* m_elog;
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Interface that sockets/security policies must implement
|
||||
@@ -95,7 +94,10 @@ namespace error {
|
||||
pass_through,
|
||||
|
||||
/// Required tls_init handler not present
|
||||
missing_tls_init_handler
|
||||
missing_tls_init_handler,
|
||||
|
||||
/// TLS Handshake Failed
|
||||
tls_handshake_failed,
|
||||
};
|
||||
} // namespace error
|
||||
|
||||
@@ -119,9 +121,11 @@ public:
|
||||
case error::tls_handshake_timeout:
|
||||
return "TLS handshake timed out";
|
||||
case error::pass_through:
|
||||
return "Pass through from underlying library";
|
||||
return "Pass through from socket policy";
|
||||
case error::missing_tls_init_handler:
|
||||
return "Required tls_init handler not present.";
|
||||
case error::tls_handshake_failed:
|
||||
return "TLS handshake failed";
|
||||
default:
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -33,14 +33,16 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace asio {
|
||||
/// A socket policy for the asio transport that implements a plain, unencrypted
|
||||
/// socket
|
||||
namespace basic_socket {
|
||||
|
||||
/// The signature of the socket init handler for this socket policy
|
||||
typedef lib::function<void(connection_hdl,boost::asio::ip::tcp::socket&)>
|
||||
socket_init_handler;
|
||||
|
||||
@@ -60,8 +62,10 @@ public:
|
||||
typedef boost::asio::io_service* io_service_ptr;
|
||||
/// Type of a pointer to the ASIO io_service strand being used
|
||||
typedef lib::shared_ptr<boost::asio::io_service::strand> strand_ptr;
|
||||
/// Type of the ASIO socket being used
|
||||
typedef boost::asio::ip::tcp::socket socket_type;
|
||||
/// 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) {
|
||||
//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 is_server Whether or not the endpoint is a server or not.
|
||||
*/
|
||||
lib::error_code init_asio (io_service_ptr service, strand_ptr strand,
|
||||
bool is_server)
|
||||
lib::error_code init_asio (io_service_ptr service, strand_ptr, bool)
|
||||
{
|
||||
if (m_state != UNINITIALIZED) {
|
||||
return socket::make_error_code(socket::error::invalid_state);
|
||||
}
|
||||
|
||||
m_socket.reset(new boost::asio::ip::tcp::socket(*service));
|
||||
m_socket = lib::make_shared<boost::asio::ip::tcp::socket>(
|
||||
lib::ref(*service));
|
||||
|
||||
m_state = READY;
|
||||
|
||||
@@ -229,6 +233,23 @@ protected:
|
||||
lib::error_code get_ec() const {
|
||||
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:
|
||||
enum state {
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -37,16 +37,19 @@
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
namespace transport {
|
||||
namespace asio {
|
||||
/// A socket policy for the asio transport that implements a TLS encrypted
|
||||
/// socket by wrapping with an asio::ssl::stream
|
||||
namespace tls_socket {
|
||||
|
||||
/// The signature of the socket_init_handler for this socket policy
|
||||
typedef lib::function<void(connection_hdl,boost::asio::ssl::stream<
|
||||
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)>
|
||||
tls_init_handler;
|
||||
|
||||
@@ -190,7 +193,8 @@ protected:
|
||||
if (!m_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_strand = strand;
|
||||
@@ -260,11 +264,10 @@ protected:
|
||||
m_hdl = hdl;
|
||||
}
|
||||
|
||||
void handle_init(init_handler callback, const
|
||||
boost::system::error_code& ec)
|
||||
void handle_init(init_handler callback,boost::system::error_code const & 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 {
|
||||
m_ec = lib::error_code();
|
||||
}
|
||||
@@ -284,6 +287,37 @@ protected:
|
||||
void async_shutdown(socket_shutdown_handler 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:
|
||||
socket_type::handshake_type get_handshake_type() {
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -141,6 +141,7 @@ struct buffer {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/// Generic transport related errors
|
||||
namespace error {
|
||||
enum value {
|
||||
/// Catch-all error for transport policy errors that don't fit in other
|
||||
@@ -170,9 +171,12 @@ enum value {
|
||||
|
||||
/// Timer expired
|
||||
timeout,
|
||||
|
||||
|
||||
/// read or write after shutdown
|
||||
action_after_shutdown
|
||||
action_after_shutdown,
|
||||
|
||||
/// Other TLS error
|
||||
tls_error,
|
||||
};
|
||||
|
||||
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";
|
||||
case eof:
|
||||
return "End of File";
|
||||
case tls_short_read:
|
||||
case tls_short_read:
|
||||
return "TLS Short Read";
|
||||
case timeout:
|
||||
return "Timer Expired";
|
||||
case action_after_shutdown:
|
||||
return "A transport action was requested after shutdown";
|
||||
case tls_error:
|
||||
return "Generic TLS related error";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -28,8 +28,9 @@
|
||||
#ifndef 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/memory.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <websocketpp/transport/base/connection.hpp>
|
||||
@@ -127,14 +128,13 @@ public:
|
||||
return in;
|
||||
}
|
||||
|
||||
/// Manual input supply
|
||||
/// Manual input supply (read some)
|
||||
/**
|
||||
* Copies bytes from buf into WebSocket++'s input buffers. Bytes will be
|
||||
* copied from the supplied buffer to fulfill any pending library reads. It
|
||||
* will return the number of bytes successfully processed. If there are no
|
||||
* pending reads read_some will return immediately. Not all of the bytes may
|
||||
* be able to be read in one call
|
||||
*
|
||||
* be able to be read in one call.
|
||||
*
|
||||
* @since 0.3.0-alpha4
|
||||
*
|
||||
@@ -148,6 +148,37 @@ public:
|
||||
|
||||
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)
|
||||
/**
|
||||
@@ -273,7 +304,7 @@ public:
|
||||
* @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) {
|
||||
timer_ptr set_timer(long, timer_handler) {
|
||||
return timer_ptr();
|
||||
}
|
||||
protected:
|
||||
@@ -479,7 +510,7 @@ private:
|
||||
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);
|
||||
|
||||
|
||||
@@ -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
|
||||
* 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 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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
* 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 {
|
||||
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 temp;
|
||||
|
||||
int state = 0;
|
||||
|
||||
it = uri.begin();
|
||||
it = uri_string.begin();
|
||||
|
||||
if (std::equal(it,it+6,"wss://")) {
|
||||
m_secure = true;
|
||||
@@ -88,14 +88,14 @@ public:
|
||||
//temp = std::find(it,it2,']');
|
||||
|
||||
temp = it;
|
||||
while (temp != uri.end()) {
|
||||
while (temp != uri_string.end()) {
|
||||
if (*temp == ']') {
|
||||
break;
|
||||
}
|
||||
++temp;
|
||||
}
|
||||
|
||||
if (temp == uri.end()) {
|
||||
if (temp == uri_string.end()) {
|
||||
return;
|
||||
} else {
|
||||
// validate IPv6 literal parts
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
m_host.append(it,temp);
|
||||
}
|
||||
it = temp+1;
|
||||
if (it == uri.end()) {
|
||||
if (it == uri_string.end()) {
|
||||
state = 2;
|
||||
} else if (*it == '/') {
|
||||
state = 2;
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
// IPv4 or hostname
|
||||
// extract until : or /
|
||||
while (state == 0) {
|
||||
if (it == uri.end()) {
|
||||
if (it == uri_string.end()) {
|
||||
state = 2;
|
||||
break;
|
||||
} else if (*it == '/') {
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
// parse port
|
||||
std::string port = "";
|
||||
while (state == 1) {
|
||||
if (it == uri.end()) {
|
||||
if (it == uri_string.end()) {
|
||||
// state is not used after this point presently.
|
||||
// this should be re-enabled if it ever is needed in a future
|
||||
// refactoring
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
}
|
||||
|
||||
m_resource = "/";
|
||||
m_resource.append(it,uri.end());
|
||||
m_resource.append(it,uri_string.end());
|
||||
|
||||
|
||||
m_valid = true;
|
||||
@@ -290,10 +290,10 @@ public:
|
||||
* @return query portion of the URI.
|
||||
*/
|
||||
std::string get_query() const {
|
||||
std::size_t found = m_resource.find('?');
|
||||
if (found != std::string::npos) {
|
||||
return m_resource.substr(found + 1);
|
||||
} else {
|
||||
std::size_t found = m_resource.find('?');
|
||||
if (found != std::string::npos) {
|
||||
return m_resource.substr(found + 1);
|
||||
} else {
|
||||
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
|
||||
* 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>
|
||||
{
|
||||
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 {
|
||||
|
||||
+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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -42,7 +42,7 @@ namespace websocketpp {
|
||||
/// Library major version number
|
||||
static int const major_version = 0;
|
||||
/// Library minor version number
|
||||
static int const minor_version = 3;
|
||||
static int const minor_version = 4;
|
||||
/// Library patch version number
|
||||
static int const patch_version = 0;
|
||||
/// 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
|
||||
* 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
|
||||
static char const user_agent[] = "WebSocket++/0.3.0-alpha4";
|
||||
static char const user_agent[] = "WebSocket++/0.4.0";
|
||||
|
||||
} // namespace websocketpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user